From ae0232ec92c17fbe81e3ad5cc8640b582e7673f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Onur=20=C3=96zkan?= Date: Fri, 28 Oct 2022 10:20:51 +0300 Subject: [PATCH 1/6] improve `filesearch::get_or_default_sysroot` r=ozkanonur MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Onur Özkan --- Cargo.lock | 5 +- compiler/rustc_codegen_ssa/src/back/link.rs | 3 +- compiler/rustc_interface/Cargo.toml | 6 - compiler/rustc_interface/src/util.rs | 97 +------------ compiler/rustc_session/Cargo.toml | 7 + compiler/rustc_session/src/config.rs | 2 +- compiler/rustc_session/src/filesearch.rs | 143 ++++++++++++++++---- compiler/rustc_session/src/session.rs | 2 +- src/tools/clippy/src/driver.rs | 79 +---------- src/tools/miri/src/bin/miri.rs | 70 ++-------- 10 files changed, 151 insertions(+), 263 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index dab693419a95d..cd0d14817baa6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3646,7 +3646,6 @@ dependencies = [ name = "rustc_interface" version = "0.0.0" dependencies = [ - "libc", "libloading", "rustc-rayon", "rustc-rayon-core", @@ -3689,7 +3688,6 @@ dependencies = [ "rustc_ty_utils", "smallvec", "tracing", - "winapi", ] [[package]] @@ -4109,6 +4107,7 @@ name = "rustc_session" version = "0.0.0" dependencies = [ "getopts", + "libc", "rustc_ast", "rustc_data_structures", "rustc_errors", @@ -4120,7 +4119,9 @@ dependencies = [ "rustc_serialize", "rustc_span", "rustc_target", + "smallvec", "tracing", + "winapi", ] [[package]] diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index 0dc0dee862c74..bd986c3b8e519 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -1153,7 +1153,8 @@ fn link_sanitizer_runtime(sess: &Session, linker: &mut dyn Linker, name: &str) { if path.exists() { return session_tlib; } else { - let default_sysroot = filesearch::get_or_default_sysroot(); + let default_sysroot = + filesearch::get_or_default_sysroot().expect("Failed finding sysroot"); let default_tlib = filesearch::make_target_lib_path( &default_sysroot, sess.opts.target_triple.triple(), diff --git a/compiler/rustc_interface/Cargo.toml b/compiler/rustc_interface/Cargo.toml index 6a4c5b4d37376..2e526733df974 100644 --- a/compiler/rustc_interface/Cargo.toml +++ b/compiler/rustc_interface/Cargo.toml @@ -48,12 +48,6 @@ rustc_resolve = { path = "../rustc_resolve" } rustc_trait_selection = { path = "../rustc_trait_selection" } rustc_ty_utils = { path = "../rustc_ty_utils" } -[target.'cfg(unix)'.dependencies] -libc = "0.2" - -[target.'cfg(windows)'.dependencies] -winapi = { version = "0.3", features = ["libloaderapi"] } - [dev-dependencies] rustc_target = { path = "../rustc_target" } diff --git a/compiler/rustc_interface/src/util.rs b/compiler/rustc_interface/src/util.rs index 519b8a7fc7c37..62ee72f988308 100644 --- a/compiler/rustc_interface/src/util.rs +++ b/compiler/rustc_interface/src/util.rs @@ -9,6 +9,7 @@ use rustc_session as session; use rustc_session::config::CheckCfg; use rustc_session::config::{self, CrateType}; use rustc_session::config::{ErrorOutputType, Input, OutputFilenames}; +use rustc_session::filesearch::sysroot_candidates; use rustc_session::lint::{self, BuiltinLintDiagnostics, LintBuffer}; use rustc_session::parse::CrateConfig; use rustc_session::{early_error, filesearch, output, Session}; @@ -78,7 +79,7 @@ pub fn create_session( let bundle = match rustc_errors::fluent_bundle( sopts.maybe_sysroot.clone(), - sysroot_candidates(), + sysroot_candidates().to_vec(), sopts.unstable_opts.translate_lang.clone(), sopts.unstable_opts.translate_additional_ftl.as_deref(), sopts.unstable_opts.translate_directionality_markers, @@ -273,100 +274,6 @@ fn get_rustc_path_inner(bin_path: &str) -> Option { }) } -fn sysroot_candidates() -> Vec { - let target = session::config::host_triple(); - let mut sysroot_candidates = vec![filesearch::get_or_default_sysroot()]; - let path = current_dll_path().and_then(|s| s.canonicalize().ok()); - if let Some(dll) = path { - // use `parent` twice to chop off the file name and then also the - // directory containing the dll which should be either `lib` or `bin`. - if let Some(path) = dll.parent().and_then(|p| p.parent()) { - // The original `path` pointed at the `rustc_driver` crate's dll. - // Now that dll should only be in one of two locations. The first is - // in the compiler's libdir, for example `$sysroot/lib/*.dll`. The - // other is the target's libdir, for example - // `$sysroot/lib/rustlib/$target/lib/*.dll`. - // - // We don't know which, so let's assume that if our `path` above - // ends in `$target` we *could* be in the target libdir, and always - // assume that we may be in the main libdir. - sysroot_candidates.push(path.to_owned()); - - if path.ends_with(target) { - sysroot_candidates.extend( - path.parent() // chop off `$target` - .and_then(|p| p.parent()) // chop off `rustlib` - .and_then(|p| p.parent()) // chop off `lib` - .map(|s| s.to_owned()), - ); - } - } - } - - return sysroot_candidates; - - #[cfg(unix)] - fn current_dll_path() -> Option { - use std::ffi::{CStr, OsStr}; - use std::os::unix::prelude::*; - - unsafe { - let addr = current_dll_path as usize as *mut _; - let mut info = mem::zeroed(); - if libc::dladdr(addr, &mut info) == 0 { - info!("dladdr failed"); - return None; - } - if info.dli_fname.is_null() { - info!("dladdr returned null pointer"); - return None; - } - let bytes = CStr::from_ptr(info.dli_fname).to_bytes(); - let os = OsStr::from_bytes(bytes); - Some(PathBuf::from(os)) - } - } - - #[cfg(windows)] - fn current_dll_path() -> Option { - use std::ffi::OsString; - use std::io; - use std::os::windows::prelude::*; - use std::ptr; - - use winapi::um::libloaderapi::{ - GetModuleFileNameW, GetModuleHandleExW, GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, - }; - - unsafe { - let mut module = ptr::null_mut(); - let r = GetModuleHandleExW( - GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, - current_dll_path as usize as *mut _, - &mut module, - ); - if r == 0 { - info!("GetModuleHandleExW failed: {}", io::Error::last_os_error()); - return None; - } - let mut space = Vec::with_capacity(1024); - let r = GetModuleFileNameW(module, space.as_mut_ptr(), space.capacity() as u32); - if r == 0 { - info!("GetModuleFileNameW failed: {}", io::Error::last_os_error()); - return None; - } - let r = r as usize; - if r >= space.capacity() { - info!("our buffer was too small? {}", io::Error::last_os_error()); - return None; - } - space.set_len(r); - let os = OsString::from_wide(&space); - Some(PathBuf::from(os)) - } - } -} - fn get_codegen_sysroot(maybe_sysroot: &Option, backend_name: &str) -> MakeBackendFn { // For now we only allow this function to be called once as it'll dlopen a // few things, which seems to work best if we only do that once. In diff --git a/compiler/rustc_session/Cargo.toml b/compiler/rustc_session/Cargo.toml index 6b1eaa4d399d9..a052f29334169 100644 --- a/compiler/rustc_session/Cargo.toml +++ b/compiler/rustc_session/Cargo.toml @@ -17,3 +17,10 @@ rustc_span = { path = "../rustc_span" } rustc_fs_util = { path = "../rustc_fs_util" } rustc_ast = { path = "../rustc_ast" } rustc_lint_defs = { path = "../rustc_lint_defs" } +smallvec = "1.8.1" + +[target.'cfg(unix)'.dependencies] +libc = "0.2" + +[target.'cfg(windows)'.dependencies] +winapi = { version = "0.3", features = ["libloaderapi"] } diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index f2ee52262adee..5dfd9f00ad159 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -2431,7 +2431,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options { let sysroot = match &sysroot_opt { Some(s) => s, None => { - tmp_buf = crate::filesearch::get_or_default_sysroot(); + tmp_buf = crate::filesearch::get_or_default_sysroot().expect("Failed finding sysroot"); &tmp_buf } }; diff --git a/compiler/rustc_session/src/filesearch.rs b/compiler/rustc_session/src/filesearch.rs index e8edb38f5038e..8dfb8d33038fc 100644 --- a/compiler/rustc_session/src/filesearch.rs +++ b/compiler/rustc_session/src/filesearch.rs @@ -1,12 +1,12 @@ //! A module for searching for libraries +use smallvec::{smallvec, SmallVec}; use std::env; use std::fs; use std::iter::FromIterator; use std::path::{Path, PathBuf}; use crate::search_paths::{PathKind, SearchPath}; -use rustc_fs_util::fix_windows_verbatim_for_gcc; #[derive(Copy, Clone)] pub enum FileMatch { @@ -62,29 +62,126 @@ pub fn make_target_lib_path(sysroot: &Path, target_triple: &str) -> PathBuf { PathBuf::from_iter([sysroot, Path::new(&rustlib_path), Path::new("lib")]) } -/// This function checks if sysroot is found using env::args().next(), and if it -/// is not found, uses env::current_exe() to imply sysroot. -pub fn get_or_default_sysroot() -> PathBuf { - // Follow symlinks. If the resolved path is relative, make it absolute. - fn canonicalize(path: PathBuf) -> PathBuf { - let path = fs::canonicalize(&path).unwrap_or(path); - // See comments on this target function, but the gist is that - // gcc chokes on verbatim paths which fs::canonicalize generates - // so we try to avoid those kinds of paths. - fix_windows_verbatim_for_gcc(&path) +#[cfg(unix)] +fn current_dll_path() -> Result { + use std::ffi::{CStr, OsStr}; + use std::os::unix::prelude::*; + + unsafe { + let addr = current_dll_path as usize as *mut _; + let mut info = std::mem::zeroed(); + if libc::dladdr(addr, &mut info) == 0 { + return Err("dladdr failed".into()); + } + if info.dli_fname.is_null() { + return Err("dladdr returned null pointer".into()); + } + let bytes = CStr::from_ptr(info.dli_fname).to_bytes(); + let os = OsStr::from_bytes(bytes); + Ok(PathBuf::from(os)) } +} - // Use env::current_exe() to get the path of the executable following - // symlinks/canonicalizing components. - fn from_current_exe() -> PathBuf { - match env::current_exe() { - Ok(exe) => { - let mut p = canonicalize(exe); - p.pop(); - p.pop(); - p +#[cfg(windows)] +fn current_dll_path() -> Result { + use std::ffi::OsString; + use std::io; + use std::os::windows::prelude::*; + use std::ptr; + + use winapi::um::libloaderapi::{ + GetModuleFileNameW, GetModuleHandleExW, GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, + }; + + unsafe { + let mut module = ptr::null_mut(); + let r = GetModuleHandleExW( + GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, + current_dll_path as usize as *mut _, + &mut module, + ); + if r == 0 { + return Err(format!("GetModuleHandleExW failed: {}", io::Error::last_os_error())); + } + let mut space = Vec::with_capacity(1024); + let r = GetModuleFileNameW(module, space.as_mut_ptr(), space.capacity() as u32); + if r == 0 { + return Err(format!("GetModuleFileNameW failed: {}", io::Error::last_os_error())); + } + let r = r as usize; + if r >= space.capacity() { + return Err(format!("our buffer was too small? {}", io::Error::last_os_error())); + } + space.set_len(r); + let os = OsString::from_wide(&space); + Ok(PathBuf::from(os)) + } +} + +pub fn sysroot_candidates() -> SmallVec<[PathBuf; 2]> { + let target = crate::config::host_triple(); + let mut sysroot_candidates: SmallVec<[PathBuf; 2]> = + smallvec![get_or_default_sysroot().expect("Failed finding sysroot")]; + let path = current_dll_path().and_then(|s| Ok(s.canonicalize().map_err(|e| e.to_string())?)); + if let Ok(dll) = path { + // use `parent` twice to chop off the file name and then also the + // directory containing the dll which should be either `lib` or `bin`. + if let Some(path) = dll.parent().and_then(|p| p.parent()) { + // The original `path` pointed at the `rustc_driver` crate's dll. + // Now that dll should only be in one of two locations. The first is + // in the compiler's libdir, for example `$sysroot/lib/*.dll`. The + // other is the target's libdir, for example + // `$sysroot/lib/rustlib/$target/lib/*.dll`. + // + // We don't know which, so let's assume that if our `path` above + // ends in `$target` we *could* be in the target libdir, and always + // assume that we may be in the main libdir. + sysroot_candidates.push(path.to_owned()); + + if path.ends_with(target) { + sysroot_candidates.extend( + path.parent() // chop off `$target` + .and_then(|p| p.parent()) // chop off `rustlib` + .and_then(|p| p.parent()) // chop off `lib` + .map(|s| s.to_owned()), + ); } - Err(e) => panic!("failed to get current_exe: {e}"), + } + } + + return sysroot_candidates; +} + +/// This function checks if sysroot is found using env::args().next(), and if it +/// is not found, finds sysroot from current rustc_driver dll. +pub fn get_or_default_sysroot() -> Result { + fn default_from_rustc_driver_dll() -> Result { + let dll = + current_dll_path().and_then(|s| Ok(s.canonicalize().map_err(|e| e.to_string())?))?; + + // `dll` will be in one of the following two: + // - compiler's libdir: $sysroot/lib/*.dll + // - target's libdir: $sysroot/lib/rustlib/$target/lib/*.dll + // + // use `parent` twice to chop off the file name and then also the + // directory containing the dll + let dir = dll.parent().and_then(|p| p.parent()).ok_or(format!( + "Could not move 2 levels upper using `parent()` on {}", + dll.display() + ))?; + + // if `dir` points target's dir, move up to the sysroot + if dir.ends_with(crate::config::host_triple()) { + dir.parent() // chop off `$target` + .and_then(|p| p.parent()) // chop off `rustlib` + .and_then(|p| p.parent()) // chop off `lib` + .map(|s| s.to_owned()) + .ok_or(format!( + "Could not move 3 levels upper using `parent()` on {}", + dir.display() + )) + } else { + Ok(dir.to_owned()) } } @@ -118,7 +215,5 @@ pub fn get_or_default_sysroot() -> PathBuf { } } - // Check if sysroot is found using env::args().next(), and if is not found, - // use env::current_exe() to imply sysroot. - from_env_args_next().unwrap_or_else(from_current_exe) + Ok(from_env_args_next().unwrap_or(default_from_rustc_driver_dll()?)) } diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index 100c66f63641c..5086117f9210e 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -1280,7 +1280,7 @@ pub fn build_session( let sysroot = match &sopts.maybe_sysroot { Some(sysroot) => sysroot.clone(), - None => filesearch::get_or_default_sysroot(), + None => filesearch::get_or_default_sysroot().expect("Failed finding sysroot"), }; let target_cfg = config::build_target_config(&sopts, target_override, &sysroot); diff --git a/src/tools/clippy/src/driver.rs b/src/tools/clippy/src/driver.rs index b12208ac62a88..46afea2c4b5a1 100644 --- a/src/tools/clippy/src/driver.rs +++ b/src/tools/clippy/src/driver.rs @@ -23,8 +23,8 @@ use std::borrow::Cow; use std::env; use std::ops::Deref; use std::panic; -use std::path::{Path, PathBuf}; -use std::process::{exit, Command}; +use std::path::Path; +use std::process::exit; use std::sync::LazyLock; /// If a command-line option matches `find_arg`, then apply the predicate `pred` on its value. If @@ -209,17 +209,6 @@ fn report_clippy_ice(info: &panic::PanicInfo<'_>, bug_report_url: &str) { interface::try_print_query_stack(&handler, num_frames); } -fn toolchain_path(home: Option, toolchain: Option) -> Option { - home.and_then(|home| { - toolchain.map(|toolchain| { - let mut path = PathBuf::from(home); - path.push("toolchains"); - path.push(toolchain); - path - }) - }) -} - #[allow(clippy::too_many_lines)] pub fn main() { rustc_driver::init_rustc_env_logger(); @@ -227,51 +216,6 @@ pub fn main() { exit(rustc_driver::catch_with_exit_code(move || { let mut orig_args: Vec = env::args().collect(); - // Get the sysroot, looking from most specific to this invocation to the least: - // - command line - // - runtime environment - // - SYSROOT - // - RUSTUP_HOME, MULTIRUST_HOME, RUSTUP_TOOLCHAIN, MULTIRUST_TOOLCHAIN - // - sysroot from rustc in the path - // - compile-time environment - // - SYSROOT - // - RUSTUP_HOME, MULTIRUST_HOME, RUSTUP_TOOLCHAIN, MULTIRUST_TOOLCHAIN - let sys_root_arg = arg_value(&orig_args, "--sysroot", |_| true); - let have_sys_root_arg = sys_root_arg.is_some(); - let sys_root = sys_root_arg - .map(PathBuf::from) - .or_else(|| std::env::var("SYSROOT").ok().map(PathBuf::from)) - .or_else(|| { - let home = std::env::var("RUSTUP_HOME") - .or_else(|_| std::env::var("MULTIRUST_HOME")) - .ok(); - let toolchain = std::env::var("RUSTUP_TOOLCHAIN") - .or_else(|_| std::env::var("MULTIRUST_TOOLCHAIN")) - .ok(); - toolchain_path(home, toolchain) - }) - .or_else(|| { - Command::new("rustc") - .arg("--print") - .arg("sysroot") - .output() - .ok() - .and_then(|out| String::from_utf8(out.stdout).ok()) - .map(|s| PathBuf::from(s.trim())) - }) - .or_else(|| option_env!("SYSROOT").map(PathBuf::from)) - .or_else(|| { - let home = option_env!("RUSTUP_HOME") - .or(option_env!("MULTIRUST_HOME")) - .map(ToString::to_string); - let toolchain = option_env!("RUSTUP_TOOLCHAIN") - .or(option_env!("MULTIRUST_TOOLCHAIN")) - .map(ToString::to_string); - toolchain_path(home, toolchain) - }) - .map(|pb| pb.to_string_lossy().to_string()) - .expect("need to specify SYSROOT env var during clippy compilation, or use rustup or multirust"); - // make "clippy-driver --rustc" work like a subcommand that passes further args to "rustc" // for example `clippy-driver --rustc --version` will print the rustc version that clippy-driver // uses @@ -279,13 +223,7 @@ pub fn main() { orig_args.remove(pos); orig_args[0] = "rustc".to_string(); - // if we call "rustc", we need to pass --sysroot here as well - let mut args: Vec = orig_args.clone(); - if !have_sys_root_arg { - args.extend(vec!["--sysroot".into(), sys_root]); - }; - - return rustc_driver::RunCompiler::new(&args, &mut DefaultCallbacks).run(); + return rustc_driver::RunCompiler::new(&orig_args, &mut DefaultCallbacks).run(); } if orig_args.iter().any(|a| a == "--version" || a == "-V") { @@ -308,14 +246,6 @@ pub fn main() { exit(0); } - // this conditional check for the --sysroot flag is there so users can call - // `clippy_driver` directly - // without having to pass --sysroot or anything - let mut args: Vec = orig_args.clone(); - if !have_sys_root_arg { - args.extend(vec!["--sysroot".into(), sys_root]); - }; - let mut no_deps = false; let clippy_args_var = env::var("CLIPPY_ARGS").ok(); let clippy_args = clippy_args_var @@ -344,10 +274,11 @@ pub fn main() { let clippy_enabled = !cap_lints_allow && (!no_deps || in_primary_package); if clippy_enabled { + let mut args: Vec = orig_args.clone(); args.extend(clippy_args); rustc_driver::RunCompiler::new(&args, &mut ClippyCallbacks { clippy_args_var }).run() } else { - rustc_driver::RunCompiler::new(&args, &mut RustcCallbacks { clippy_args_var }).run() + rustc_driver::RunCompiler::new(&orig_args, &mut RustcCallbacks { clippy_args_var }).run() } })) } diff --git a/src/tools/miri/src/bin/miri.rs b/src/tools/miri/src/bin/miri.rs index bd01ea655dd70..e673ea67dbc5b 100644 --- a/src/tools/miri/src/bin/miri.rs +++ b/src/tools/miri/src/bin/miri.rs @@ -216,76 +216,28 @@ fn init_late_loggers(tcx: TyCtxt<'_>) { } } -/// Returns the "default sysroot" that Miri will use for host things if no `--sysroot` flag is set. -/// Should be a compile-time constant. -fn host_sysroot() -> Option { - if option_env!("RUSTC_STAGE").is_some() { - // This is being built as part of rustc, and gets shipped with rustup. - // We can rely on the sysroot computation in librustc_session. - return None; - } - // For builds outside rustc, we need to ensure that we got a sysroot - // that gets used as a default. The sysroot computation in librustc_session would - // end up somewhere in the build dir (see `get_or_default_sysroot`). - // Taken from PR . - let home = option_env!("RUSTUP_HOME").or(option_env!("MULTIRUST_HOME")); - let toolchain = option_env!("RUSTUP_TOOLCHAIN").or(option_env!("MULTIRUST_TOOLCHAIN")); - Some(match (home, toolchain) { - (Some(home), Some(toolchain)) => { - // Check that at runtime, we are still in this toolchain (if there is any toolchain). - if let Some(toolchain_runtime) = - env::var_os("RUSTUP_TOOLCHAIN").or_else(|| env::var_os("MULTIRUST_TOOLCHAIN")) - { - if toolchain_runtime != toolchain { - show_error!( - "This Miri got built with local toolchain `{toolchain}`, but now is being run under a different toolchain. \n\ - Make sure to run Miri in the toolchain it got built with, e.g. via `cargo +{toolchain} miri`." - ) - } - } - format!("{home}/toolchains/{toolchain}") - } - _ => option_env!("RUST_SYSROOT") - .unwrap_or_else(|| { - show_error!( - "To build Miri without rustup, set the `RUST_SYSROOT` env var at build time", - ) - }) - .to_owned(), - }) -} - /// Execute a compiler with the given CLI arguments and callbacks. fn run_compiler( mut args: Vec, target_crate: bool, callbacks: &mut (dyn rustc_driver::Callbacks + Send), ) -> ! { - // Make sure we use the right default sysroot. The default sysroot is wrong, - // because `get_or_default_sysroot` in `librustc_session` bases that on `current_exe`. - // - // Make sure we always call `host_sysroot` as that also does some sanity-checks - // of the environment we were built in and whether it matches what we are running in. - let host_default_sysroot = host_sysroot(); - // Now see if we even need to set something. - let sysroot_flag = "--sysroot"; - if !args.iter().any(|e| e == sysroot_flag) { - // No sysroot was set, let's see if we have a custom default we want to configure. - let default_sysroot = if target_crate { + if target_crate { + // Miri needs a custom sysroot for target crates. + // If no `--sysroot` is given, the `MIRI_SYSROOT` env var is consulted to find where + // that sysroot lives, and that is passed to rustc. + let sysroot_flag = "--sysroot"; + if !args.iter().any(|e| e == sysroot_flag) { // Using the built-in default here would be plain wrong, so we *require* // the env var to make sure things make sense. - Some(env::var("MIRI_SYSROOT").unwrap_or_else(|_| { + let miri_sysroot = env::var("MIRI_SYSROOT").unwrap_or_else(|_| { show_error!( "Miri was invoked in 'target' mode without `MIRI_SYSROOT` or `--sysroot` being set" - ) - })) - } else { - host_default_sysroot - }; - if let Some(sysroot) = default_sysroot { - // We need to overwrite the default that librustc_session would compute. + ) + }); + args.push(sysroot_flag.to_owned()); - args.push(sysroot); + args.push(miri_sysroot); } } From a0c21e4e7ea3a2143af9e65a98a19e6b1942ff53 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Mon, 31 Oct 2022 20:55:03 -0400 Subject: [PATCH 2/6] Remove let_underscore_must_use from list of uplifted lints --- RELEASES.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RELEASES.md b/RELEASES.md index a3df56f1d2afc..ad550260c8bcf 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -6,7 +6,7 @@ Language - [Error on `as` casts of enums with `#[non_exhaustive]` variants](https://github.com/rust-lang/rust/pull/92744/) - [Stabilize `let else`](https://github.com/rust-lang/rust/pull/93628/) - [Stabilize generic associated types (GATs)](https://github.com/rust-lang/rust/pull/96709/) -- [Add lints `let_underscore_drop`, `let_underscore_lock`, and `let_underscore_must_use` from Clippy](https://github.com/rust-lang/rust/pull/97739/) +- [Add lints `let_underscore_drop` and `let_underscore_lock` from Clippy](https://github.com/rust-lang/rust/pull/97739/) - [Stabilize `break`ing from arbitrary labeled blocks ("label-break-value")](https://github.com/rust-lang/rust/pull/99332/) - [Uninitialized integers, floats, and raw pointers are now considered immediate UB](https://github.com/rust-lang/rust/pull/98919/). Usage of `MaybeUninit` is the correct way to work with uninitialized memory. From 10a5e75537e3189ffa808be7eadc19569966b266 Mon Sep 17 00:00:00 2001 From: Cameron Steffen Date: Tue, 1 Nov 2022 12:24:51 -0500 Subject: [PATCH 3/6] Add track_caller to some Lock methods --- compiler/rustc_data_structures/src/sync.rs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/compiler/rustc_data_structures/src/sync.rs b/compiler/rustc_data_structures/src/sync.rs index 9c0fb8265cff7..c550f246e094a 100644 --- a/compiler/rustc_data_structures/src/sync.rs +++ b/compiler/rustc_data_structures/src/sync.rs @@ -410,6 +410,7 @@ impl Lock { #[cfg(parallel_compiler)] #[inline(always)] + #[track_caller] pub fn lock(&self) -> LockGuard<'_, T> { if ERROR_CHECKING { self.0.try_lock().expect("lock was already held") @@ -420,21 +421,25 @@ impl Lock { #[cfg(not(parallel_compiler))] #[inline(always)] + #[track_caller] pub fn lock(&self) -> LockGuard<'_, T> { self.0.borrow_mut() } #[inline(always)] + #[track_caller] pub fn with_lock R, R>(&self, f: F) -> R { f(&mut *self.lock()) } #[inline(always)] + #[track_caller] pub fn borrow(&self) -> LockGuard<'_, T> { self.lock() } #[inline(always)] + #[track_caller] pub fn borrow_mut(&self) -> LockGuard<'_, T> { self.lock() } @@ -476,6 +481,7 @@ impl RwLock { #[cfg(not(parallel_compiler))] #[inline(always)] + #[track_caller] pub fn read(&self) -> ReadGuard<'_, T> { self.0.borrow() } @@ -491,6 +497,7 @@ impl RwLock { } #[inline(always)] + #[track_caller] pub fn with_read_lock R, R>(&self, f: F) -> R { f(&*self.read()) } @@ -509,6 +516,7 @@ impl RwLock { #[cfg(not(parallel_compiler))] #[inline(always)] + #[track_caller] pub fn write(&self) -> WriteGuard<'_, T> { self.0.borrow_mut() } @@ -524,16 +532,19 @@ impl RwLock { } #[inline(always)] + #[track_caller] pub fn with_write_lock R, R>(&self, f: F) -> R { f(&mut *self.write()) } #[inline(always)] + #[track_caller] pub fn borrow(&self) -> ReadGuard<'_, T> { self.read() } #[inline(always)] + #[track_caller] pub fn borrow_mut(&self) -> WriteGuard<'_, T> { self.write() } From 74fec9b95ad308c3dc064bb38778aea4ec51f5ee Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 2 Nov 2022 02:13:27 +0000 Subject: [PATCH 4/6] Remove has_errors from FnCtxt --- compiler/rustc_hir_typeck/src/expr.rs | 2 -- .../rustc_hir_typeck/src/fn_ctxt/_impl.rs | 1 - .../rustc_hir_typeck/src/fn_ctxt/checks.rs | 8 +------ compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs | 4 ---- src/test/ui/error-codes/E0767.rs | 3 ++- src/test/ui/error-codes/E0767.stderr | 21 +++++++++++++++---- 6 files changed, 20 insertions(+), 19 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index 9fde62a81a1a6..47b5673e8b3d0 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -220,7 +220,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Hide the outer diverging and has_errors flags. let old_diverges = self.diverges.replace(Diverges::Maybe); - let old_has_errors = self.has_errors.replace(false); let ty = ensure_sufficient_stack(|| match &expr.kind { hir::ExprKind::Path( @@ -259,7 +258,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Combine the diverging and has_error flags. self.diverges.set(self.diverges.get() | old_diverges); - self.has_errors.set(self.has_errors.get() | old_has_errors); debug!("type of {} is...", self.tcx.hir().node_to_string(expr.hir_id)); debug!("... {:?}, expected is {:?}", ty, expected); diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs index 6a1cffe3e6025..38da0a47d7161 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs @@ -143,7 +143,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.typeck_results.borrow_mut().node_types_mut().insert(id, ty); if ty.references_error() { - self.has_errors.set(true); self.set_tainted_by_errors(); } } diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs index 8e0fcb56c7f37..e1955d838f253 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs @@ -1334,7 +1334,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Hide the outer diverging and `has_errors` flags. let old_diverges = self.diverges.replace(Diverges::Maybe); - let old_has_errors = self.has_errors.replace(false); match stmt.kind { hir::StmtKind::Local(l) => { @@ -1364,7 +1363,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // Combine the diverging and `has_error` flags. self.diverges.set(self.diverges.get() | old_diverges); - self.has_errors.set(self.has_errors.get() | old_has_errors); } pub fn check_block_no_value(&self, blk: &'tcx hir::Block<'tcx>) { @@ -1544,11 +1542,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.diverges.set(prev_diverges); } - let mut ty = ctxt.coerce.unwrap().complete(self); - - if self.has_errors.get() || ty.references_error() { - ty = self.tcx.ty_error() - } + let ty = ctxt.coerce.unwrap().complete(self); self.write_ty(blk.hir_id, ty); diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs index 0c600daf4459e..19839ad4d4c27 100644 --- a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs +++ b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs @@ -112,9 +112,6 @@ pub struct FnCtxt<'a, 'tcx> { /// the diverges flag is set to something other than `Maybe`. pub(super) diverges: Cell, - /// Whether any child nodes have any type errors. - pub(super) has_errors: Cell, - pub(super) enclosing_breakables: RefCell>, pub(super) inh: &'a Inherited<'tcx>, @@ -145,7 +142,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { resume_yield_tys: None, ps: Cell::new(UnsafetyState::function(hir::Unsafety::Normal, hir::CRATE_HIR_ID)), diverges: Cell::new(Diverges::Maybe), - has_errors: Cell::new(false), enclosing_breakables: RefCell::new(EnclosingBreakables { stack: Vec::new(), by_id: Default::default(), diff --git a/src/test/ui/error-codes/E0767.rs b/src/test/ui/error-codes/E0767.rs index 6c6cb746e6c75..14215d36a3833 100644 --- a/src/test/ui/error-codes/E0767.rs +++ b/src/test/ui/error-codes/E0767.rs @@ -1,6 +1,7 @@ -fn main () { +fn main() { 'a: loop { || { + //~^ ERROR mismatched types loop { break 'a; } //~ ERROR E0767 } } diff --git a/src/test/ui/error-codes/E0767.stderr b/src/test/ui/error-codes/E0767.stderr index 2429823306b6e..ee85247301c9c 100644 --- a/src/test/ui/error-codes/E0767.stderr +++ b/src/test/ui/error-codes/E0767.stderr @@ -1,14 +1,27 @@ error[E0767]: use of unreachable label `'a` - --> $DIR/E0767.rs:4:26 + --> $DIR/E0767.rs:5:26 | LL | 'a: loop { | -- unreachable label defined here -LL | || { +... LL | loop { break 'a; } | ^^ unreachable label `'a` | = note: labels are unreachable through functions, closures, async blocks and modules -error: aborting due to previous error +error[E0308]: mismatched types + --> $DIR/E0767.rs:3:9 + | +LL | / || { +LL | | +LL | | loop { break 'a; } +LL | | } + | |_________^ expected `()`, found closure + | + = note: expected unit type `()` + found closure `[closure@$DIR/E0767.rs:3:9: 3:11]` + +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0767`. +Some errors have detailed explanations: E0308, E0767. +For more information about an error, try `rustc --explain E0308`. From 59be5151287e29d5340d6189dea2f18206f51e02 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 2 Nov 2022 17:33:25 +0000 Subject: [PATCH 5/6] Properly render asyncness for traits without default body --- compiler/rustc_ty_utils/src/ty.rs | 2 +- src/librustdoc/clean/mod.rs | 32 +++++++++++++++++------------ src/librustdoc/clean/types.rs | 5 +---- src/test/rustdoc/async-trait-sig.rs | 14 +++++++++++++ 4 files changed, 35 insertions(+), 18 deletions(-) create mode 100644 src/test/rustdoc/async-trait-sig.rs diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs index 3eebb4ace477f..99d3bda6ebfff 100644 --- a/compiler/rustc_ty_utils/src/ty.rs +++ b/compiler/rustc_ty_utils/src/ty.rs @@ -413,7 +413,7 @@ fn issue33140_self_ty(tcx: TyCtxt<'_>, def_id: DefId) -> Option> { /// Check if a function is async. fn asyncness(tcx: TyCtxt<'_>, def_id: DefId) -> hir::IsAsync { let node = tcx.hir().get_by_def_id(def_id.expect_local()); - if let Some(fn_kind) = node.fn_kind() { fn_kind.asyncness() } else { hir::IsAsync::NotAsync } + node.fn_sig().map_or(hir::IsAsync::NotAsync, |sig| sig.header.asyncness) } /// Don't call this directly: use ``tcx.conservative_is_privately_uninhabited`` instead. diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 1ce0d1e4ffd02..84afdadfa002a 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -880,7 +880,7 @@ fn clean_fn_or_proc_macro<'tcx>( ProcMacroItem(ProcMacro { kind, helpers }) } None => { - let mut func = clean_function(cx, sig, generics, body_id); + let mut func = clean_function(cx, sig, generics, FunctionArgs::Body(body_id)); clean_fn_decl_legacy_const_generics(&mut func, attrs); FunctionItem(func) } @@ -917,16 +917,28 @@ fn clean_fn_decl_legacy_const_generics(func: &mut Function, attrs: &[ast::Attrib } } +enum FunctionArgs<'tcx> { + Body(hir::BodyId), + Names(&'tcx [Ident]), +} + fn clean_function<'tcx>( cx: &mut DocContext<'tcx>, sig: &hir::FnSig<'tcx>, generics: &hir::Generics<'tcx>, - body_id: hir::BodyId, + args: FunctionArgs<'tcx>, ) -> Box { let (generics, decl) = enter_impl_trait(cx, |cx| { // NOTE: generics must be cleaned before args let generics = clean_generics(generics, cx); - let args = clean_args_from_types_and_body_id(cx, sig.decl.inputs, body_id); + let args = match args { + FunctionArgs::Body(body_id) => { + clean_args_from_types_and_body_id(cx, sig.decl.inputs, body_id) + } + FunctionArgs::Names(names) => { + clean_args_from_types_and_names(cx, sig.decl.inputs, names) + } + }; let mut decl = clean_fn_decl_with_args(cx, sig.decl, args); if sig.header.is_async() { decl.output = decl.sugared_async_return_type(); @@ -1051,18 +1063,12 @@ fn clean_trait_item<'tcx>(trait_item: &hir::TraitItem<'tcx>, cx: &mut DocContext ), hir::TraitItemKind::Const(ty, None) => TyAssocConstItem(clean_ty(ty, cx)), hir::TraitItemKind::Fn(ref sig, hir::TraitFn::Provided(body)) => { - let m = clean_function(cx, sig, trait_item.generics, body); + let m = clean_function(cx, sig, trait_item.generics, FunctionArgs::Body(body)); MethodItem(m, None) } hir::TraitItemKind::Fn(ref sig, hir::TraitFn::Required(names)) => { - let (generics, decl) = enter_impl_trait(cx, |cx| { - // NOTE: generics must be cleaned before args - let generics = clean_generics(trait_item.generics, cx); - let args = clean_args_from_types_and_names(cx, sig.decl.inputs, names); - let decl = clean_fn_decl_with_args(cx, sig.decl, args); - (generics, decl) - }); - TyMethodItem(Box::new(Function { decl, generics })) + let m = clean_function(cx, sig, trait_item.generics, FunctionArgs::Names(names)); + TyMethodItem(m) } hir::TraitItemKind::Type(bounds, Some(default)) => { let generics = enter_impl_trait(cx, |cx| clean_generics(trait_item.generics, cx)); @@ -1099,7 +1105,7 @@ pub(crate) fn clean_impl_item<'tcx>( AssocConstItem(clean_ty(ty, cx), default) } hir::ImplItemKind::Fn(ref sig, body) => { - let m = clean_function(cx, sig, impl_.generics, body); + let m = clean_function(cx, sig, impl_.generics, FunctionArgs::Body(body)); let defaultness = cx.tcx.impl_defaultness(impl_.owner_id); MethodItem(m, Some(defaultness)) } diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 439311f064029..f1eb438b199ce 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -694,13 +694,10 @@ impl Item { asyncness: hir::IsAsync::NotAsync, } } - ItemKind::FunctionItem(_) | ItemKind::MethodItem(_, _) => { + ItemKind::FunctionItem(_) | ItemKind::MethodItem(_, _) | ItemKind::TyMethodItem(_) => { let def_id = self.item_id.as_def_id().unwrap(); build_fn_header(def_id, tcx, tcx.asyncness(def_id)) } - ItemKind::TyMethodItem(_) => { - build_fn_header(self.item_id.as_def_id().unwrap(), tcx, hir::IsAsync::NotAsync) - } _ => return None, }; Some(header) diff --git a/src/test/rustdoc/async-trait-sig.rs b/src/test/rustdoc/async-trait-sig.rs new file mode 100644 index 0000000000000..2578bc8f7a166 --- /dev/null +++ b/src/test/rustdoc/async-trait-sig.rs @@ -0,0 +1,14 @@ +// edition:2021 + +#![feature(async_fn_in_trait)] +#![allow(incomplete_features)] + +pub trait Foo { + // @has async_trait_sig/trait.Foo.html '//h4[@class="code-header"]' "async fn bar() -> i32" + async fn bar() -> i32; + + // @has async_trait_sig/trait.Foo.html '//h4[@class="code-header"]' "async fn baz() -> i32" + async fn baz() -> i32 { + 1 + } +} From 68e19aa4ac8812e83b80035988d915087a4183e5 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Wed, 2 Nov 2022 15:33:36 -0700 Subject: [PATCH 6/6] rustdoc: remove redundant mobile CSS `.sidebar-elems { background }` The exact same background is already set for its parent, the `nav.sidebar`. --- src/librustdoc/html/static/css/rustdoc.css | 1 - 1 file changed, 1 deletion(-) diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css index 360b6b9832a55..d7526498b0d66 100644 --- a/src/librustdoc/html/static/css/rustdoc.css +++ b/src/librustdoc/html/static/css/rustdoc.css @@ -1797,7 +1797,6 @@ in storage.js .sidebar-elems { margin-top: 1em; - background-color: var(--sidebar-background-color); } .content {