diff options
Diffstat (limited to 'src')
181 files changed, 1344 insertions, 966 deletions
diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py index e5a710c0a96..fe66b1d41bf 100644 --- a/src/bootstrap/bootstrap.py +++ b/src/bootstrap/bootstrap.py @@ -97,7 +97,7 @@ def _download(path, url, probably_big, verbose, exception): print("downloading {}".format(url), file=sys.stderr) try: - if probably_big or verbose: + if (probably_big or verbose) and "GITHUB_ACTIONS" not in os.environ: option = "-#" else: option = "-s" @@ -914,12 +914,7 @@ class RustBuild(object): # preserve existing RUSTFLAGS env.setdefault("RUSTFLAGS", "") - # we need to explicitly add +xgot here so that we can successfully bootstrap - # a usable stage1 compiler - # FIXME: remove this if condition on the next bootstrap bump - # cfg(bootstrap) - if self.build_triple().startswith('mips'): - env["RUSTFLAGS"] += " -Ctarget-feature=+xgot" + target_features = [] if self.get_toml("crt-static", build_section) == "true": target_features += ["+crt-static"] diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index c0c749552e6..766c187e8e8 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -115,6 +115,43 @@ impl RunConfig<'_> { } INTERNER.intern_list(crates) } + + /// Given an `alias` selected by the `Step` and the paths passed on the command line, + /// return a list of the crates that should be built. + /// + /// Normally, people will pass *just* `library` if they pass it. + /// But it's possible (although strange) to pass something like `library std core`. + /// Build all crates anyway, as if they hadn't passed the other args. + pub fn make_run_crates(&self, alias: Alias) -> Interned<Vec<String>> { + let has_alias = + self.paths.iter().any(|set| set.assert_single_path().path.ends_with(alias.as_str())); + if !has_alias { + return self.cargo_crates_in_set(); + } + + let crates = match alias { + Alias::Library => self.builder.in_tree_crates("sysroot", Some(self.target)), + Alias::Compiler => self.builder.in_tree_crates("rustc-main", Some(self.target)), + }; + + let crate_names = crates.into_iter().map(|krate| krate.name.to_string()).collect(); + INTERNER.intern_list(crate_names) + } +} + +#[derive(Debug, Copy, Clone)] +pub enum Alias { + Library, + Compiler, +} + +impl Alias { + fn as_str(self) -> &'static str { + match self { + Alias::Library => "library", + Alias::Compiler => "compiler", + } + } } /// A description of the crates in this set, suitable for passing to `builder.info`. @@ -358,7 +395,7 @@ impl StepDescription { eprintln!( "note: if you are adding a new Step to bootstrap itself, make sure you register it with `describe!`" ); - crate::detail_exit_macro!(1); + crate::exit!(1); } } } @@ -902,21 +939,6 @@ impl<'a> Builder<'a> { Self::new_internal(build, kind, paths.to_owned()) } - /// Creates a new standalone builder for use outside of the normal process - pub fn new_standalone( - build: &mut Build, - kind: Kind, - paths: Vec<PathBuf>, - stage: Option<u32>, - ) -> Builder<'_> { - // FIXME: don't mutate `build` - if let Some(stage) = stage { - build.config.stage = stage; - } - - Self::new_internal(build, kind, paths.to_owned()) - } - pub fn execute_cli(&self) { self.run_step_descriptions(&Builder::get_step_descriptions(self.kind), &self.paths); } @@ -1338,7 +1360,7 @@ impl<'a> Builder<'a> { "error: `x.py clippy` requires a host `rustc` toolchain with the `clippy` component" ); eprintln!("help: try `rustup component add clippy`"); - crate::detail_exit_macro!(1); + crate::exit!(1); }); if !t!(std::str::from_utf8(&output.stdout)).contains("nightly") { rustflags.arg("--cfg=bootstrap"); diff --git a/src/bootstrap/builder/tests.rs b/src/bootstrap/builder/tests.rs index 31dcee58216..65b8f7fd3b7 100644 --- a/src/bootstrap/builder/tests.rs +++ b/src/bootstrap/builder/tests.rs @@ -68,13 +68,17 @@ macro_rules! std { } macro_rules! doc_std { - ($host:ident => $target:ident, stage = $stage:literal) => { + ($host:ident => $target:ident, stage = $stage:literal) => {{ + let config = configure("doc", &["A"], &["A"]); + let build = Build::new(config); + let builder = Builder::new(&build); doc::Std::new( $stage, TargetSelection::from_user(stringify!($target)), + &builder, DocumentationFormat::HTML, ) - }; + }}; } macro_rules! rustc { diff --git a/src/bootstrap/check.rs b/src/bootstrap/check.rs index 1a0f0047812..9795f22e2b5 100644 --- a/src/bootstrap/check.rs +++ b/src/bootstrap/check.rs @@ -1,10 +1,8 @@ //! Implementation of compiling the compiler and standard library, in "check"-based modes. -use crate::builder::{crate_description, Builder, Kind, RunConfig, ShouldRun, Step}; +use crate::builder::{crate_description, Alias, Builder, Kind, RunConfig, ShouldRun, Step}; use crate::cache::Interned; -use crate::compile::{ - add_to_sysroot, make_run_crates, run_cargo, rustc_cargo, rustc_cargo_env, std_cargo, -}; +use crate::compile::{add_to_sysroot, run_cargo, rustc_cargo, rustc_cargo_env, std_cargo}; use crate::config::TargetSelection; use crate::tool::{prepare_tool_cargo, SourceType}; use crate::INTERNER; @@ -89,7 +87,7 @@ impl Step for Std { } fn make_run(run: RunConfig<'_>) { - let crates = make_run_crates(&run, "library"); + let crates = run.make_run_crates(Alias::Library); run.builder.ensure(Std { target: run.target, crates }); } @@ -137,10 +135,11 @@ impl Step for Std { let hostdir = builder.sysroot_libdir(compiler, compiler.host); add_to_sysroot(&builder, &libdir, &hostdir, &libstd_stamp(builder, compiler, target)); } + drop(_guard); // don't run on std twice with x.py clippy // don't check test dependencies if we haven't built libtest - if builder.kind == Kind::Clippy || !self.crates.is_empty() { + if builder.kind == Kind::Clippy || !self.crates.iter().any(|krate| krate == "test") { return; } @@ -200,10 +199,11 @@ pub struct Rustc { impl Rustc { pub fn new(target: TargetSelection, builder: &Builder<'_>) -> Self { - let mut crates = vec![]; - for krate in builder.in_tree_crates("rustc-main", None) { - crates.push(krate.name.to_string()); - } + let crates = builder + .in_tree_crates("rustc-main", Some(target)) + .into_iter() + .map(|krate| krate.name.to_string()) + .collect(); Self { target, crates: INTERNER.intern_list(crates) } } } @@ -218,7 +218,7 @@ impl Step for Rustc { } fn make_run(run: RunConfig<'_>) { - let crates = make_run_crates(&run, "compiler"); + let crates = run.make_run_crates(Alias::Compiler); run.builder.ensure(Rustc { target: run.target, crates }); } diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs index caa7417011e..f3d95b57a76 100644 --- a/src/bootstrap/compile.rs +++ b/src/bootstrap/compile.rs @@ -55,17 +55,6 @@ impl Std { } } -/// Given an `alias` selected by the `Step` and the paths passed on the command line, -/// return a list of the crates that should be built. -/// -/// Normally, people will pass *just* `library` if they pass it. -/// But it's possible (although strange) to pass something like `library std core`. -/// Build all crates anyway, as if they hadn't passed the other args. -pub(crate) fn make_run_crates(run: &RunConfig<'_>, alias: &str) -> Interned<Vec<String>> { - let has_alias = run.paths.iter().any(|set| set.assert_single_path().path.ends_with(alias)); - if has_alias { Default::default() } else { run.cargo_crates_in_set() } -} - impl Step for Std { type Output = (); const DEFAULT: bool = true; @@ -80,10 +69,15 @@ impl Step for Std { } fn make_run(run: RunConfig<'_>) { + // If the paths include "library", build the entire standard library. + let has_alias = + run.paths.iter().any(|set| set.assert_single_path().path.ends_with("library")); + let crates = if has_alias { Default::default() } else { run.cargo_crates_in_set() }; + run.builder.ensure(Std { compiler: run.builder.compiler(run.builder.top_stage, run.build_triple()), target: run.target, - crates: make_run_crates(&run, "library"), + crates, force_recompile: false, }); } @@ -228,13 +222,6 @@ fn copy_third_party_objects( ) -> Vec<(PathBuf, DependencyType)> { let mut target_deps = vec![]; - // FIXME: remove this in 2021 - if target == "x86_64-fortanix-unknown-sgx" { - if env::var_os("X86_FORTANIX_SGX_LIBS").is_some() { - builder.info("Warning: X86_FORTANIX_SGX_LIBS environment variable is ignored, libunwind is now compiled as part of rustbuild"); - } - } - if builder.config.sanitizers_enabled(target) && compiler.stage != 0 { // The sanitizers are only copied in stage1 or above, // to avoid creating dependency on LLVM. @@ -1826,7 +1813,7 @@ pub fn run_cargo( }); if !ok { - crate::detail_exit_macro!(1); + crate::exit!(1); } // Ok now we need to actually find all the files listed in `toplevel`. We've diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs index 34853743323..856a73a22b5 100644 --- a/src/bootstrap/config.rs +++ b/src/bootstrap/config.rs @@ -23,7 +23,7 @@ use crate::channel::{self, GitInfo}; pub use crate::flags::Subcommand; use crate::flags::{Color, Flags, Warnings}; use crate::util::{exe, output, t}; -use build_helper::detail_exit_macro; +use build_helper::exit; use once_cell::sync::OnceCell; use semver::Version; use serde::{Deserialize, Deserializer}; @@ -646,7 +646,7 @@ macro_rules! define_config { panic!("overriding existing option") } else { eprintln!("overriding existing option: `{}`", stringify!($field)); - detail_exit_macro!(2); + exit!(2); } } else { self.$field = other.$field; @@ -745,7 +745,7 @@ impl<T> Merge for Option<T> { panic!("overriding existing option") } else { eprintln!("overriding existing option"); - detail_exit_macro!(2); + exit!(2); } } else { *self = other; @@ -1101,7 +1101,7 @@ impl Config { .and_then(|table: toml::Value| TomlConfig::deserialize(table)) .unwrap_or_else(|err| { eprintln!("failed to parse TOML configuration '{}': {err}", file.display()); - detail_exit_macro!(2); + exit!(2); }) } Self::parse_inner(args, get_toml) @@ -1135,7 +1135,7 @@ impl Config { eprintln!( "Cannot use both `llvm_bolt_profile_generate` and `llvm_bolt_profile_use` at the same time" ); - detail_exit_macro!(1); + exit!(1); } // Infer the rest of the configuration. @@ -1259,7 +1259,7 @@ impl Config { } } eprintln!("failed to parse override `{option}`: `{err}"); - detail_exit_macro!(2) + exit!(2) } toml.merge(override_toml, ReplaceOpt::Override); @@ -1742,6 +1742,18 @@ impl Config { } } + /// Runs a command, printing out nice contextual information if it fails. + /// Exits if the command failed to execute at all, otherwise returns its + /// `status.success()`. + #[deprecated = "use `Builder::try_run` instead where possible"] + pub(crate) fn try_run(&self, cmd: &mut Command) -> Result<(), ()> { + if self.dry_run() { + return Ok(()); + } + self.verbose(&format!("running: {:?}", cmd)); + build_helper::util::try_run(cmd, self.is_verbose()) + } + /// A git invocation which runs inside the source directory. /// /// Use this rather than `Command::new("git")` in order to support out-of-tree builds. @@ -2007,7 +2019,7 @@ impl Config { "Unexpected rustc version: {}, we should use {}/{} to build source with {}", rustc_version, prev_version, source_version, source_version ); - detail_exit_macro!(1); + exit!(1); } } @@ -2043,7 +2055,7 @@ impl Config { println!("help: maybe your repository history is too shallow?"); println!("help: consider disabling `download-rustc`"); println!("help: or fetch enough history to include one upstream commit"); - crate::detail_exit_macro!(1); + crate::exit!(1); } // Warn if there were changes to the compiler or standard library since the ancestor commit. diff --git a/src/bootstrap/configure.py b/src/bootstrap/configure.py index e8eebdfb5a5..a7beb2a1767 100755 --- a/src/bootstrap/configure.py +++ b/src/bootstrap/configure.py @@ -550,6 +550,8 @@ if __name__ == "__main__": # If 'config.toml' already exists, exit the script at this point quit_if_file_exists('config.toml') + if "GITHUB_ACTIONS" in os.environ: + print("::group::Configure the build") p("processing command line") # Parse all known arguments into a configuration structure that reflects the # TOML we're going to write out @@ -572,3 +574,5 @@ if __name__ == "__main__": p("") p("run `python {}/x.py --help`".format(rust_dir)) + if "GITHUB_ACTIONS" in os.environ: + print("::endgroup::") diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index b34a4b2dc63..8c71b7f7fc2 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -106,7 +106,12 @@ impl Step for JsonDocs { /// Builds the `rust-docs-json` installer component. fn run(self, builder: &Builder<'_>) -> Option<GeneratedTarball> { let host = self.host; - builder.ensure(crate::doc::Std::new(builder.top_stage, host, DocumentationFormat::JSON)); + builder.ensure(crate::doc::Std::new( + builder.top_stage, + host, + builder, + DocumentationFormat::JSON, + )); let dest = "share/doc/rust/json"; @@ -897,7 +902,9 @@ impl Step for Src { /// Creates the `rust-src` installer component fn run(self, builder: &Builder<'_>) -> GeneratedTarball { - builder.update_submodule(&Path::new("src/llvm-project")); + if !builder.config.dry_run() { + builder.update_submodule(&Path::new("src/llvm-project")); + } let tarball = Tarball::new_targetless(builder, "rust-src"); diff --git a/src/bootstrap/doc.rs b/src/bootstrap/doc.rs index 5ebfe0995a8..e58f736d67f 100644 --- a/src/bootstrap/doc.rs +++ b/src/bootstrap/doc.rs @@ -11,10 +11,9 @@ use std::fs; use std::path::{Path, PathBuf}; use crate::builder::crate_description; -use crate::builder::{Builder, Compiler, Kind, RunConfig, ShouldRun, Step}; +use crate::builder::{Alias, Builder, Compiler, Kind, RunConfig, ShouldRun, Step}; use crate::cache::{Interned, INTERNER}; use crate::compile; -use crate::compile::make_run_crates; use crate::config::{Config, TargetSelection}; use crate::tool::{self, prepare_tool_cargo, SourceType, Tool}; use crate::util::{symlink_dir, t, up_to_date}; @@ -221,8 +220,11 @@ impl Step for TheBook { // build the version info page and CSS let shared_assets = builder.ensure(SharedAssets { target }); + // build the command first so we don't nest GHA groups + builder.rustdoc_cmd(compiler); + // build the redirect pages - builder.msg_doc(compiler, "book redirect pages", target); + let _guard = builder.msg_doc(compiler, "book redirect pages", target); for file in t!(fs::read_dir(builder.src.join(&relative_path).join("redirects"))) { let file = t!(file); let path = file.path(); @@ -306,7 +308,7 @@ impl Step for Standalone { fn run(self, builder: &Builder<'_>) { let target = self.target; let compiler = self.compiler; - builder.msg_doc(compiler, "standalone", target); + let _guard = builder.msg_doc(compiler, "standalone", target); let out = builder.doc_out(target); t!(fs::create_dir_all(&out)); @@ -424,8 +426,18 @@ pub struct Std { } impl Std { - pub(crate) fn new(stage: u32, target: TargetSelection, format: DocumentationFormat) -> Self { - Std { stage, target, format, crates: INTERNER.intern_list(vec![]) } + pub(crate) fn new( + stage: u32, + target: TargetSelection, + builder: &Builder<'_>, + format: DocumentationFormat, + ) -> Self { + let crates = builder + .in_tree_crates("sysroot", Some(target)) + .into_iter() + .map(|krate| krate.name.to_string()) + .collect(); + Std { stage, target, format, crates: INTERNER.intern_list(crates) } } } @@ -447,7 +459,7 @@ impl Step for Std { } else { DocumentationFormat::HTML }, - crates: make_run_crates(&run, "library"), + crates: run.make_run_crates(Alias::Library), }); } @@ -455,7 +467,7 @@ impl Step for Std { /// /// This will generate all documentation for the standard library and its /// dependencies. This is largely just a wrapper around `cargo doc`. - fn run(mut self, builder: &Builder<'_>) { + fn run(self, builder: &Builder<'_>) { let stage = self.stage; let target = self.target; let out = match self.format { @@ -493,20 +505,17 @@ impl Step for Std { return; } - // Look for library/std, library/core etc in the `x.py doc` arguments and - // open the corresponding rendered docs. - if self.crates.is_empty() { - self.crates = INTERNER.intern_list(vec!["library".to_owned()]); - }; - - for requested_crate in &*self.crates { - if requested_crate == "library" { - // For `x.py doc library --open`, open `std` by default. - let index = out.join("std").join("index.html"); - builder.open_in_browser(index); - } else if STD_PUBLIC_CRATES.iter().any(|&k| k == requested_crate) { - let index = out.join(requested_crate).join("index.html"); - builder.open_in_browser(index); + if builder.paths.iter().any(|path| path.ends_with("library")) { + // For `x.py doc library --open`, open `std` by default. + let index = out.join("std").join("index.html"); + builder.open_in_browser(index); + } else { + for requested_crate in &*self.crates { + if STD_PUBLIC_CRATES.iter().any(|&k| k == requested_crate) { + let index = out.join(requested_crate).join("index.html"); + builder.open_in_browser(index); + break; + } } } } @@ -539,9 +548,6 @@ impl DocumentationFormat { } /// Build the documentation for public standard library crates. -/// -/// `requested_crates` can be used to build only a subset of the crates. If empty, all crates will -/// be built. fn doc_std( builder: &Builder<'_>, format: DocumentationFormat, @@ -560,10 +566,6 @@ fn doc_std( let compiler = builder.compiler(stage, builder.config.build); - let description = - format!("library{} in {} format", crate_description(&requested_crates), format.as_str()); - let _guard = builder.msg_doc(compiler, &description, target); - let target_doc_dir_name = if format == DocumentationFormat::JSON { "json-doc" } else { "doc" }; let target_dir = builder.stage_out(compiler, Mode::Std).join(target.triple).join(target_doc_dir_name); @@ -592,22 +594,18 @@ fn doc_std( cargo.rustdocflag("--document-private-items").rustdocflag("--document-hidden-items"); } - // HACK: because we use `--manifest-path library/sysroot/Cargo.toml`, cargo thinks we only want to document that specific crate, not its dependencies. - // Override its default. - let built_crates = if requested_crates.is_empty() { - builder - .in_tree_crates("sysroot", None) - .into_iter() - .map(|krate| krate.name.to_string()) - .collect() - } else { - requested_crates.to_vec() - }; - - for krate in built_crates { + for krate in requested_crates { + if krate == "sysroot" { + // The sysroot crate is an implementation detail, don't include it in public docs. + continue; + } cargo.arg("-p").arg(krate); } + let description = + format!("library{} in {} format", crate_description(&requested_crates), format.as_str()); + let _guard = builder.msg_doc(compiler, &description, target); + builder.run(&mut cargo.into()); builder.cp_r(&out_dir, &out); } @@ -621,20 +619,10 @@ pub struct Rustc { impl Rustc { pub(crate) fn new(stage: u32, target: TargetSelection, builder: &Builder<'_>) -> Self { - // Find dependencies for top level crates. - let root_crates = vec![ - INTERNER.intern_str("rustc_driver"), - INTERNER.intern_str("rustc_codegen_llvm"), - INTERNER.intern_str("rustc_codegen_ssa"), - ]; - let crates: Vec<_> = root_crates - .iter() - .flat_map(|krate| { - builder - .in_tree_crates(krate, Some(target)) - .into_iter() - .map(|krate| krate.name.to_string()) - }) + let crates = builder + .in_tree_crates("rustc-main", Some(target)) + .into_iter() + .map(|krate| krate.name.to_string()) .collect(); Self { stage, target, crates: INTERNER.intern_list(crates) } } @@ -656,7 +644,7 @@ impl Step for Rustc { run.builder.ensure(Rustc { stage: run.builder.top_stage, target: run.target, - crates: make_run_crates(&run, "compiler"), + crates: run.make_run_crates(Alias::Compiler), }); } @@ -666,7 +654,7 @@ impl Step for Rustc { /// Compiler documentation is distributed separately, so we make sure /// we do not merge it with the other documentation from std, test and /// proc_macros. This is largely just a wrapper around `cargo doc`. - fn run(mut self, builder: &Builder<'_>) { + fn run(self, builder: &Builder<'_>) { let stage = self.stage; let target = self.target; @@ -726,24 +714,26 @@ impl Step for Rustc { let mut to_open = None; - if self.crates.is_empty() { - self.crates = INTERNER.intern_list(vec!["rustc_driver".to_owned()]); - }; - for krate in &*self.crates { // Create all crate output directories first to make sure rustdoc uses // relative links. // FIXME: Cargo should probably do this itself. - t!(fs::create_dir_all(out_dir.join(krate))); + let dir_name = krate.replace("-", "_"); + t!(fs::create_dir_all(out_dir.join(&*dir_name))); cargo.arg("-p").arg(krate); if to_open.is_none() { - to_open = Some(krate); + to_open = Some(dir_name); } } builder.run(&mut cargo.into()); - // Let's open the first crate documentation page: - if let Some(krate) = to_open { + + if builder.paths.iter().any(|path| path.ends_with("compiler")) { + // For `x.py doc compiler --open`, open `rustc_middle` by default. + let index = out.join("rustc_middle").join("index.html"); + builder.open_in_browser(index); + } else if let Some(krate) = to_open { + // Let's open the first crate documentation page: let index = out.join(krate).join("index.html"); builder.open_in_browser(index); } @@ -812,8 +802,6 @@ macro_rules! tool_doc { SourceType::Submodule }; - builder.msg_doc(compiler, stringify!($tool).to_lowercase(), target); - // Symlink compiler docs to the output directory of rustdoc documentation. let out_dirs = [ builder.stage_out(compiler, Mode::ToolRustc).join(target.triple).join("doc"), @@ -852,6 +840,8 @@ macro_rules! tool_doc { cargo.rustdocflag("--show-type-layout"); cargo.rustdocflag("--generate-link-to-definition"); cargo.rustdocflag("-Zunstable-options"); + + let _guard = builder.msg_doc(compiler, stringify!($tool).to_lowercase(), target); builder.run(&mut cargo.into()); } } @@ -1073,7 +1063,16 @@ impl Step for RustcBook { // config.toml), then this needs to explicitly update the dylib search // path. builder.add_rustc_lib_path(self.compiler, &mut cmd); + let doc_generator_guard = builder.msg( + Kind::Run, + self.compiler.stage, + "lint-docs", + self.compiler.host, + self.target, + ); builder.run(&mut cmd); + drop(doc_generator_guard); + // Run rustbook/mdbook to generate the HTML pages. builder.ensure(RustbookSrc { target: self.target, diff --git a/src/bootstrap/download.rs b/src/bootstrap/download.rs index eb1941cd889..1316461fde0 100644 --- a/src/bootstrap/download.rs +++ b/src/bootstrap/download.rs @@ -7,7 +7,7 @@ use std::{ process::{Command, Stdio}, }; -use build_helper::util::try_run; +use build_helper::ci::CiEnv; use once_cell::sync::OnceCell; use xz2::bufread::XzDecoder; @@ -21,6 +21,12 @@ use crate::{ static SHOULD_FIX_BINS_AND_DYLIBS: OnceCell<bool> = OnceCell::new(); +/// `Config::try_run` wrapper for this module to avoid warnings on `try_run`, since we don't have access to a `builder` yet. +fn try_run(config: &Config, cmd: &mut Command) -> Result<(), ()> { + #[allow(deprecated)] + config.try_run(cmd) +} + /// Generic helpers that are useful anywhere in bootstrap. impl Config { pub fn is_verbose(&self) -> bool { @@ -52,17 +58,6 @@ impl Config { } /// Runs a command, printing out nice contextual information if it fails. - /// Exits if the command failed to execute at all, otherwise returns its - /// `status.success()`. - pub(crate) fn try_run(&self, cmd: &mut Command) -> Result<(), ()> { - if self.dry_run() { - return Ok(()); - } - self.verbose(&format!("running: {:?}", cmd)); - try_run(cmd, self.is_verbose()) - } - - /// Runs a command, printing out nice contextual information if it fails. /// Returns false if do not execute at all, otherwise returns its /// `status.success()`. pub(crate) fn check_run(&self, cmd: &mut Command) -> bool { @@ -156,14 +151,16 @@ impl Config { ]; } "; - nix_build_succeeded = self - .try_run(Command::new("nix-build").args(&[ + nix_build_succeeded = try_run( + self, + Command::new("nix-build").args(&[ Path::new("-E"), Path::new(NIX_EXPR), Path::new("-o"), &nix_deps_dir, - ])) - .is_ok(); + ]), + ) + .is_ok(); nix_deps_dir }); if !nix_build_succeeded { @@ -188,7 +185,7 @@ impl Config { patchelf.args(&["--set-interpreter", dynamic_linker.trim_end()]); } - let _ = self.try_run(patchelf.arg(fname)); + let _ = try_run(self, patchelf.arg(fname)); } fn download_file(&self, url: &str, dest_path: &Path, help_on_error: &str) { @@ -213,7 +210,6 @@ impl Config { // Try curl. If that fails and we are on windows, fallback to PowerShell. let mut curl = Command::new("curl"); curl.args(&[ - "-#", "-y", "30", "-Y", @@ -224,6 +220,12 @@ impl Config { "3", "-SRf", ]); + // Don't print progress in CI; the \r wrapping looks bad and downloads don't take long enough for progress to be useful. + if CiEnv::is_ci() { + curl.arg("-s"); + } else { + curl.arg("--progress-bar"); + } curl.arg(url); let f = File::create(tempfile).unwrap(); curl.stdout(Stdio::from(f)); @@ -231,7 +233,7 @@ impl Config { if self.build.contains("windows-msvc") { eprintln!("Fallback to PowerShell"); for _ in 0..3 { - if self.try_run(Command::new("PowerShell.exe").args(&[ + if try_run(self, Command::new("PowerShell.exe").args(&[ "/nologo", "-Command", "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12;", @@ -248,7 +250,7 @@ impl Config { if !help_on_error.is_empty() { eprintln!("{}", help_on_error); } - crate::detail_exit_macro!(1); + crate::exit!(1); } } diff --git a/src/bootstrap/flags.rs b/src/bootstrap/flags.rs index a882336c3c4..d67aafff841 100644 --- a/src/bootstrap/flags.rs +++ b/src/bootstrap/flags.rs @@ -193,7 +193,7 @@ impl Flags { } else { panic!("No paths available for subcommand `{}`", subcommand.as_str()); } - crate::detail_exit_macro!(0); + crate::exit!(0); } Flags::parse_from(it) @@ -538,7 +538,7 @@ pub fn get_completion<G: clap_complete::Generator>(shell: G, path: &Path) -> Opt } else { std::fs::read_to_string(path).unwrap_or_else(|_| { eprintln!("couldn't read {}", path.display()); - crate::detail_exit_macro!(1) + crate::exit!(1) }) }; let mut buf = Vec::new(); diff --git a/src/bootstrap/format.rs b/src/bootstrap/format.rs index 4330e126398..cfc9c4de60f 100644 --- a/src/bootstrap/format.rs +++ b/src/bootstrap/format.rs @@ -40,7 +40,7 @@ fn rustfmt(src: &Path, rustfmt: &Path, paths: &[PathBuf], check: bool) -> impl F code, run `./x.py fmt` instead.", cmd_debug, ); - crate::detail_exit_macro!(1); + crate::exit!(1); } true } @@ -200,7 +200,7 @@ pub fn format(build: &Builder<'_>, check: bool, paths: &[PathBuf]) { let rustfmt_path = build.initial_rustfmt().unwrap_or_else(|| { eprintln!("./x.py fmt is not supported on this channel"); - crate::detail_exit_macro!(1); + crate::exit!(1); }); assert!(rustfmt_path.exists(), "{}", rustfmt_path.display()); let src = build.src.clone(); diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index 0b509132043..de43a401926 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -27,7 +27,7 @@ use std::process::{Command, Stdio}; use std::str; use build_helper::ci::{gha, CiEnv}; -use build_helper::detail_exit_macro; +use build_helper::exit; use channel::GitInfo; use config::{DryRun, Target}; use filetime::FileTime; @@ -191,7 +191,7 @@ pub enum GitRepo { /// although most functions are implemented as free functions rather than /// methods specifically on this structure itself (to make it easier to /// organize). -#[cfg_attr(not(feature = "build-metrics"), derive(Clone))] +#[derive(Clone)] pub struct Build { /// User-specified configuration from `config.toml`. config: Config, @@ -333,7 +333,6 @@ forward! { create(path: &Path, s: &str), remove(f: &Path), tempdir() -> PathBuf, - try_run(cmd: &mut Command) -> Result<(), ()>, llvm_link_shared() -> bool, download_rustc() -> bool, initial_rustfmt() -> Option<PathBuf>, @@ -617,7 +616,9 @@ impl Build { } // Save any local changes, but avoid running `git stash pop` if there are none (since it will exit with an error). + #[allow(deprecated)] // diff-index reports the modifications through the exit status let has_local_modifications = self + .config .try_run( Command::new("git") .args(&["diff-index", "--quiet", "HEAD"]) @@ -711,7 +712,7 @@ impl Build { for failure in failures.iter() { eprintln!(" - {}\n", failure); } - detail_exit_macro!(1); + exit!(1); } #[cfg(feature = "build-metrics")] @@ -971,12 +972,36 @@ impl Build { /// Runs a command, printing out nice contextual information if it fails. /// Exits if the command failed to execute at all, otherwise returns its /// `status.success()`. - fn try_run_quiet(&self, cmd: &mut Command) -> bool { + fn run_quiet_delaying_failure(&self, cmd: &mut Command) -> bool { if self.config.dry_run() { return true; } - self.verbose(&format!("running: {:?}", cmd)); - try_run_suppressed(cmd) + if !self.fail_fast { + self.verbose(&format!("running: {:?}", cmd)); + if !try_run_suppressed(cmd) { + let mut failures = self.delayed_failures.borrow_mut(); + failures.push(format!("{:?}", cmd)); + return false; + } + } else { + self.run_quiet(cmd); + } + true + } + + /// Runs a command, printing out contextual info if it fails, and delaying errors until the build finishes. + pub(crate) fn run_delaying_failure(&self, cmd: &mut Command) -> bool { + if !self.fail_fast { + #[allow(deprecated)] // can't use Build::try_run, that's us + if self.config.try_run(cmd).is_err() { + let mut failures = self.delayed_failures.borrow_mut(); + failures.push(format!("{:?}", cmd)); + return false; + } + } else { + self.run(cmd); + } + true } pub fn is_verbose_than(&self, level: usize) -> bool { @@ -999,6 +1024,8 @@ impl Build { } } + #[must_use = "Groups should not be dropped until the Step finishes running"] + #[track_caller] fn msg_check( &self, what: impl Display, @@ -1007,6 +1034,8 @@ impl Build { self.msg(Kind::Check, self.config.stage, what, self.config.build, target) } + #[must_use = "Groups should not be dropped until the Step finishes running"] + #[track_caller] fn msg_doc( &self, compiler: Compiler, @@ -1016,6 +1045,8 @@ impl Build { self.msg(Kind::Doc, compiler.stage, what, compiler.host, target.into()) } + #[must_use = "Groups should not be dropped until the Step finishes running"] + #[track_caller] fn msg_build( &self, compiler: Compiler, @@ -1028,6 +1059,8 @@ impl Build { /// Return a `Group` guard for a [`Step`] that is built for each `--stage`. /// /// [`Step`]: crate::builder::Step + #[must_use = "Groups should not be dropped until the Step finishes running"] + #[track_caller] fn msg( &self, action: impl Into<Kind>, @@ -1054,6 +1087,8 @@ impl Build { /// Return a `Group` guard for a [`Step`] that is only built once and isn't affected by `--stage`. /// /// [`Step`]: crate::builder::Step + #[must_use = "Groups should not be dropped until the Step finishes running"] + #[track_caller] fn msg_unstaged( &self, action: impl Into<Kind>, @@ -1065,6 +1100,8 @@ impl Build { self.group(&msg) } + #[must_use = "Groups should not be dropped until the Step finishes running"] + #[track_caller] fn msg_sysroot_tool( &self, action: impl Into<Kind>, @@ -1083,6 +1120,7 @@ impl Build { self.group(&msg) } + #[track_caller] fn group(&self, msg: &str) -> Option<gha::Group> { match self.config.dry_run { DryRun::SelfCheck => None, @@ -1502,6 +1540,7 @@ impl Build { } } } + ret.sort_unstable_by_key(|krate| krate.name); // reproducible order needed for tests ret } @@ -1515,7 +1554,7 @@ impl Build { "Error: Unable to find the stamp file {}, did you try to keep a nonexistent build stage?", stamp.display() ); - crate::detail_exit_macro!(1); + crate::exit!(1); } let mut paths = Vec::new(); @@ -1707,7 +1746,7 @@ Alternatively, set `download-ci-llvm = true` in that `[llvm]` section to download LLVM rather than building it. " ); - detail_exit_macro!(1); + exit!(1); } } diff --git a/src/bootstrap/metrics.rs b/src/bootstrap/metrics.rs index b73df7fe822..cf8d33dfcb0 100644 --- a/src/bootstrap/metrics.rs +++ b/src/bootstrap/metrics.rs @@ -40,6 +40,13 @@ pub(crate) struct BuildMetrics { state: RefCell<MetricsState>, } +/// NOTE: this isn't really cloning anything, but `x suggest` doesn't need metrics so this is probably ok. +impl Clone for BuildMetrics { + fn clone(&self) -> Self { + Self::init() + } +} + impl BuildMetrics { pub(crate) fn init() -> Self { let state = RefCell::new(MetricsState { diff --git a/src/bootstrap/render_tests.rs b/src/bootstrap/render_tests.rs index ccd067053ef..6802bf4511b 100644 --- a/src/bootstrap/render_tests.rs +++ b/src/bootstrap/render_tests.rs @@ -30,7 +30,7 @@ pub(crate) fn try_run_tests(builder: &Builder<'_>, cmd: &mut Command, stream: bo if !run_tests(builder, cmd, stream) { if builder.fail_fast { - crate::detail_exit_macro!(1); + crate::exit!(1); } else { let mut failures = builder.delayed_failures.borrow_mut(); failures.push(format!("{cmd:?}")); diff --git a/src/bootstrap/run.rs b/src/bootstrap/run.rs index 70b91700043..4082f5bb9b1 100644 --- a/src/bootstrap/run.rs +++ b/src/bootstrap/run.rs @@ -24,8 +24,7 @@ impl Step for ExpandYamlAnchors { /// anchors in them, since GitHub Actions doesn't support them. fn run(self, builder: &Builder<'_>) { builder.info("Expanding YAML anchors in the GitHub Actions configuration"); - try_run( - builder, + builder.run_delaying_failure( &mut builder.tool_cmd(Tool::ExpandYamlAnchors).arg("generate").arg(&builder.src), ); } @@ -39,19 +38,6 @@ impl Step for ExpandYamlAnchors { } } -fn try_run(builder: &Builder<'_>, cmd: &mut Command) -> bool { - if !builder.fail_fast { - if builder.try_run(cmd).is_err() { - let mut failures = builder.delayed_failures.borrow_mut(); - failures.push(format!("{:?}", cmd)); - return false; - } - } else { - builder.run(cmd); - } - true -} - #[derive(Debug, PartialOrd, Ord, Copy, Clone, Hash, PartialEq, Eq)] pub struct BuildManifest; diff --git a/src/bootstrap/sanity.rs b/src/bootstrap/sanity.rs index 8f5ba42736b..9321fc1bcb8 100644 --- a/src/bootstrap/sanity.rs +++ b/src/bootstrap/sanity.rs @@ -104,7 +104,7 @@ You should install cmake, or set `download-ci-llvm = true` in the than building it. " ); - crate::detail_exit_macro!(1); + crate::exit!(1); } } diff --git a/src/bootstrap/setup.rs b/src/bootstrap/setup.rs index 34c6ccf1365..2075c58598d 100644 --- a/src/bootstrap/setup.rs +++ b/src/bootstrap/setup.rs @@ -203,7 +203,7 @@ fn setup_config_toml(path: &PathBuf, profile: Profile, config: &Config) { "note: this will use the configuration in {}", profile.include_path(&config.src).display() ); - crate::detail_exit_macro!(1); + crate::exit!(1); } let settings = format!( @@ -389,7 +389,7 @@ pub fn interactive_path() -> io::Result<Profile> { io::stdin().read_line(&mut input)?; if input.is_empty() { eprintln!("EOF on stdin, when expecting answer to question. Giving up."); - crate::detail_exit_macro!(1); + crate::exit!(1); } break match parse_with_abbrev(&input) { Ok(profile) => profile, diff --git a/src/bootstrap/suggest.rs b/src/bootstrap/suggest.rs index ff20ebec267..f225104bda9 100644 --- a/src/bootstrap/suggest.rs +++ b/src/bootstrap/suggest.rs @@ -4,18 +4,11 @@ use std::str::FromStr; use std::path::PathBuf; -use crate::{ - builder::{Builder, Kind}, - tool::Tool, -}; +use clap::Parser; -#[cfg(feature = "build-metrics")] -pub fn suggest(builder: &Builder<'_>, run: bool) { - panic!("`x suggest` is not supported with `build-metrics`") -} +use crate::{builder::Builder, tool::Tool}; /// Suggests a list of possible `x.py` commands to run based on modified files in branch. -#[cfg(not(feature = "build-metrics"))] pub fn suggest(builder: &Builder<'_>, run: bool) { let suggestions = builder.tool_cmd(Tool::SuggestTests).output().expect("failed to run `suggest-tests` tool"); @@ -67,12 +60,13 @@ pub fn suggest(builder: &Builder<'_>, run: bool) { if run { for sug in suggestions { - let mut build = builder.build.clone(); - - let builder = - Builder::new_standalone(&mut build, Kind::parse(&sug.0).unwrap(), sug.2, sug.1); - - builder.execute_cli() + let mut build: crate::Build = builder.build.clone(); + build.config.paths = sug.2; + build.config.cmd = crate::flags::Flags::parse_from(["x.py", sug.0]).cmd; + if let Some(stage) = sug.1 { + build.config.stage = stage; + } + build.build(); } } else { println!("help: consider using the `--run` flag to automatically run suggested tests"); diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs index d7303427c3b..44b8c2d8c01 100644 --- a/src/bootstrap/test.rs +++ b/src/bootstrap/test.rs @@ -48,32 +48,6 @@ const MIR_OPT_BLESS_TARGET_MAPPING: &[(&str, &str)] = &[ // build for, so there is no entry for "aarch64-apple-darwin" here. ]; -fn try_run(builder: &Builder<'_>, cmd: &mut Command) -> bool { - if !builder.fail_fast { - if builder.try_run(cmd).is_err() { - let mut failures = builder.delayed_failures.borrow_mut(); - failures.push(format!("{:?}", cmd)); - return false; - } - } else { - builder.run(cmd); - } - true -} - -fn try_run_quiet(builder: &Builder<'_>, cmd: &mut Command) -> bool { - if !builder.fail_fast { - if !builder.try_run_quiet(cmd) { - let mut failures = builder.delayed_failures.borrow_mut(); - failures.push(format!("{:?}", cmd)); - return false; - } - } else { - builder.run_quiet(cmd); - } - true -} - #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] pub struct CrateBootstrap { path: Interned<PathBuf>, @@ -117,14 +91,8 @@ impl Step for CrateBootstrap { SourceType::InTree, &[], ); - builder.info(&format!( - "{} {} stage0 ({})", - builder.kind.description(), - path, - bootstrap_host, - )); let crate_name = path.rsplit_once('/').unwrap().1; - run_cargo_test(cargo, &[], &[], crate_name, compiler, bootstrap_host, builder); + run_cargo_test(cargo, &[], &[], crate_name, crate_name, compiler, bootstrap_host, builder); } } @@ -163,6 +131,7 @@ You can skip linkcheck with --exclude src/tools/linkchecker" // Test the linkchecker itself. let bootstrap_host = builder.config.build; let compiler = builder.compiler(0, bootstrap_host); + let cargo = tool::prepare_tool_cargo( builder, compiler, @@ -173,7 +142,16 @@ You can skip linkcheck with --exclude src/tools/linkchecker" SourceType::InTree, &[], ); - run_cargo_test(cargo, &[], &[], "linkchecker", compiler, bootstrap_host, builder); + run_cargo_test( + cargo, + &[], + &[], + "linkchecker", + "linkchecker self tests", + compiler, + bootstrap_host, + builder, + ); if builder.doc_tests == DocTests::No { return; @@ -182,12 +160,14 @@ You can skip linkcheck with --exclude src/tools/linkchecker" // Build all the default documentation. builder.default_doc(&[]); + // Build the linkchecker before calling `msg`, since GHA doesn't support nested groups. + let mut linkchecker = builder.tool_cmd(Tool::Linkchecker); + // Run the linkchecker. + let _guard = + builder.msg(Kind::Test, compiler.stage, "Linkcheck", bootstrap_host, bootstrap_host); let _time = util::timeit(&builder); - try_run( - builder, - builder.tool_cmd(Tool::Linkchecker).arg(builder.out.join(host.triple).join("doc")), - ); + builder.run_delaying_failure(linkchecker.arg(builder.out.join(host.triple).join("doc"))); } fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { @@ -240,7 +220,9 @@ impl Step for HtmlCheck { builder.default_doc(&[]); builder.ensure(crate::doc::Rustc::new(builder.top_stage, self.target, builder)); - try_run(builder, builder.tool_cmd(Tool::HtmlChecker).arg(builder.doc_out(self.target))); + builder.run_delaying_failure( + builder.tool_cmd(Tool::HtmlChecker).arg(builder.doc_out(self.target)), + ); } } @@ -279,8 +261,7 @@ impl Step for Cargotest { let _time = util::timeit(&builder); let mut cmd = builder.tool_cmd(Tool::CargoTest); - try_run( - builder, + builder.run_delaying_failure( cmd.arg(&cargo) .arg(&out_dir) .args(builder.config.test_args()) @@ -406,7 +387,7 @@ impl Step for RustAnalyzer { cargo.env("SKIP_SLOW_TESTS", "1"); cargo.add_rustc_lib_path(builder, compiler); - run_cargo_test(cargo, &[], &[], "rust-analyzer", compiler, host, builder); + run_cargo_test(cargo, &[], &[], "rust-analyzer", "rust-analyzer", compiler, host, builder); } } @@ -455,7 +436,7 @@ impl Step for Rustfmt { cargo.add_rustc_lib_path(builder, compiler); - run_cargo_test(cargo, &[], &[], "rustfmt", compiler, host, builder); + run_cargo_test(cargo, &[], &[], "rustfmt", "rustfmt", compiler, host, builder); } } @@ -503,7 +484,16 @@ impl Step for RustDemangler { cargo.env("RUST_DEMANGLER_DRIVER_PATH", rust_demangler); cargo.add_rustc_lib_path(builder, compiler); - run_cargo_test(cargo, &[], &[], "rust-demangler", compiler, host, builder); + run_cargo_test( + cargo, + &[], + &[], + "rust-demangler", + "rust-demangler", + compiler, + host, + builder, + ); } } @@ -547,6 +537,13 @@ impl Miri { cargo.env("RUST_BACKTRACE", "1"); let mut cargo = Command::from(cargo); + let _guard = builder.msg( + Kind::Build, + compiler.stage + 1, + "miri sysroot", + compiler.host, + compiler.host, + ); builder.run(&mut cargo); // # Determine where Miri put its sysroot. @@ -624,6 +621,8 @@ impl Step for Miri { SourceType::InTree, &[], ); + let _guard = builder.msg_sysroot_tool(Kind::Test, compiler.stage, "miri", host, host); + cargo.add_rustc_lib_path(builder, compiler); // miri tests need to know about the stage sysroot @@ -736,7 +735,16 @@ impl Step for CompiletestTest { &[], ); cargo.allow_features("test"); - run_cargo_test(cargo, &[], &[], "compiletest", compiler, host, builder); + run_cargo_test( + cargo, + &[], + &[], + "compiletest", + "compiletest self test", + compiler, + host, + builder, + ); } } @@ -792,13 +800,16 @@ impl Step for Clippy { cargo.env("BLESS", "Gesundheit"); } - if builder.try_run(&mut cargo).is_ok() { + let _guard = builder.msg_sysroot_tool(Kind::Test, compiler.stage, "clippy", host, host); + + #[allow(deprecated)] // Clippy reports errors if it blessed the outputs + if builder.config.try_run(&mut cargo).is_ok() { // The tests succeeded; nothing to do. return; } if !builder.config.cmd.bless() { - crate::detail_exit_macro!(1); + crate::exit!(1); } } } @@ -852,7 +863,7 @@ impl Step for RustdocTheme { util::lld_flag_no_threads(self.compiler.host.contains("windows")), ); } - try_run(builder, &mut cmd); + builder.run_delaying_failure(&mut cmd); } } @@ -867,7 +878,8 @@ impl Step for RustdocJSStd { const ONLY_HOSTS: bool = true; fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { - run.suite_path("tests/rustdoc-js-std") + let default = run.builder.config.nodejs.is_some(); + run.suite_path("tests/rustdoc-js-std").default_condition(default) } fn make_run(run: RunConfig<'_>) { @@ -875,38 +887,42 @@ impl Step for RustdocJSStd { } fn run(self, builder: &Builder<'_>) { - if let Some(ref nodejs) = builder.config.nodejs { - let mut command = Command::new(nodejs); - command - .arg(builder.src.join("src/tools/rustdoc-js/tester.js")) - .arg("--crate-name") - .arg("std") - .arg("--resource-suffix") - .arg(&builder.version) - .arg("--doc-folder") - .arg(builder.doc_out(self.target)) - .arg("--test-folder") - .arg(builder.src.join("tests/rustdoc-js-std")); - for path in &builder.paths { - if let Some(p) = - util::is_valid_test_suite_arg(path, "tests/rustdoc-js-std", builder) - { - if !p.ends_with(".js") { - eprintln!("A non-js file was given: `{}`", path.display()); - panic!("Cannot run rustdoc-js-std tests"); - } - command.arg("--test-file").arg(path); + let nodejs = + builder.config.nodejs.as_ref().expect("need nodejs to run rustdoc-js-std tests"); + let mut command = Command::new(nodejs); + command + .arg(builder.src.join("src/tools/rustdoc-js/tester.js")) + .arg("--crate-name") + .arg("std") + .arg("--resource-suffix") + .arg(&builder.version) + .arg("--doc-folder") + .arg(builder.doc_out(self.target)) + .arg("--test-folder") + .arg(builder.src.join("tests/rustdoc-js-std")); + for path in &builder.paths { + if let Some(p) = util::is_valid_test_suite_arg(path, "tests/rustdoc-js-std", builder) { + if !p.ends_with(".js") { + eprintln!("A non-js file was given: `{}`", path.display()); + panic!("Cannot run rustdoc-js-std tests"); } + command.arg("--test-file").arg(path); } - builder.ensure(crate::doc::Std::new( - builder.top_stage, - self.target, - DocumentationFormat::HTML, - )); - builder.run(&mut command); - } else { - builder.info("No nodejs found, skipping \"tests/rustdoc-js-std\" tests"); } + builder.ensure(crate::doc::Std::new( + builder.top_stage, + self.target, + builder, + DocumentationFormat::HTML, + )); + let _guard = builder.msg( + Kind::Test, + builder.top_stage, + "rustdoc-js-std", + builder.config.build, + self.target, + ); + builder.run(&mut command); } } @@ -922,7 +938,8 @@ impl Step for RustdocJSNotStd { const ONLY_HOSTS: bool = true; fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { - run.suite_path("tests/rustdoc-js") + let default = run.builder.config.nodejs.is_some(); + run.suite_path("tests/rustdoc-js").default_condition(default) } fn make_run(run: RunConfig<'_>) { @@ -931,18 +948,14 @@ impl Step for RustdocJSNotStd { } fn run(self, builder: &Builder<'_>) { - if builder.config.nodejs.is_some() { - builder.ensure(Compiletest { - compiler: self.compiler, - target: self.target, - mode: "js-doc-test", - suite: "rustdoc-js", - path: "tests/rustdoc-js", - compare_mode: None, - }); - } else { - builder.info("No nodejs found, skipping \"tests/rustdoc-js\" tests"); - } + builder.ensure(Compiletest { + compiler: self.compiler, + target: self.target, + mode: "js-doc-test", + suite: "rustdoc-js", + path: "tests/rustdoc-js", + compare_mode: None, + }); } } @@ -1047,6 +1060,13 @@ impl Step for RustdocGUI { } let _time = util::timeit(&builder); + let _guard = builder.msg_sysroot_tool( + Kind::Test, + self.compiler.stage, + "rustdoc-gui", + self.compiler.host, + self.target, + ); crate::render_tests::try_run_tests(builder, &mut cmd, true); } } @@ -1097,13 +1117,13 @@ help: to skip test's attempt to check tidiness, pass `--exclude src/tools/tidy` PATH = inferred_rustfmt_dir.display(), CHAN = builder.config.channel, ); - crate::detail_exit_macro!(1); + crate::exit!(1); } crate::format::format(&builder, !builder.config.cmd.bless(), &[]); } builder.info("tidy check"); - try_run(builder, &mut cmd); + builder.run_delaying_failure(&mut cmd); builder.ensure(ExpandYamlAnchors); @@ -1120,7 +1140,7 @@ help: to skip test's attempt to check tidiness, pass `--exclude src/tools/tidy` eprintln!( "x.py completions were changed; run `x.py run generate-completions` to update them" ); - crate::detail_exit_macro!(1); + crate::exit!(1); } } } @@ -1148,8 +1168,7 @@ impl Step for ExpandYamlAnchors { /// by the user before committing CI changes. fn run(self, builder: &Builder<'_>) { builder.info("Ensuring the YAML anchors in the GitHub Actions config were expanded"); - try_run( - builder, + builder.run_delaying_failure( &mut builder.tool_cmd(Tool::ExpandYamlAnchors).arg("check").arg(&builder.src), ); } @@ -1431,7 +1450,7 @@ help: to test the compiler, use `--stage 1` instead help: to test the standard library, use `--stage 0 library/std` instead note: if you're sure you want to do this, please open an issue as to why. In the meantime, you can override this with `COMPILETEST_FORCE_STAGE0=1`." ); - crate::detail_exit_macro!(1); + crate::exit!(1); } let mut compiler = self.compiler; @@ -1568,6 +1587,8 @@ note: if you're sure you want to do this, please open an issue as to why. In the if let Some(ref nodejs) = builder.config.nodejs { cmd.arg("--nodejs").arg(nodejs); + } else if mode == "js-doc-test" { + panic!("need nodejs to run js-doc-test suite"); } if let Some(ref npm) = builder.config.npm { cmd.arg("--npm").arg(npm); @@ -1889,14 +1910,6 @@ impl Step for BookTest { /// /// This uses the `rustdoc` that sits next to `compiler`. fn run(self, builder: &Builder<'_>) { - let host = self.compiler.host; - let _guard = builder.msg( - Kind::Test, - self.compiler.stage, - &format!("book {}", self.name), - host, - host, - ); // External docs are different from local because: // - Some books need pre-processing by mdbook before being tested. // - They need to save their state to toolstate. @@ -1939,12 +1952,12 @@ impl BookTest { let _guard = builder.msg( Kind::Test, compiler.stage, - format_args!("rustbook {}", self.path.display()), + format_args!("mdbook {}", self.path.display()), compiler.host, compiler.host, ); let _time = util::timeit(&builder); - let toolstate = if try_run(builder, &mut rustbook_cmd) { + let toolstate = if builder.run_delaying_failure(&mut rustbook_cmd) { ToolState::TestPass } else { ToolState::TestFail @@ -1955,8 +1968,12 @@ impl BookTest { /// This runs `rustdoc --test` on all `.md` files in the path. fn run_local_doc(self, builder: &Builder<'_>) { let compiler = self.compiler; + let host = self.compiler.host; - builder.ensure(compile::Std::new(compiler, compiler.host)); + builder.ensure(compile::Std::new(compiler, host)); + + let _guard = + builder.msg(Kind::Test, compiler.stage, &format!("book {}", self.name), host, host); // Do a breadth-first traversal of the `src/doc` directory and just run // tests for all files that end in `*.md` @@ -2102,9 +2119,9 @@ fn markdown_test(builder: &Builder<'_>, compiler: Compiler, markdown: &Path) -> cmd.arg("--test-args").arg(test_args); if builder.config.verbose_tests { - try_run(builder, &mut cmd) + builder.run_delaying_failure(&mut cmd) } else { - try_run_quiet(builder, &mut cmd) + builder.run_quiet_delaying_failure(&mut cmd) } } @@ -2130,7 +2147,7 @@ impl Step for RustcGuide { let src = builder.src.join(relative_path); let mut rustbook_cmd = builder.tool_cmd(Tool::Rustbook); - let toolstate = if try_run(builder, rustbook_cmd.arg("linkcheck").arg(&src)) { + let toolstate = if builder.run_delaying_failure(rustbook_cmd.arg("linkcheck").arg(&src)) { ToolState::TestPass } else { ToolState::TestFail @@ -2181,11 +2198,12 @@ impl Step for CrateLibrustc { /// Given a `cargo test` subcommand, add the appropriate flags and run it. /// /// Returns whether the test succeeded. -fn run_cargo_test( +fn run_cargo_test<'a>( cargo: impl Into<Command>, libtest_args: &[&str], crates: &[Interned<String>], primary_crate: &str, + description: impl Into<Option<&'a str>>, compiler: Compiler, target: TargetSelection, builder: &Builder<'_>, @@ -2193,6 +2211,9 @@ fn run_cargo_test( let mut cargo = prepare_cargo_test(cargo, libtest_args, crates, primary_crate, compiler, target, builder); let _time = util::timeit(&builder); + let _group = description.into().and_then(|what| { + builder.msg_sysroot_tool(Kind::Test, compiler.stage, what, compiler.host, target) + }); #[cfg(feature = "build-metrics")] builder.metrics.begin_test_suite( @@ -2358,14 +2379,16 @@ impl Step for Crate { _ => panic!("can only test libraries"), }; - let _guard = builder.msg( - builder.kind, - compiler.stage, - crate_description(&self.crates), - compiler.host, + run_cargo_test( + cargo, + &[], + &self.crates, + &self.crates[0], + &*crate_description(&self.crates), + compiler, target, + builder, ); - run_cargo_test(cargo, &[], &self.crates, &self.crates[0], compiler, target, builder); } } @@ -2458,18 +2481,12 @@ impl Step for CrateRustdoc { dylib_path.insert(0, PathBuf::from(&*libdir)); cargo.env(dylib_path_var(), env::join_paths(&dylib_path).unwrap()); - let _guard = builder.msg_sysroot_tool( - builder.kind, - compiler.stage, - "rustdoc", - compiler.host, - target, - ); run_cargo_test( cargo, &[], &[INTERNER.intern_str("rustdoc:0.0.0")], "rustdoc", + "rustdoc", compiler, target, builder, @@ -2525,13 +2542,12 @@ impl Step for CrateRustdocJsonTypes { &[] }; - let _guard = - builder.msg(builder.kind, compiler.stage, "rustdoc-json-types", compiler.host, target); run_cargo_test( cargo, libtest_args, &[INTERNER.intern_str("rustdoc-json-types")], "rustdoc-json-types", + "rustdoc-json-types", compiler, target, builder, @@ -2672,6 +2688,10 @@ impl Step for Bootstrap { /// Tests the build system itself. fn run(self, builder: &Builder<'_>) { + let host = builder.config.build; + let compiler = builder.compiler(0, host); + let _guard = builder.msg(Kind::Test, 0, "bootstrap", host, host); + let mut check_bootstrap = Command::new(&builder.python()); check_bootstrap .args(["-m", "unittest", "bootstrap_test.py"]) @@ -2680,10 +2700,8 @@ impl Step for Bootstrap { .current_dir(builder.src.join("src/bootstrap/")); // NOTE: we intentionally don't pass test_args here because the args for unittest and cargo test are mutually incompatible. // Use `python -m unittest` manually if you want to pass arguments. - try_run(builder, &mut check_bootstrap); + builder.run_delaying_failure(&mut check_bootstrap); - let host = builder.config.build; - let compiler = builder.compiler(0, host); let mut cmd = Command::new(&builder.initial_cargo); cmd.arg("test") .current_dir(builder.src.join("src/bootstrap")) @@ -2700,7 +2718,7 @@ impl Step for Bootstrap { } // rustbuild tests are racy on directory creation so just run them one at a time. // Since there's not many this shouldn't be a problem. - run_cargo_test(cmd, &["--test-threads=1"], &[], "bootstrap", compiler, host, builder); + run_cargo_test(cmd, &["--test-threads=1"], &[], "bootstrap", None, compiler, host, builder); } fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { @@ -2751,8 +2769,14 @@ impl Step for TierCheck { cargo.arg("--verbose"); } - builder.info("platform support check"); - try_run(builder, &mut cargo.into()); + let _guard = builder.msg( + Kind::Test, + self.compiler.stage, + "platform support check", + self.compiler.host, + self.compiler.host, + ); + builder.run_delaying_failure(&mut cargo.into()); } } @@ -2799,8 +2823,6 @@ impl Step for RustInstaller { /// Ensure the version placeholder replacement tool builds fn run(self, builder: &Builder<'_>) { - builder.info("test rust-installer"); - let bootstrap_host = builder.config.build; let compiler = builder.compiler(0, bootstrap_host); let cargo = tool::prepare_tool_cargo( @@ -2813,7 +2835,15 @@ impl Step for RustInstaller { SourceType::InTree, &[], ); - run_cargo_test(cargo, &[], &[], "installer", compiler, bootstrap_host, builder); + + let _guard = builder.msg( + Kind::Test, + compiler.stage, + "rust-installer", + bootstrap_host, + bootstrap_host, + ); + run_cargo_test(cargo, &[], &[], "installer", None, compiler, bootstrap_host, builder); // We currently don't support running the test.sh script outside linux(?) environments. // Eventually this should likely migrate to #[test]s in rust-installer proper rather than a @@ -2832,7 +2862,7 @@ impl Step for RustInstaller { cmd.env("CARGO", &builder.initial_cargo); cmd.env("RUSTC", &builder.initial_rustc); cmd.env("TMP_DIR", &tmpdir); - try_run(builder, &mut cmd); + builder.run_delaying_failure(&mut cmd); } fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { diff --git a/src/bootstrap/tool.rs b/src/bootstrap/tool.rs index 915dceae389..725f864b718 100644 --- a/src/bootstrap/tool.rs +++ b/src/bootstrap/tool.rs @@ -34,6 +34,7 @@ struct ToolBuild { } impl Builder<'_> { + #[track_caller] fn msg_tool( &self, mode: Mode, @@ -107,7 +108,8 @@ impl Step for ToolBuild { ); let mut cargo = Command::from(cargo); - let is_expected = builder.try_run(&mut cargo).is_ok(); + #[allow(deprecated)] // we check this in `is_optional_tool` in a second + let is_expected = builder.config.try_run(&mut cargo).is_ok(); builder.save_toolstate( tool, @@ -116,7 +118,7 @@ impl Step for ToolBuild { if !is_expected { if !is_optional_tool { - crate::detail_exit_macro!(1); + crate::exit!(1); } else { None } diff --git a/src/bootstrap/toolstate.rs b/src/bootstrap/toolstate.rs index 9c4d0ea265d..eb65c8bee09 100644 --- a/src/bootstrap/toolstate.rs +++ b/src/bootstrap/toolstate.rs @@ -91,7 +91,7 @@ fn print_error(tool: &str, submodule: &str) { eprintln!("If you do NOT intend to update '{}', please ensure you did not accidentally", tool); eprintln!("change the submodule at '{}'. You may ask your reviewer for the", submodule); eprintln!("proper steps."); - crate::detail_exit_macro!(3); + crate::exit!(3); } fn check_changed_files(toolstates: &HashMap<Box<str>, ToolState>) { @@ -106,7 +106,7 @@ fn check_changed_files(toolstates: &HashMap<Box<str>, ToolState>) { Ok(o) => o, Err(e) => { eprintln!("Failed to get changed files: {:?}", e); - crate::detail_exit_macro!(1); + crate::exit!(1); } }; @@ -177,7 +177,7 @@ impl Step for ToolStateCheck { } if did_error { - crate::detail_exit_macro!(1); + crate::exit!(1); } check_changed_files(&toolstates); @@ -223,7 +223,7 @@ impl Step for ToolStateCheck { } if did_error { - crate::detail_exit_macro!(1); + crate::exit!(1); } if builder.config.channel == "nightly" && env::var_os("TOOLSTATE_PUBLISH").is_some() { @@ -262,6 +262,8 @@ impl Builder<'_> { /// `rust.save-toolstates` in `config.toml`. If unspecified, nothing will be /// done. The file is updated immediately after this function completes. pub fn save_toolstate(&self, tool: &str, state: ToolState) { + use std::io::Write; + // If we're in a dry run setting we don't want to save toolstates as // that means if we e.g. panic down the line it'll look like we tested // everything (but we actually haven't). @@ -286,7 +288,8 @@ impl Builder<'_> { current_toolstates.insert(tool.into(), state); t!(file.seek(SeekFrom::Start(0))); t!(file.set_len(0)); - t!(serde_json::to_writer(file, ¤t_toolstates)); + t!(serde_json::to_writer(&file, ¤t_toolstates)); + t!(writeln!(file)); // make sure this ends in a newline } } } diff --git a/src/bootstrap/util.rs b/src/bootstrap/util.rs index b291584b300..2725813aba3 100644 --- a/src/bootstrap/util.rs +++ b/src/bootstrap/util.rs @@ -153,16 +153,6 @@ pub fn symlink_dir(config: &Config, original: &Path, link: &Path) -> io::Result< } } -/// The CI environment rustbuild is running in. This mainly affects how the logs -/// are printed. -#[derive(Copy, Clone, PartialEq, Eq, Debug)] -pub enum CiEnv { - /// Not a CI environment. - None, - /// The GitHub Actions environment, for Linux (including Docker), Windows and macOS builds. - GitHubActions, -} - pub fn forcing_clang_based_tests() -> bool { if let Some(var) = env::var_os("RUSTBUILD_FORCE_CLANG_BASED_TESTS") { match &var.to_string_lossy().to_lowercase()[..] { @@ -229,7 +219,7 @@ pub fn is_valid_test_suite_arg<'a, P: AsRef<Path>>( pub fn run(cmd: &mut Command, print_cmd_on_fail: bool) { if try_run(cmd, print_cmd_on_fail).is_err() { - crate::detail_exit_macro!(1); + crate::exit!(1); } } @@ -253,7 +243,7 @@ pub fn check_run(cmd: &mut Command, print_cmd_on_fail: bool) -> bool { pub fn run_suppressed(cmd: &mut Command) { if !try_run_suppressed(cmd) { - crate::detail_exit_macro!(1); + crate::exit!(1); } } diff --git a/src/ci/docker/run.sh b/src/ci/docker/run.sh index 4b218d57727..da9d68672c4 100755 --- a/src/ci/docker/run.sh +++ b/src/ci/docker/run.sh @@ -79,7 +79,7 @@ if [ -f "$docker_dir/$image/Dockerfile" ]; then loaded_images=$(/usr/bin/timeout -k 720 600 docker load -i /tmp/rustci_docker_cache \ | sed 's/.* sha/sha/') set -e - echo "Downloaded containers:\n$loaded_images" + printf "Downloaded containers:\n$loaded_images\n" fi dockerfile="$docker_dir/$image/Dockerfile" @@ -89,12 +89,14 @@ if [ -f "$docker_dir/$image/Dockerfile" ]; then else context="$script_dir" fi + echo "::group::Building docker image for $image" retry docker \ build \ --rm \ -t rust-ci \ -f "$dockerfile" \ "$context" + echo "::endgroup::" if [ "$CI" != "" ]; then s3url="s3://$SCCACHE_BUCKET/docker/$cksum" diff --git a/src/ci/run.sh b/src/ci/run.sh index 48fb40d6a6d..da1960fc057 100755 --- a/src/ci/run.sh +++ b/src/ci/run.sh @@ -154,13 +154,13 @@ fi # check for clock drifts. An HTTP URL is used instead of HTTPS since on Azure # Pipelines it happened that the certificates were marked as expired. datecheck() { - echo "== clock drift check ==" + echo "::group::Clock drift check" echo -n " local time: " date echo -n " network time: " curl -fs --head http://ci-caches.rust-lang.org | grep ^Date: \ | sed 's/Date: //g' || true - echo "== end clock drift check ==" + echo "::endgroup::" } datecheck trap datecheck EXIT @@ -177,6 +177,7 @@ retry make prepare # Display the CPU and memory information. This helps us know why the CI timing # is fluctuating. +echo "::group::Display CPU and Memory information" if isMacOS; then system_profiler SPHardwareDataType || true sysctl hw || true @@ -186,6 +187,7 @@ else cat /proc/meminfo || true ncpus=$(grep processor /proc/cpuinfo | wc -l) fi +echo "::endgroup::" if [ ! -z "$SCRIPT" ]; then echo "Executing ${SCRIPT}" @@ -218,4 +220,6 @@ if [ "$RUN_CHECK_WITH_PARALLEL_QUERIES" != "" ]; then CARGO_INCREMENTAL=0 ../x check fi +echo "::group::sccache stats" sccache --show-stats || true +echo "::endgroup::" diff --git a/src/doc/rustc/src/SUMMARY.md b/src/doc/rustc/src/SUMMARY.md index f8af26326a7..537c90e985a 100644 --- a/src/doc/rustc/src/SUMMARY.md +++ b/src/doc/rustc/src/SUMMARY.md @@ -36,6 +36,7 @@ - [m68k-unknown-linux-gnu](platform-support/m68k-unknown-linux-gnu.md) - [mips64-openwrt-linux-musl](platform-support/mips64-openwrt-linux-musl.md) - [mipsel-sony-psx](platform-support/mipsel-sony-psx.md) + - [mipsisa\*r6\*-unknown-linux-gnu\*](platform-support/mips-release-6.md) - [nvptx64-nvidia-cuda](platform-support/nvptx64-nvidia-cuda.md) - [riscv32imac-unknown-xous-elf](platform-support/riscv32imac-unknown-xous-elf.md) - [*-pc-windows-gnullvm](platform-support/pc-windows-gnullvm.md) diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index d2a25e612ec..a2cabb7bb5c 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -277,10 +277,10 @@ target | std | host | notes [`mipsel-sony-psx`](platform-support/mipsel-sony-psx.md) | * | | MIPS (LE) Sony PlayStation 1 (PSX) `mipsel-unknown-linux-uclibc` | ✓ | | MIPS (LE) Linux with uClibc `mipsel-unknown-none` | * | | Bare MIPS (LE) softfloat -`mipsisa32r6-unknown-linux-gnu` | ? | | -`mipsisa32r6el-unknown-linux-gnu` | ? | | -`mipsisa64r6-unknown-linux-gnuabi64` | ? | | -`mipsisa64r6el-unknown-linux-gnuabi64` | ? | | +[`mipsisa32r6-unknown-linux-gnu`](platform-support/mips-release-6.md) | ? | | 32-bit MIPS Release 6 Big Endian +[`mipsisa32r6el-unknown-linux-gnu`](platform-support/mips-release-6.md) | ? | | 32-bit MIPS Release 6 Little Endian +[`mipsisa64r6-unknown-linux-gnuabi64`](platform-support/mips-release-6.md) | ? | | 64-bit MIPS Release 6 Big Endian +[`mipsisa64r6el-unknown-linux-gnuabi64`](platform-support/mips-release-6.md) | ✓ | ✓ | 64-bit MIPS Release 6 Little Endian `msp430-none-elf` | * | | 16-bit MSP430 microcontrollers `powerpc-unknown-linux-gnuspe` | ✓ | | PowerPC SPE Linux `powerpc-unknown-linux-musl` | ? | | @@ -305,7 +305,7 @@ target | std | host | notes `riscv64gc-unknown-freebsd` | | | RISC-V FreeBSD `riscv64gc-unknown-fuchsia` | | | RISC-V Fuchsia `riscv64gc-unknown-linux-musl` | | | RISC-V Linux (kernel 4.20, musl 1.2.0) -[`riscv64gc-unknown-netbsd`](platform-support/netbsd.md) | ✓ | ? | RISC-V NetBSD +[`riscv64gc-unknown-netbsd`](platform-support/netbsd.md) | ✓ | ✓ | RISC-V NetBSD [`riscv64gc-unknown-openbsd`](platform-support/openbsd.md) | ✓ | ✓ | OpenBSD/riscv64 `s390x-unknown-linux-musl` | | | S390x Linux (kernel 3.2, MUSL) `sparc-unknown-linux-gnu` | ✓ | | 32-bit SPARC Linux diff --git a/src/doc/rustc/src/platform-support/mips-release-6.md b/src/doc/rustc/src/platform-support/mips-release-6.md new file mode 100644 index 00000000000..3f1912fc6f9 --- /dev/null +++ b/src/doc/rustc/src/platform-support/mips-release-6.md @@ -0,0 +1,181 @@ +# mipsisa\*r6\*-unknown-linux-gnu\* + +**Tier: 3** + +[MIPS Release 6](https://s3-eu-west-1.amazonaws.com/downloads-mips/documents/MD00083-2B-MIPS64INT-AFP-06.01.pdf), or simply MIPS R6, is the latest iteration of the MIPS instruction set architecture (ISA). + +MIPS R6 is experimental in nature, as there is not yet real hardware. However, Qemu emulation is available and we have two Linux distros maintained for development and evaluation purposes. This documentation describes the Rust support for MIPS R6 targets under `mipsisa*r6*-unknown-linux-gnu*`. + +The target name follow this format: `<machine>-<vendor>-<os><abi_suffix>`, where `<machine>` specifies the CPU family/model, `<vendor>` specifies the vendor and `<os>` the operating system name. The `<abi_suffix>` denotes the base ABI (32/n32/64/o64). + +| ABI suffix | Description | +|------------|------------------------------------| +| abi64 | Uses the 64-bit (64) ABI | +| abin32 | Uses the n32 ABI | +| N/A | Uses the (assumed) 32-bit (32) ABI | + +## Target Maintainers + +- [Xuan Chen](https://github.com/chenx97) <henry.chen@oss.cipunited.com> +- [Walter Ji](https://github.com/709924470) <walter.ji@oss.cipunited.com> +- [Xinhui Yang](https://github.com/Cyanoxygen) <cyan@oss.cipunited.com> +- [Lain Yang](https://github.com/Fearyncess) <lain.yang@oss.cipunited.com> + +## Requirements + +### C/C++ Toolchain + +A GNU toolchain for one of the MIPS R6 target is required. [AOSC OS](https://aosc.io/) provides working native and cross-compiling build environments. You may also supply your own a toolchain consisting of recent versions of GCC and Binutils. + +### Target libraries + +A minimum set of libraries is required to perform dynamic linking: + +- GNU glibc +- OpenSSL +- Zlib +- Linux API Headers + +This set of libraries should be installed to make up minimal target sysroot. + +For AOSC OS, You may install such a sysroot with the following commands: + +```sh +cd /tmp + +# linux+api, glibc, and file system structure are included in the toolchain. +sudo apt install gcc+cross-mips64r6el binutils+cross-mips64r6el + +# Download and extract required libraries. +wget https://repo.aosc.io/debs/pool/stable/main/z/zlib_1.2.13-0_mips64r6el.deb -O zlib.deb +wget https://repo.aosc.io/debs/pool/stable/main/o/openssl_1.1.1q-1_mips64r6el.deb -O openssl.deb + +# Extract them to your desired location. +for i in zlib openssl ; do + sudo dpkg-deb -vx $i.deb /var/ab/cross-root/mips64r6el +done + +# Workaround a possible ld bug when using -Wl,-Bdynamic. +sudo sed -i 's|/usr|=/usr|g' /var/ab/cross-root/mips64r6el/usr/lib/libc.so +``` + +For other distros, you may build them manually. + +## Building + +The following procedure outlines the build process for the MIPS64 R6 target with 64-bit (64) ABI (`mipsisa64r6el-unknown-linux-gnuabi64`). + +### Prerequisite: Disable debuginfo + +A LLVM bug makes rustc crash if debug or debug info generation is enabled. You need to edit `config.toml` to disable this: + +```toml +[rust] +debug = false +debug-info-level = 0 +``` + +### Prerequisite: Enable rustix's libc backend + +The crate `rustix` may try to link itself against MIPS R2 assembly, resulting in linkage error. To avoid this, you may force `rustix` to use its fallback `libc` backend by setting relevant `RUSTFLAGS`: + +```sh +export RUSTFLAGS="--cfg rustix_use_libc" +``` + +This will trigger warnings during build, as `-D warnings` is enabled by default. Disable `-D warnings` by editing `config.toml` to append the following: + +```toml +[rust] +deny-warnings = false +``` + +### Prerequisite: Supplying OpenSSL + +As a Tier 3 target, `openssl_sys` lacks the vendored OpenSSL library for this target. You will need to provide a prebuilt OpenSSL library to link `cargo`. Since we have a pre-configured sysroot, we can point to it directly: + +```sh +export MIPSISA64R6EL_UNKNOWN_LINUX_GNUABI64_OPENSSL_NO_VENDOR=y +export MIPSISA64R6EL_UNKNOWN_LINUX_GNUABI64_OPENSSL_DIR="/var/ab/cross-root/mips64r6el/usr" +``` + +On Debian, you may need to provide library path and include path separately: + +```sh +export MIPSISA64R6EL_UNKNOWN_LINUX_GNUABI64_OPENSSL_NO_VENDOR=y +export MIPSISA64R6EL_UNKNOWN_LINUX_GNUABI64_OPENSSL_LIB_DIR="/usr/lib/mipsisa64r6el-linux-gnuabi64/" +export MIPSISA64R6EL_UNKNOWN_LINUX_GNUABI64_OPENSSL_INCLUDE_DIR="/usr/include" +``` + +### Launching `x.py` + +```toml +[build] +target = ["mipsisa64r6el-unknown-linux-gnuabi64"] +``` + +Make sure that `mipsisa64r6el-unknown-linux-gnuabi64-gcc` is available from your executable search path (`$PATH`). + +Alternatively, you can specify the directories to all necessary toolchain executables in `config.toml`: + +```toml +[target.mipsisa64r6el-unknown-linux-gnuabi64] +# Adjust the paths below to point to your toolchain installation prefix. +cc = "/toolchain_prefix/bin/mipsisa64r6el-unknown-linux-gnuabi64-gcc" +cxx = "/toolchain_prefix/bin/mipsisa64r6el-unknown-linux-gnuabi64-g++" +ar = "/toolchain_prefix/bin/mipsisa64r6el-unknown-linux-gnuabi64-gcc-ar" +ranlib = "/toolchain_prefix/bin/mipsisa64r6el-unknown-linux-gnuabi64-ranlib" +linker = "/toolchain_prefix/bin/mipsisa64r6el-unknown-linux-gnuabi64-gcc" +``` + +Or, you can specify your cross compiler toolchain with an environment variable: + +```sh +export CROSS_COMPILE="/opt/abcross/mips64r6el/bin/mipsisa64r6el-aosc-linux-gnuabi64-" +``` + +Finally, launch the build script: + +```sh +./x.py build +``` + +### Tips + +- Avoid setting `cargo-native-static` to `false`, as this will result in a redundant artifact error while building clippy: + ```text + duplicate artifacts found when compiling a tool, this typically means that something was recompiled because a transitive dependency has different features activated than in a previous build: + + the following dependencies have different features: + syn 2.0.8 (registry+https://github.com/rust-lang/crates.io-index) + `clippy-driver` additionally enabled features {"full"} at ... + `cargo` additionally enabled features {} at ... + + to fix this you will probably want to edit the local src/tools/rustc-workspace-hack/Cargo.toml crate, as that will update the dependency graph to ensure that these crates all share the same feature set + thread 'main' panicked at 'tools should not compile multiple copies of the same crate', tool.rs:250:13 + note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace + ``` + +## Building Rust programs + +To build Rust programs for MIPS R6 targets, for instance, the `mipsisa64r6el-unknown-linux-gnuabi64` target: + +```bash +cargo build --target mipsisa64r6el-unknown-linux-gnuabi64 +``` + +## Testing + +To test a cross-compiled binary on your build system, install the Qemu user emulator that support the MIPS R6 architecture (`qemu-user-mipsel` or `qemu-user-mips64el`). GCC runtime libraries (`libgcc_s`) for the target architecture should be present in target sysroot to run the program. + +```sh +env \ + CARGO_TARGET_MIPSISA64R6EL_UNKNOWN_LINUX_GNUABI64_LINKER="/opt/abcross/mips64r6el/bin/mipsisa64r6el-aosc-linux-gnuabi64-gcc" \ + CARGO_TARGET_MIPSISA64R6EL_UNKNOWN_LINUX_GNUABI64_RUNNER="qemu-mips64el-static -L /var/ab/cross-root/mips64r6el" \ + cargo run --release \ + --target mipsisa64r6el-unknown-linux-gnuabi64 +``` + +## Tips for building Rust programs for MIPS R6 + +- Until we finalize a fix, please make sure the aforementioned workarounds for `rustix` crate and LLVM are always applied. This can be achieved by setting the relevant environment variables, and editing `Cargo.toml` before building. diff --git a/src/doc/style-guide/src/items.md b/src/doc/style-guide/src/items.md index 1e0e60248bf..de31e8a8799 100644 --- a/src/doc/style-guide/src/items.md +++ b/src/doc/style-guide/src/items.md @@ -282,7 +282,7 @@ impl<T: Display, U: Debug> SomeType<T, U> { ... If the generics clause must be formatted across multiple lines, each parameter should have its own block-indented line, there should be newlines after the -opening bracket and before the closing bracket, and the should be a trailing +opening bracket and before the closing bracket, and there should be a trailing comma. ```rust diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs index 92bae551644..68d636b360a 100644 --- a/src/librustdoc/clean/auto_trait.rs +++ b/src/librustdoc/clean/auto_trait.rs @@ -137,7 +137,7 @@ where pub(crate) fn get_auto_trait_impls(&mut self, item_def_id: DefId) -> Vec<Item> { let tcx = self.cx.tcx; let param_env = tcx.param_env(item_def_id); - let ty = tcx.type_of(item_def_id).subst_identity(); + let ty = tcx.type_of(item_def_id).instantiate_identity(); let f = auto_trait::AutoTraitFinder::new(tcx); debug!("get_auto_trait_impls({:?})", ty); diff --git a/src/librustdoc/clean/blanket_impl.rs b/src/librustdoc/clean/blanket_impl.rs index c4ac5466164..f5e02940c82 100644 --- a/src/librustdoc/clean/blanket_impl.rs +++ b/src/librustdoc/clean/blanket_impl.rs @@ -38,12 +38,12 @@ impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> { continue; } let infcx = cx.tcx.infer_ctxt().build(); - let substs = infcx.fresh_substs_for_item(DUMMY_SP, item_def_id); - let impl_ty = ty.subst(infcx.tcx, substs); - let param_env = EarlyBinder::bind(param_env).subst(infcx.tcx, substs); + let args = infcx.fresh_args_for_item(DUMMY_SP, item_def_id); + let impl_ty = ty.instantiate(infcx.tcx, args); + let param_env = EarlyBinder::bind(param_env).instantiate(infcx.tcx, args); - let impl_substs = infcx.fresh_substs_for_item(DUMMY_SP, impl_def_id); - let impl_trait_ref = trait_ref.subst(infcx.tcx, impl_substs); + let impl_args = infcx.fresh_args_for_item(DUMMY_SP, impl_def_id); + let impl_trait_ref = trait_ref.instantiate(infcx.tcx, impl_args); // Require the type the impl is implemented on to match // our type, and ignore the impl if there was a mismatch. @@ -67,7 +67,7 @@ impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> { let predicates = cx .tcx .predicates_of(impl_def_id) - .instantiate(cx.tcx, impl_substs) + .instantiate(cx.tcx, impl_args) .predicates .into_iter() .chain(Some(ty::Binder::dummy(impl_trait_ref).to_predicate(infcx.tcx))); @@ -108,11 +108,11 @@ impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> { // the post-inference `trait_ref`, as it's more accurate. trait_: Some(clean_trait_ref_with_bindings( cx, - ty::Binder::dummy(trait_ref.subst_identity()), + ty::Binder::dummy(trait_ref.instantiate_identity()), ThinVec::new(), )), for_: clean_middle_ty( - ty::Binder::dummy(ty.subst_identity()), + ty::Binder::dummy(ty.instantiate_identity()), cx, None, None, @@ -125,7 +125,7 @@ impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> { .collect::<Vec<_>>(), polarity: ty::ImplPolarity::Positive, kind: ImplKind::Blanket(Box::new(clean_middle_ty( - ty::Binder::dummy(trait_ref.subst_identity().self_ty()), + ty::Binder::dummy(trait_ref.instantiate_identity().self_ty()), cx, None, None, diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index 870cfa93058..a98d466cd81 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -226,7 +226,7 @@ pub(crate) fn build_external_trait(cx: &mut DocContext<'_>, did: DefId) -> clean } fn build_external_function<'tcx>(cx: &mut DocContext<'tcx>, did: DefId) -> Box<clean::Function> { - let sig = cx.tcx.fn_sig(did).subst_identity(); + let sig = cx.tcx.fn_sig(did).instantiate_identity(); let late_bound_regions = sig.bound_vars().into_iter().filter_map(|var| match var { ty::BoundVariableKind::Region(ty::BrNamed(_, name)) if name != kw::UnderscoreLifetime => { @@ -279,7 +279,7 @@ fn build_union(cx: &mut DocContext<'_>, did: DefId) -> clean::Union { fn build_type_alias(cx: &mut DocContext<'_>, did: DefId) -> Box<clean::Typedef> { let predicates = cx.tcx.explicit_predicates_of(did); let type_ = clean_middle_ty( - ty::Binder::dummy(cx.tcx.type_of(did).subst_identity()), + ty::Binder::dummy(cx.tcx.type_of(did).instantiate_identity()), cx, Some(did), None, @@ -391,7 +391,7 @@ pub(crate) fn build_impl( let for_ = match &impl_item { Some(impl_) => clean_ty(impl_.self_ty, cx), None => clean_middle_ty( - ty::Binder::dummy(tcx.type_of(did).subst_identity()), + ty::Binder::dummy(tcx.type_of(did).instantiate_identity()), cx, Some(did), None, @@ -634,7 +634,7 @@ pub(crate) fn print_inlined_const(tcx: TyCtxt<'_>, did: DefId) -> String { fn build_const(cx: &mut DocContext<'_>, def_id: DefId) -> clean::Constant { clean::Constant { type_: clean_middle_ty( - ty::Binder::dummy(cx.tcx.type_of(def_id).subst_identity()), + ty::Binder::dummy(cx.tcx.type_of(def_id).instantiate_identity()), cx, Some(def_id), None, @@ -646,7 +646,7 @@ fn build_const(cx: &mut DocContext<'_>, def_id: DefId) -> clean::Constant { fn build_static(cx: &mut DocContext<'_>, did: DefId, mutable: bool) -> clean::Static { clean::Static { type_: clean_middle_ty( - ty::Binder::dummy(cx.tcx.type_of(did).subst_identity()), + ty::Binder::dummy(cx.tcx.type_of(did).instantiate_identity()), cx, Some(did), None, diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index d26de77a78d..d62c4b707e1 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -24,7 +24,6 @@ use rustc_infer::infer::region_constraints::{Constraint, RegionConstraintData}; use rustc_middle::metadata::Reexport; use rustc_middle::middle::resolve_bound_vars as rbv; use rustc_middle::ty::fold::TypeFolder; -use rustc_middle::ty::InternalSubsts; use rustc_middle::ty::TypeVisitableExt; use rustc_middle::ty::{self, AdtKind, EarlyBinder, Ty, TyCtxt}; use rustc_middle::{bug, span_bug}; @@ -201,7 +200,7 @@ pub(crate) fn clean_trait_ref_with_bindings<'tcx>( } inline::record_extern_fqn(cx, trait_ref.def_id(), kind); let path = - external_path(cx, trait_ref.def_id(), true, bindings, trait_ref.map_bound(|tr| tr.substs)); + external_path(cx, trait_ref.def_id(), true, bindings, trait_ref.map_bound(|tr| tr.args)); debug!(?trait_ref); @@ -239,7 +238,7 @@ fn clean_lifetime<'tcx>(lifetime: &hir::Lifetime, cx: &mut DocContext<'tcx>) -> | rbv::ResolvedArg::Free(_, node_id), ) = def { - if let Some(lt) = cx.substs.get(&node_id).and_then(|p| p.as_lt()).cloned() { + if let Some(lt) = cx.args.get(&node_id).and_then(|p| p.as_lt()).cloned() { return lt; } } @@ -250,7 +249,7 @@ pub(crate) fn clean_const<'tcx>(constant: &hir::ConstArg, cx: &mut DocContext<'t let def_id = cx.tcx.hir().body_owner_def_id(constant.value.body).to_def_id(); Constant { type_: clean_middle_ty( - ty::Binder::dummy(cx.tcx.type_of(def_id).subst_identity()), + ty::Binder::dummy(cx.tcx.type_of(def_id).instantiate_identity()), cx, Some(def_id), None, @@ -442,7 +441,7 @@ fn clean_projection<'tcx>( let bounds = cx .tcx .explicit_item_bounds(ty.skip_binder().def_id) - .subst_iter_copied(cx.tcx, ty.skip_binder().substs) + .arg_iter_copied(cx.tcx, ty.skip_binder().args) .map(|(pred, _)| pred) .collect::<Vec<_>>(); return clean_middle_opaque_bounds(cx, bounds); @@ -481,9 +480,9 @@ fn projection_to_path_segment<'tcx>( PathSegment { name: item.name, args: GenericArgs::AngleBracketed { - args: substs_to_args( + args: ty_args_to_args( cx, - ty.map_bound(|ty| &ty.substs[generics.parent_count..]), + ty.map_bound(|ty| &ty.args[generics.parent_count..]), false, None, ) @@ -504,7 +503,7 @@ fn clean_generic_param_def<'tcx>( ty::GenericParamDefKind::Type { has_default, synthetic, .. } => { let default = if has_default { Some(clean_middle_ty( - ty::Binder::dummy(cx.tcx.type_of(def.def_id).subst_identity()), + ty::Binder::dummy(cx.tcx.type_of(def.def_id).instantiate_identity()), cx, Some(def.def_id), None, @@ -538,7 +537,7 @@ fn clean_generic_param_def<'tcx>( )), default: match has_default { true => Some(Box::new( - cx.tcx.const_param_default(def.def_id).subst_identity().to_string(), + cx.tcx.const_param_default(def.def_id).instantiate_identity().to_string(), )), false => None, }, @@ -1243,7 +1242,7 @@ pub(crate) fn clean_middle_assoc_item<'tcx>( let kind = match assoc_item.kind { ty::AssocKind::Const => { let ty = clean_middle_ty( - ty::Binder::dummy(tcx.type_of(assoc_item.def_id).subst_identity()), + ty::Binder::dummy(tcx.type_of(assoc_item.def_id).instantiate_identity()), cx, Some(assoc_item.def_id), None, @@ -1260,7 +1259,7 @@ pub(crate) fn clean_middle_assoc_item<'tcx>( } } ty::AssocKind::Fn => { - let sig = tcx.fn_sig(assoc_item.def_id).subst_identity(); + let sig = tcx.fn_sig(assoc_item.def_id).instantiate_identity(); let late_bound_regions = sig.bound_vars().into_iter().filter_map(|var| match var { ty::BoundVariableKind::Region(ty::BrNamed(_, name)) @@ -1283,7 +1282,9 @@ pub(crate) fn clean_middle_assoc_item<'tcx>( if assoc_item.fn_has_self_parameter { let self_ty = match assoc_item.container { - ty::ImplContainer => tcx.type_of(assoc_item.container_id(tcx)).subst_identity(), + ty::ImplContainer => { + tcx.type_of(assoc_item.container_id(tcx)).instantiate_identity() + } ty::TraitContainer => tcx.types.self_param, }; let self_arg_ty = sig.input(0).skip_binder(); @@ -1339,7 +1340,7 @@ pub(crate) fn clean_middle_assoc_item<'tcx>( let mut predicates = tcx.explicit_predicates_of(assoc_item.def_id).predicates; if let ty::TraitContainer = assoc_item.container { let bounds = - tcx.explicit_item_bounds(assoc_item.def_id).subst_identity_iter_copied(); + tcx.explicit_item_bounds(assoc_item.def_id).instantiate_identity_iter_copied(); predicates = tcx.arena.alloc_from_iter(bounds.chain(predicates.iter().copied())); } let mut generics = clean_ty_generics( @@ -1442,7 +1443,9 @@ pub(crate) fn clean_middle_assoc_item<'tcx>( AssocTypeItem( Box::new(Typedef { type_: clean_middle_ty( - ty::Binder::dummy(tcx.type_of(assoc_item.def_id).subst_identity()), + ty::Binder::dummy( + tcx.type_of(assoc_item.def_id).instantiate_identity(), + ), cx, Some(assoc_item.def_id), None, @@ -1459,7 +1462,9 @@ pub(crate) fn clean_middle_assoc_item<'tcx>( AssocTypeItem( Box::new(Typedef { type_: clean_middle_ty( - ty::Binder::dummy(tcx.type_of(assoc_item.def_id).subst_identity()), + ty::Binder::dummy( + tcx.type_of(assoc_item.def_id).instantiate_identity(), + ), cx, Some(assoc_item.def_id), None, @@ -1485,7 +1490,7 @@ fn clean_qpath<'tcx>(hir_ty: &hir::Ty<'tcx>, cx: &mut DocContext<'tcx>) -> Type match qpath { hir::QPath::Resolved(None, path) => { if let Res::Def(DefKind::TyParam, did) = path.res { - if let Some(new_ty) = cx.substs.get(&did).and_then(|p| p.as_ty()).cloned() { + if let Some(new_ty) = cx.args.get(&did).and_then(|p| p.as_ty()).cloned() { return new_ty; } if let Some(bounds) = cx.impl_trait_bounds.remove(&did.into()) { @@ -1576,7 +1581,7 @@ fn maybe_expand_private_type_alias<'tcx>( let hir::ItemKind::TyAlias(ty, generics) = alias else { return None }; let provided_params = &path.segments.last().expect("segments were empty"); - let mut substs = DefIdMap::default(); + let mut args = DefIdMap::default(); let generic_args = provided_params.args(); let mut indices: hir::GenericParamCount = Default::default(); @@ -1600,7 +1605,7 @@ fn maybe_expand_private_type_alias<'tcx>( } else { Lifetime::elided() }; - substs.insert(param.def_id.to_def_id(), SubstParam::Lifetime(cleaned)); + args.insert(param.def_id.to_def_id(), SubstParam::Lifetime(cleaned)); } indices.lifetimes += 1; } @@ -1617,10 +1622,9 @@ fn maybe_expand_private_type_alias<'tcx>( _ => None, }); if let Some(ty) = type_ { - substs.insert(param.def_id.to_def_id(), SubstParam::Type(clean_ty(ty, cx))); + args.insert(param.def_id.to_def_id(), SubstParam::Type(clean_ty(ty, cx))); } else if let Some(default) = *default { - substs - .insert(param.def_id.to_def_id(), SubstParam::Type(clean_ty(default, cx))); + args.insert(param.def_id.to_def_id(), SubstParam::Type(clean_ty(default, cx))); } indices.types += 1; } @@ -1637,7 +1641,7 @@ fn maybe_expand_private_type_alias<'tcx>( _ => None, }); if let Some(ct) = const_ { - substs.insert( + args.insert( param.def_id.to_def_id(), SubstParam::Constant(clean_const(ct, cx)), ); @@ -1648,7 +1652,7 @@ fn maybe_expand_private_type_alias<'tcx>( } } - Some(cx.enter_alias(substs, def_id.to_def_id(), |cx| clean_ty(ty, cx))) + Some(cx.enter_alias(args, def_id.to_def_id(), |cx| clean_ty(ty, cx))) } pub(crate) fn clean_ty<'tcx>(ty: &hir::Ty<'tcx>, cx: &mut DocContext<'tcx>) -> Type { @@ -1817,14 +1821,14 @@ fn can_elide_trait_object_lifetime_bound<'tcx>( #[derive(Debug)] pub(crate) enum ContainerTy<'tcx> { Ref(ty::Region<'tcx>), - Regular { ty: DefId, substs: ty::Binder<'tcx, &'tcx [ty::GenericArg<'tcx>]>, arg: usize }, + Regular { ty: DefId, args: ty::Binder<'tcx, &'tcx [ty::GenericArg<'tcx>]>, arg: usize }, } impl<'tcx> ContainerTy<'tcx> { fn object_lifetime_default(self, tcx: TyCtxt<'tcx>) -> ObjectLifetimeDefault<'tcx> { match self { Self::Ref(region) => ObjectLifetimeDefault::Arg(region), - Self::Regular { ty: container, substs, arg: index } => { + Self::Regular { ty: container, args, arg: index } => { let (DefKind::Struct | DefKind::Union | DefKind::Enum @@ -1843,7 +1847,7 @@ impl<'tcx> ContainerTy<'tcx> { match default { rbv::ObjectLifetimeDefault::Param(lifetime) => { let index = generics.param_def_id_to_index[&lifetime]; - let arg = substs.skip_binder()[index as usize].expect_region(); + let arg = args.skip_binder()[index as usize].expect_region(); ObjectLifetimeDefault::Arg(arg) } rbv::ObjectLifetimeDefault::Empty => ObjectLifetimeDefault::Empty, @@ -1909,7 +1913,7 @@ pub(crate) fn clean_middle_ty<'tcx>( abi: sig.abi(), })) } - ty::Adt(def, substs) => { + ty::Adt(def, args) => { let did = def.did(); let kind = match def.adt_kind() { AdtKind::Struct => ItemType::Struct, @@ -1917,7 +1921,7 @@ pub(crate) fn clean_middle_ty<'tcx>( AdtKind::Enum => ItemType::Enum, }; inline::record_extern_fqn(cx, did, kind); - let path = external_path(cx, did, false, ThinVec::new(), bound_ty.rebind(substs)); + let path = external_path(cx, did, false, ThinVec::new(), bound_ty.rebind(args)); Type::Path { path } } ty::Foreign(did) => { @@ -1927,7 +1931,7 @@ pub(crate) fn clean_middle_ty<'tcx>( did, false, ThinVec::new(), - ty::Binder::dummy(InternalSubsts::empty()), + ty::Binder::dummy(ty::GenericArgs::empty()), ); Type::Path { path } } @@ -1940,10 +1944,10 @@ pub(crate) fn clean_middle_ty<'tcx>( .principal_def_id() .or_else(|| dids.next()) .unwrap_or_else(|| panic!("found trait object `{bound_ty:?}` with no traits?")); - let substs = match obj.principal() { - Some(principal) => principal.map_bound(|p| p.substs), - // marker traits have no substs. - _ => ty::Binder::dummy(InternalSubsts::empty()), + let args = match obj.principal() { + Some(principal) => principal.map_bound(|p| p.args), + // marker traits have no args. + _ => ty::Binder::dummy(ty::GenericArgs::empty()), }; inline::record_extern_fqn(cx, did, ItemType::Trait); @@ -1952,7 +1956,7 @@ pub(crate) fn clean_middle_ty<'tcx>( let mut bounds = dids .map(|did| { - let empty = ty::Binder::dummy(InternalSubsts::empty()); + let empty = ty::Binder::dummy(ty::GenericArgs::empty()); let path = external_path(cx, did, false, ThinVec::new(), empty); inline::record_extern_fqn(cx, did, ItemType::Trait); PolyTrait { trait_: path, generic_params: Vec::new() } @@ -1966,7 +1970,7 @@ pub(crate) fn clean_middle_ty<'tcx>( pb.map_bound(|pb| { pb // HACK(compiler-errors): Doesn't actually matter what self - // type we put here, because we're only using the GAT's substs. + // type we put here, because we're only using the GAT's args. .with_self_ty(cx.tcx, cx.tcx.types.self_param) .projection_ty }), @@ -1992,7 +1996,7 @@ pub(crate) fn clean_middle_ty<'tcx>( .collect(); let late_bound_regions = late_bound_regions.into_iter().collect(); - let path = external_path(cx, did, false, bindings, substs); + let path = external_path(cx, did, false, bindings, args); bounds.insert(0, PolyTrait { trait_: path, generic_params: late_bound_regions }); DynTrait(bounds, lifetime) @@ -2013,9 +2017,9 @@ pub(crate) fn clean_middle_ty<'tcx>( assoc: PathSegment { name: cx.tcx.associated_item(alias_ty.skip_binder().def_id).name, args: GenericArgs::AngleBracketed { - args: substs_to_args( + args: ty_args_to_args( cx, - alias_ty.map_bound(|ty| ty.substs.as_slice()), + alias_ty.map_bound(|ty| ty.args.as_slice()), true, None, ) @@ -2038,11 +2042,11 @@ pub(crate) fn clean_middle_ty<'tcx>( data.def_id, false, ThinVec::new(), - bound_ty.rebind(data.substs), + bound_ty.rebind(data.args), ); Type::Path { path } } else { - let ty = cx.tcx.type_of(data.def_id).subst(cx.tcx, data.substs); + let ty = cx.tcx.type_of(data.def_id).instantiate(cx.tcx, data.args); clean_middle_ty(bound_ty.rebind(ty), cx, None, None) } } @@ -2055,11 +2059,10 @@ pub(crate) fn clean_middle_ty<'tcx>( } } - ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs, .. }) => { + ty::Alias(ty::Opaque, ty::AliasTy { def_id, args, .. }) => { // If it's already in the same alias, don't get an infinite loop. if cx.current_type_aliases.contains_key(&def_id) { - let path = - external_path(cx, def_id, false, ThinVec::new(), bound_ty.rebind(substs)); + let path = external_path(cx, def_id, false, ThinVec::new(), bound_ty.rebind(args)); Type::Path { path } } else { *cx.current_type_aliases.entry(def_id).or_insert(0) += 1; @@ -2068,7 +2071,7 @@ pub(crate) fn clean_middle_ty<'tcx>( let bounds = cx .tcx .explicit_item_bounds(def_id) - .subst_iter_copied(cx.tcx, substs) + .arg_iter_copied(cx.tcx, args) .map(|(bound, _)| bound) .collect::<Vec<_>>(); let ty = clean_middle_opaque_bounds(cx, bounds); @@ -2161,7 +2164,7 @@ pub(crate) fn clean_middle_field<'tcx>(field: &ty::FieldDef, cx: &mut DocContext field.did, field.name, clean_middle_ty( - ty::Binder::dummy(cx.tcx.type_of(field.did).subst_identity()), + ty::Binder::dummy(cx.tcx.type_of(field.did).instantiate_identity()), cx, Some(field.did), None, @@ -2562,7 +2565,7 @@ fn clean_impl<'tcx>( let type_alias = for_.def_id(&cx.cache).and_then(|alias_def_id: DefId| match tcx.def_kind(alias_def_id) { DefKind::TyAlias => Some(clean_middle_ty( - ty::Binder::dummy(tcx.type_of(def_id).subst_identity()), + ty::Binder::dummy(tcx.type_of(def_id).instantiate_identity()), cx, Some(def_id.to_def_id()), None, diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index eccc881d6b1..cfe62407fd3 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -1221,7 +1221,7 @@ pub(crate) enum GenericBound { impl GenericBound { pub(crate) fn maybe_sized(cx: &mut DocContext<'_>) -> GenericBound { let did = cx.tcx.require_lang_item(LangItem::Sized, None); - let empty = ty::Binder::dummy(ty::InternalSubsts::empty()); + let empty = ty::Binder::dummy(ty::GenericArgs::empty()); let path = external_path(cx, did, false, ThinVec::new(), empty); inline::record_extern_fqn(cx, did, ItemType::Trait); GenericBound::TraitBound( diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs index d6a970fba39..df9da9e7c7f 100644 --- a/src/librustdoc/clean/utils.rs +++ b/src/librustdoc/clean/utils.rs @@ -16,8 +16,7 @@ use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::{DefId, LOCAL_CRATE}; use rustc_middle::mir; use rustc_middle::mir::interpret::ConstValue; -use rustc_middle::ty::subst::{GenericArgKind, SubstsRef}; -use rustc_middle::ty::{self, TyCtxt}; +use rustc_middle::ty::{self, GenericArgKind, GenericArgsRef, TyCtxt}; use rustc_span::symbol::{kw, sym, Symbol}; use std::fmt::Write as _; use std::mem; @@ -71,20 +70,16 @@ pub(crate) fn krate(cx: &mut DocContext<'_>) -> Crate { Crate { module, external_traits: cx.external_traits.clone() } } -pub(crate) fn substs_to_args<'tcx>( +pub(crate) fn ty_args_to_args<'tcx>( cx: &mut DocContext<'tcx>, - substs: ty::Binder<'tcx, &'tcx [ty::subst::GenericArg<'tcx>]>, + args: ty::Binder<'tcx, &'tcx [ty::GenericArg<'tcx>]>, mut skip_first: bool, container: Option<DefId>, ) -> Vec<GenericArg> { let mut ret_val = - Vec::with_capacity(substs.skip_binder().len().saturating_sub(if skip_first { - 1 - } else { - 0 - })); + Vec::with_capacity(args.skip_binder().len().saturating_sub(if skip_first { 1 } else { 0 })); - ret_val.extend(substs.iter().enumerate().filter_map(|(index, kind)| { + ret_val.extend(args.iter().enumerate().filter_map(|(index, kind)| { match kind.skip_binder().unpack() { GenericArgKind::Lifetime(lt) => { Some(GenericArg::Lifetime(clean_middle_region(lt).unwrap_or(Lifetime::elided()))) @@ -99,7 +94,7 @@ pub(crate) fn substs_to_args<'tcx>( None, container.map(|container| crate::clean::ContainerTy::Regular { ty: container, - substs, + args, arg: index, }), ))), @@ -116,12 +111,12 @@ fn external_generic_args<'tcx>( did: DefId, has_self: bool, bindings: ThinVec<TypeBinding>, - substs: ty::Binder<'tcx, SubstsRef<'tcx>>, + ty_args: ty::Binder<'tcx, GenericArgsRef<'tcx>>, ) -> GenericArgs { - let args = substs_to_args(cx, substs.map_bound(|substs| &substs[..]), has_self, Some(did)); + let args = ty_args_to_args(cx, ty_args.map_bound(|args| &args[..]), has_self, Some(did)); if cx.tcx.fn_trait_kind_from_def_id(did).is_some() { - let ty = substs + let ty = ty_args .iter() .nth(if has_self { 1 } else { 0 }) .unwrap() @@ -149,7 +144,7 @@ pub(super) fn external_path<'tcx>( did: DefId, has_self: bool, bindings: ThinVec<TypeBinding>, - substs: ty::Binder<'tcx, SubstsRef<'tcx>>, + args: ty::Binder<'tcx, GenericArgsRef<'tcx>>, ) -> Path { let def_kind = cx.tcx.def_kind(did); let name = cx.tcx.item_name(did); @@ -157,7 +152,7 @@ pub(super) fn external_path<'tcx>( res: Res::Def(def_kind, did), segments: thin_vec![PathSegment { name, - args: external_generic_args(cx, did, has_self, bindings, substs), + args: external_generic_args(cx, did, has_self, bindings, args), }], } } @@ -252,7 +247,7 @@ pub(crate) fn name_from_pat(p: &hir::Pat<'_>) -> Symbol { pub(crate) fn print_const(cx: &DocContext<'_>, n: ty::Const<'_>) -> String { match n.kind() { - ty::ConstKind::Unevaluated(ty::UnevaluatedConst { def, substs: _ }) => { + ty::ConstKind::Unevaluated(ty::UnevaluatedConst { def, args: _ }) => { let s = if let Some(def) = def.as_local() { print_const_expr(cx.tcx, cx.tcx.hir().body_owned_by(def)) } else { @@ -277,7 +272,7 @@ pub(crate) fn print_evaluated_const( underscores_and_type: bool, ) -> Option<String> { tcx.const_eval_poly(def_id).ok().and_then(|val| { - let ty = tcx.type_of(def_id).subst_identity(); + let ty = tcx.type_of(def_id).instantiate_identity(); match (val, ty.kind()) { (_, &ty::Ref(..)) => None, (ConstValue::Scalar(_), &ty::Adt(_, _)) => None, diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 9687b8b1887..1bd40aea823 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -45,7 +45,7 @@ pub(crate) struct DocContext<'tcx> { // The current set of parameter substitutions, // for expanding type aliases at the HIR level: /// Table `DefId` of type, lifetime, or const parameter -> substituted type, lifetime, or const - pub(crate) substs: DefIdMap<clean::SubstParam>, + pub(crate) args: DefIdMap<clean::SubstParam>, pub(crate) current_type_aliases: DefIdMap<usize>, /// Table synthetic type parameter for `impl Trait` in argument position -> bounds pub(crate) impl_trait_bounds: FxHashMap<ImplTraitParam, Vec<clean::GenericBound>>, @@ -85,17 +85,17 @@ impl<'tcx> DocContext<'tcx> { /// the substitutions for a type alias' RHS. pub(crate) fn enter_alias<F, R>( &mut self, - substs: DefIdMap<clean::SubstParam>, + args: DefIdMap<clean::SubstParam>, def_id: DefId, f: F, ) -> R where F: FnOnce(&mut Self) -> R, { - let old_substs = mem::replace(&mut self.substs, substs); + let old_args = mem::replace(&mut self.args, args); *self.current_type_aliases.entry(def_id).or_insert(0) += 1; let r = f(self); - self.substs = old_substs; + self.args = old_args; if let Some(count) = self.current_type_aliases.get_mut(&def_id) { *count -= 1; if *count == 0 { @@ -340,7 +340,7 @@ pub(crate) fn run_global_ctxt( param_env: ParamEnv::empty(), external_traits: Default::default(), active_extern_traits: Default::default(), - substs: Default::default(), + args: Default::default(), current_type_aliases: Default::default(), impl_trait_bounds: Default::default(), generated_synthetics: Default::default(), diff --git a/src/librustdoc/formats/cache.rs b/src/librustdoc/formats/cache.rs index dac762e9ff9..6b48936cc59 100644 --- a/src/librustdoc/formats/cache.rs +++ b/src/librustdoc/formats/cache.rs @@ -473,7 +473,7 @@ impl<'a, 'tcx> DocFolder for CacheBuilder<'a, 'tcx> { | clean::BorrowedRef { type_: box clean::Type::Path { ref path }, .. } => { dids.insert(path.def_id()); if let Some(generics) = path.generics() && - let ty::Adt(adt, _) = self.tcx.type_of(path.def_id()).subst_identity().kind() && + let ty::Adt(adt, _) = self.tcx.type_of(path.def_id()).instantiate_identity().kind() && adt.is_fundamental() { for ty in generics { if let Some(did) = ty.def_id(self.cache) { diff --git a/src/librustdoc/html/highlight.rs b/src/librustdoc/html/highlight.rs index 0aee79a6947..a99ac0f4e05 100644 --- a/src/librustdoc/html/highlight.rs +++ b/src/librustdoc/html/highlight.rs @@ -986,6 +986,11 @@ fn string_without_closing_tag<T: Display>( ) .ok() .map(|(url, _, _)| url), + LinkFromSrc::Doc(def_id) => { + format::href_with_root_path(*def_id, context, Some(&href_context.root_path)) + .ok() + .map(|(doc_link, _, _)| doc_link) + } } }) { diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index 8a1ce9fb135..575ce6aa99a 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -1821,9 +1821,9 @@ fn render_rightside( ); if let Some(l) = src_href { if has_stability { - write!(rightside, " · <a class=\"srclink\" href=\"{}\">source</a>", l) + write!(rightside, " · <a class=\"src\" href=\"{}\">source</a>", l) } else { - write!(rightside, "<a class=\"srclink rightside\" href=\"{}\">source</a>", l) + write!(rightside, "<a class=\"src rightside\" href=\"{}\">source</a>", l) } } if has_stability && has_src_ref { diff --git a/src/librustdoc/html/render/span_map.rs b/src/librustdoc/html/render/span_map.rs index eb9262f472b..ac587bf6008 100644 --- a/src/librustdoc/html/render/span_map.rs +++ b/src/librustdoc/html/render/span_map.rs @@ -1,11 +1,11 @@ -use crate::clean::{self, PrimitiveType}; +use crate::clean::{self, rustc_span, PrimitiveType}; use crate::html::sources; use rustc_data_structures::fx::FxHashMap; use rustc_hir::def::{DefKind, Res}; -use rustc_hir::def_id::DefId; +use rustc_hir::def_id::{DefId, LOCAL_CRATE}; use rustc_hir::intravisit::{self, Visitor}; -use rustc_hir::{ExprKind, HirId, Mod, Node}; +use rustc_hir::{ExprKind, HirId, Item, ItemKind, Mod, Node}; use rustc_middle::hir::nested_filter; use rustc_middle::ty::TyCtxt; use rustc_span::hygiene::MacroKind; @@ -25,6 +25,7 @@ pub(crate) enum LinkFromSrc { Local(clean::Span), External(DefId), Primitive(PrimitiveType), + Doc(DefId), } /// This function will do at most two things: @@ -65,24 +66,43 @@ struct SpanMapVisitor<'tcx> { impl<'tcx> SpanMapVisitor<'tcx> { /// This function is where we handle `hir::Path` elements and add them into the "span map". fn handle_path(&mut self, path: &rustc_hir::Path<'_>) { - let info = match path.res { + match path.res { // FIXME: For now, we handle `DefKind` if it's not a `DefKind::TyParam`. // Would be nice to support them too alongside the other `DefKind` // (such as primitive types!). - Res::Def(kind, def_id) if kind != DefKind::TyParam => Some(def_id), - Res::Local(_) => None, + Res::Def(kind, def_id) if kind != DefKind::TyParam => { + let link = if def_id.as_local().is_some() { + LinkFromSrc::Local(rustc_span(def_id, self.tcx)) + } else { + LinkFromSrc::External(def_id) + }; + self.matches.insert(path.span, link); + } + Res::Local(_) => { + if let Some(span) = self.tcx.hir().res_span(path.res) { + self.matches.insert(path.span, LinkFromSrc::Local(clean::Span::new(span))); + } + } Res::PrimTy(p) => { // FIXME: Doesn't handle "path-like" primitives like arrays or tuples. self.matches.insert(path.span, LinkFromSrc::Primitive(PrimitiveType::from(p))); - return; } - Res::Err => return, - _ => return, - }; - if let Some(span) = self.tcx.hir().res_span(path.res) { - self.matches.insert(path.span, LinkFromSrc::Local(clean::Span::new(span))); - } else if let Some(def_id) = info { - self.matches.insert(path.span, LinkFromSrc::External(def_id)); + Res::Err => {} + _ => {} + } + } + + /// Used to generate links on items' definition to go to their documentation page. + pub(crate) fn extract_info_from_hir_id(&mut self, hir_id: HirId) { + if let Some(Node::Item(item)) = self.tcx.hir().find(hir_id) { + if let Some(span) = self.tcx.def_ident_span(item.owner_id) { + let cspan = clean::Span::new(span); + // If the span isn't from the current crate, we ignore it. + if cspan.inner().is_dummy() || cspan.cnum(self.tcx.sess) != LOCAL_CRATE { + return; + } + self.matches.insert(span, LinkFromSrc::Doc(item.owner_id.to_def_id())); + } } } @@ -117,10 +137,13 @@ impl<'tcx> SpanMapVisitor<'tcx> { _ => return true, }; let link_from_src = match data.macro_def_id { - Some(macro_def_id) if macro_def_id.is_local() => { - LinkFromSrc::Local(clean::Span::new(data.def_site)) + Some(macro_def_id) => { + if macro_def_id.is_local() { + LinkFromSrc::Local(clean::Span::new(data.def_site)) + } else { + LinkFromSrc::External(macro_def_id) + } } - Some(macro_def_id) => LinkFromSrc::External(macro_def_id), None => return true, }; let new_span = data.call_site; @@ -160,6 +183,9 @@ impl<'tcx> Visitor<'tcx> for SpanMapVisitor<'tcx> { LinkFromSrc::Local(clean::Span::new(m.spans.inner_span)), ); } + } else { + // If it's a "mod foo {}", we want to look to its documentation page. + self.extract_info_from_hir_id(id); } intravisit::walk_mod(self, m, id); } @@ -176,13 +202,12 @@ impl<'tcx> Visitor<'tcx> for SpanMapVisitor<'tcx> { .tcx .typeck_body(hir.maybe_body_owned_by(body_id).expect("a body which isn't a body")); if let Some(def_id) = typeck_results.type_dependent_def_id(expr.hir_id) { - self.matches.insert( - segment.ident.span, - match hir.span_if_local(def_id) { - Some(span) => LinkFromSrc::Local(clean::Span::new(span)), - None => LinkFromSrc::External(def_id), - }, - ); + let link = if def_id.as_local().is_some() { + LinkFromSrc::Local(rustc_span(def_id, self.tcx)) + } else { + LinkFromSrc::External(def_id) + }; + self.matches.insert(segment.ident.span, link); } } else if self.handle_macro(expr.span) { // We don't want to go deeper into the macro. @@ -190,4 +215,28 @@ impl<'tcx> Visitor<'tcx> for SpanMapVisitor<'tcx> { } intravisit::walk_expr(self, expr); } + + fn visit_item(&mut self, item: &'tcx Item<'tcx>) { + match item.kind { + ItemKind::Static(_, _, _) + | ItemKind::Const(_, _) + | ItemKind::Fn(_, _, _) + | ItemKind::Macro(_, _) + | ItemKind::TyAlias(_, _) + | ItemKind::Enum(_, _) + | ItemKind::Struct(_, _) + | ItemKind::Union(_, _) + | ItemKind::Trait(_, _, _, _, _) + | ItemKind::TraitAlias(_, _) => self.extract_info_from_hir_id(item.hir_id()), + ItemKind::Impl(_) + | ItemKind::Use(_, _) + | ItemKind::ExternCrate(_) + | ItemKind::ForeignMod { .. } + | ItemKind::GlobalAsm(_) + | ItemKind::OpaqueTy(_) + // We already have "visit_mod" above so no need to check it here. + | ItemKind::Mod(_) => {} + } + intravisit::walk_item(self, item); + } } diff --git a/src/librustdoc/html/render/type_layout.rs b/src/librustdoc/html/render/type_layout.rs index 0bc32ea5a20..377daaeb9d4 100644 --- a/src/librustdoc/html/render/type_layout.rs +++ b/src/librustdoc/html/render/type_layout.rs @@ -39,7 +39,7 @@ pub(crate) fn document_type_layout<'a, 'cx: 'a>( let tcx = cx.tcx(); let param_env = tcx.param_env(ty_def_id); - let ty = tcx.type_of(ty_def_id).subst_identity(); + let ty = tcx.type_of(ty_def_id).instantiate_identity(); let type_layout = tcx.layout_of(param_env.and(ty)); let variants = diff --git a/src/librustdoc/html/render/write_shared.rs b/src/librustdoc/html/render/write_shared.rs index 54749e9a317..3f41765a5af 100644 --- a/src/librustdoc/html/render/write_shared.rs +++ b/src/librustdoc/html/render/write_shared.rs @@ -270,7 +270,7 @@ pub(super) fn write_shared( hierarchy.add_path(source); } let hierarchy = Rc::try_unwrap(hierarchy).unwrap(); - let dst = cx.dst.join(&format!("source-files{}.js", cx.shared.resource_suffix)); + let dst = cx.dst.join(&format!("src-files{}.js", cx.shared.resource_suffix)); let make_sources = || { let (mut all_sources, _krates) = try_err!(collect_json(&dst, krate.name(cx.tcx()).as_str()), &dst); @@ -286,12 +286,12 @@ pub(super) fn write_shared( .replace("\\\"", "\\\\\"") )); all_sources.sort(); - let mut v = String::from("var sourcesIndex = JSON.parse('{\\\n"); + let mut v = String::from("var srcIndex = JSON.parse('{\\\n"); v.push_str(&all_sources.join(",\\\n")); - v.push_str("\\\n}');\ncreateSourceSidebar();\n"); + v.push_str("\\\n}');\ncreateSrcSidebar();\n"); Ok(v.into_bytes()) }; - write_invocation_specific("source-files.js", &make_sources)?; + write_invocation_specific("src-files.js", &make_sources)?; } // Update the search index and crate list. diff --git a/src/librustdoc/html/sources.rs b/src/librustdoc/html/sources.rs index a26fa374912..3e3fc8a0e72 100644 --- a/src/librustdoc/html/sources.rs +++ b/src/librustdoc/html/sources.rs @@ -227,7 +227,7 @@ impl SourceCollector<'_, '_> { let desc = format!("Source of the Rust file `{}`.", filename.prefer_remapped()); let page = layout::Page { title: &title, - css_class: "source", + css_class: "src", root_path: &root_path, static_root_path: shared.static_root_path.as_deref(), description: &desc, diff --git a/src/librustdoc/html/static/css/noscript.css b/src/librustdoc/html/static/css/noscript.css index 54e8b6561f3..93aa11a5852 100644 --- a/src/librustdoc/html/static/css/noscript.css +++ b/src/librustdoc/html/static/css/noscript.css @@ -19,7 +19,7 @@ nav.sub { display: none; } -.source .sidebar { +.src .sidebar { display: none; } diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css index b7f455259ef..9209915895a 100644 --- a/src/librustdoc/html/static/css/rustdoc.css +++ b/src/librustdoc/html/static/css/rustdoc.css @@ -194,7 +194,7 @@ h1, h2, h3, h4, h5, h6, .item-name > a, .out-of-band, span.since, -a.srclink, +a.src, #help-button > a, summary.hideme, .scraped-example-list, @@ -206,7 +206,7 @@ ul.all-items { #toggle-all-docs, a.anchor, .small-section-header a, -#source-sidebar a, +#src-sidebar a, .rust a, .sidebar h2 a, .sidebar h3 a, @@ -315,7 +315,7 @@ main { min-width: 0; /* avoid growing beyond the size limit */ } -.source main { +.src main { padding: 15px; } @@ -350,10 +350,10 @@ pre.item-decl { contain: initial; } -.source .content pre { +.src .content pre { padding: 20px; } -.rustdoc.source .example-wrap pre.src-line-numbers { +.rustdoc.src .example-wrap pre.src-line-numbers { padding: 20px 0 20px 4px; } @@ -392,7 +392,7 @@ img { left: 0; } -.rustdoc.source .sidebar { +.rustdoc.src .sidebar { flex-basis: 50px; border-right: 1px solid; overflow-x: hidden; @@ -402,7 +402,7 @@ img { } .sidebar, .mobile-topbar, .sidebar-menu-toggle, -#src-sidebar-toggle, #source-sidebar { +#src-sidebar-toggle, #src-sidebar { background-color: var(--sidebar-background-color); } @@ -410,16 +410,16 @@ img { background-color: var(--sidebar-background-color-hover); } -.source .sidebar > *:not(#src-sidebar-toggle) { +.src .sidebar > *:not(#src-sidebar-toggle) { visibility: hidden; } -.source-sidebar-expanded .source .sidebar { +.src-sidebar-expanded .src .sidebar { overflow-y: auto; flex-basis: 300px; } -.source-sidebar-expanded .source .sidebar > *:not(#src-sidebar-toggle) { +.src-sidebar-expanded .src .sidebar > *:not(#src-sidebar-toggle) { visibility: visible; } @@ -544,7 +544,7 @@ ul.block, .block li { flex-grow: 1; } -.rustdoc:not(.source) .example-wrap pre { +.rustdoc:not(.src) .example-wrap pre { overflow: auto hidden; } @@ -619,7 +619,7 @@ ul.block, .block li { } .docblock code, .docblock-short code, -pre, .rustdoc.source .example-wrap { +pre, .rustdoc.src .example-wrap { background-color: var(--code-block-background-color); } @@ -676,7 +676,7 @@ nav.sub { height: 34px; flex-grow: 1; } -.source nav.sub { +.src nav.sub { margin: 0 0 15px 0; } @@ -1074,7 +1074,7 @@ pre.rust .doccomment { color: var(--code-highlight-doc-comment-color); } -.rustdoc.source .example-wrap pre.rust a { +.rustdoc.src .example-wrap pre.rust a { background: var(--codeblock-link-background); } @@ -1301,22 +1301,22 @@ a.tooltip:hover::after { align-items: stretch; z-index: 10; } -#source-sidebar { +#src-sidebar { width: 100%; overflow: auto; } -#source-sidebar > .title { +#src-sidebar > .title { font-size: 1.5rem; text-align: center; border-bottom: 1px solid var(--border-color); margin-bottom: 6px; } -#source-sidebar div.files > a:hover, details.dir-entry summary:hover, -#source-sidebar div.files > a:focus, details.dir-entry summary:focus { - background-color: var(--source-sidebar-background-hover); +#src-sidebar div.files > a:hover, details.dir-entry summary:hover, +#src-sidebar div.files > a:focus, details.dir-entry summary:focus { + background-color: var(--src-sidebar-background-hover); } -#source-sidebar div.files > a.selected { - background-color: var(--source-sidebar-background-selected); +#src-sidebar div.files > a.selected { + background-color: var(--src-sidebar-background-selected); } #src-sidebar-toggle > button { font-size: inherit; @@ -1562,7 +1562,7 @@ However, it's not needed with smaller screen width because the doc/code block is /* WARNING: RUSTDOC_MOBILE_BREAKPOINT MEDIA QUERY If you update this line, then you also need to update the line with the same warning -in source-script.js +in src-script.js */ @media (max-width: 700px) { /* When linking to an item with an `id` (for instance, by clicking a link in the sidebar, @@ -1619,8 +1619,8 @@ in source-script.js /* The source view uses a different design for the sidebar toggle, and doesn't have a topbar, so don't bump down the main content or the sidebar. */ - .source main, - .rustdoc.source .sidebar { + .src main, + .rustdoc.src .sidebar { top: 0; padding: 0; height: 100vh; @@ -1628,8 +1628,8 @@ in source-script.js } .sidebar.shown, - .source-sidebar-expanded .source .sidebar, - .rustdoc:not(.source) .sidebar:focus-within { + .src-sidebar-expanded .src .sidebar, + .rustdoc:not(.src) .sidebar:focus-within { left: 0; } @@ -1709,7 +1709,7 @@ in source-script.js border-left: 0; } - .source-sidebar-expanded #src-sidebar-toggle { + .src-sidebar-expanded #src-sidebar-toggle { left: unset; top: unset; width: unset; @@ -1749,7 +1749,7 @@ in source-script.js display: inline; } - .source-sidebar-expanded .source .sidebar { + .src-sidebar-expanded .src .sidebar { max-width: 100vw; width: 100vw; } @@ -1769,7 +1769,7 @@ in source-script.js margin-left: 34px; } - .source nav.sub { + .src nav.sub { margin: 0; padding: var(--nav-sub-mobile-padding); } @@ -1792,7 +1792,7 @@ in source-script.js } @media print { - nav.sidebar, nav.sub, .out-of-band, a.srclink, #copy-path, + nav.sidebar, nav.sub, .out-of-band, a.src, #copy-path, details.toggle[open] > summary::before, details.toggle > summary::before, details.toggle.top-doc > summary { display: none; diff --git a/src/librustdoc/html/static/css/themes/ayu.css b/src/librustdoc/html/static/css/themes/ayu.css index 7145baad256..d8dae51eb1b 100644 --- a/src/librustdoc/html/static/css/themes/ayu.css +++ b/src/librustdoc/html/static/css/themes/ayu.css @@ -89,8 +89,8 @@ Original by Dempfi (https://github.com/dempfi/ayu) --crate-search-div-hover-filter: invert(98%) sepia(12%) saturate(81%) hue-rotate(343deg) brightness(113%) contrast(76%); --crate-search-hover-border: #e0e0e0; - --source-sidebar-background-selected: #14191f; - --source-sidebar-background-hover: #14191f; + --src-sidebar-background-selected: #14191f; + --src-sidebar-background-hover: #14191f; --table-alt-row-background-color: #191f26; --codeblock-link-background: #333; --scrape-example-toggle-line-background: #999; @@ -107,7 +107,7 @@ Original by Dempfi (https://github.com/dempfi/ayu) h1, h2, h3, h4, h1 a, .sidebar h2 a, .sidebar h3 a, -#source-sidebar > .title { +#src-sidebar > .title { color: #fff; } h4 { @@ -124,15 +124,15 @@ h4 { .docblock pre > code, pre, pre > code, .item-info code, -.rustdoc.source .example-wrap { +.rustdoc.src .example-wrap { color: #e6e1cf; } .sidebar .current, .sidebar a:hover, -#source-sidebar div.files > a:hover, details.dir-entry summary:hover, -#source-sidebar div.files > a:focus, details.dir-entry summary:focus, -#source-sidebar div.files > a.selected { +#src-sidebar div.files > a:hover, details.dir-entry summary:hover, +#src-sidebar div.files > a:focus, details.dir-entry summary:focus, +#src-sidebar div.files > a.selected { color: #ffb44c; } diff --git a/src/librustdoc/html/static/css/themes/dark.css b/src/librustdoc/html/static/css/themes/dark.css index 3c1186a5649..b653f61d536 100644 --- a/src/librustdoc/html/static/css/themes/dark.css +++ b/src/librustdoc/html/static/css/themes/dark.css @@ -84,8 +84,8 @@ --crate-search-div-hover-filter: invert(69%) sepia(60%) saturate(6613%) hue-rotate(184deg) brightness(100%) contrast(91%); --crate-search-hover-border: #2196f3; - --source-sidebar-background-selected: #333; - --source-sidebar-background-hover: #444; + --src-sidebar-background-selected: #333; + --src-sidebar-background-hover: #444; --table-alt-row-background-color: #2A2A2A; --codeblock-link-background: #333; --scrape-example-toggle-line-background: #999; diff --git a/src/librustdoc/html/static/css/themes/light.css b/src/librustdoc/html/static/css/themes/light.css index f8c287137de..6be25fc0544 100644 --- a/src/librustdoc/html/static/css/themes/light.css +++ b/src/librustdoc/html/static/css/themes/light.css @@ -81,8 +81,8 @@ --crate-search-div-hover-filter: invert(44%) sepia(18%) saturate(23%) hue-rotate(317deg) brightness(96%) contrast(93%); --crate-search-hover-border: #717171; - --source-sidebar-background-selected: #fff; - --source-sidebar-background-hover: #e0e0e0; + --src-sidebar-background-selected: #fff; + --src-sidebar-background-hover: #e0e0e0; --table-alt-row-background-color: #F5F5F5; --codeblock-link-background: #eee; --scrape-example-toggle-line-background: #ccc; diff --git a/src/librustdoc/html/static/js/source-script.js b/src/librustdoc/html/static/js/src-script.js index 6eb99136040..679c2341f02 100644 --- a/src/librustdoc/html/static/js/source-script.js +++ b/src/librustdoc/html/static/js/src-script.js @@ -1,5 +1,5 @@ // From rust: -/* global sourcesIndex */ +/* global srcIndex */ // Local js definitions: /* global addClass, getCurrentValue, onEachLazy, removeClass, browserSupportsHistoryApi */ @@ -74,11 +74,11 @@ function createDirEntry(elem, parent, fullPath, hasFoundFile) { function toggleSidebar() { const child = this.parentNode.children[0]; if (child.innerText === ">") { - addClass(document.documentElement, "source-sidebar-expanded"); + addClass(document.documentElement, "src-sidebar-expanded"); child.innerText = "<"; updateLocalStorage("source-sidebar-show", "true"); } else { - removeClass(document.documentElement, "source-sidebar-expanded"); + removeClass(document.documentElement, "src-sidebar-expanded"); child.innerText = ">"; updateLocalStorage("source-sidebar-show", "false"); } @@ -101,16 +101,16 @@ function createSidebarToggle() { return sidebarToggle; } -// This function is called from "source-files.js", generated in `html/render/write_shared.rs`. +// This function is called from "src-files.js", generated in `html/render/write_shared.rs`. // eslint-disable-next-line no-unused-vars -function createSourceSidebar() { +function createSrcSidebar() { const container = document.querySelector("nav.sidebar"); const sidebarToggle = createSidebarToggle(); container.insertBefore(sidebarToggle, container.firstChild); const sidebar = document.createElement("div"); - sidebar.id = "source-sidebar"; + sidebar.id = "src-sidebar"; let hasFoundFile = false; @@ -118,9 +118,9 @@ function createSourceSidebar() { title.className = "title"; title.innerText = "Files"; sidebar.appendChild(title); - Object.keys(sourcesIndex).forEach(key => { - sourcesIndex[key][NAME_OFFSET] = key; - hasFoundFile = createDirEntry(sourcesIndex[key], sidebar, "", hasFoundFile); + Object.keys(srcIndex).forEach(key => { + srcIndex[key][NAME_OFFSET] = key; + hasFoundFile = createDirEntry(srcIndex[key], sidebar, "", hasFoundFile); }); container.appendChild(sidebar); @@ -133,7 +133,7 @@ function createSourceSidebar() { const lineNumbersRegex = /^#?(\d+)(?:-(\d+))?$/; -function highlightSourceLines(match) { +function highlightSrcLines(match) { if (typeof match === "undefined") { match = window.location.hash.match(lineNumbersRegex); } @@ -172,7 +172,7 @@ function highlightSourceLines(match) { } } -const handleSourceHighlight = (function() { +const handleSrcHighlight = (function() { let prev_line_id = 0; const set_fragment = name => { @@ -180,7 +180,7 @@ const handleSourceHighlight = (function() { y = window.scrollY; if (browserSupportsHistoryApi()) { history.replaceState(null, null, "#" + name); - highlightSourceLines(); + highlightSrcLines(); } else { location.replace("#" + name); } @@ -221,15 +221,15 @@ const handleSourceHighlight = (function() { window.addEventListener("hashchange", () => { const match = window.location.hash.match(lineNumbersRegex); if (match) { - return highlightSourceLines(match); + return highlightSrcLines(match); } }); onEachLazy(document.getElementsByClassName("src-line-numbers"), el => { - el.addEventListener("click", handleSourceHighlight); + el.addEventListener("click", handleSrcHighlight); }); -highlightSourceLines(); +highlightSrcLines(); -window.createSourceSidebar = createSourceSidebar; +window.createSrcSidebar = createSrcSidebar; })(); diff --git a/src/librustdoc/html/static/js/storage.js b/src/librustdoc/html/static/js/storage.js index 71961f6f2a9..af3ca42a6c0 100644 --- a/src/librustdoc/html/static/js/storage.js +++ b/src/librustdoc/html/static/js/storage.js @@ -185,7 +185,7 @@ updateTheme(); if (getSettingValue("source-sidebar-show") === "true") { // At this point in page load, `document.body` is not available yet. // Set a class on the `<html>` element instead. - addClass(document.documentElement, "source-sidebar-expanded"); + addClass(document.documentElement, "src-sidebar-expanded"); } // If we navigate away (for example to a settings page), and then use the back or diff --git a/src/librustdoc/html/static_files.rs b/src/librustdoc/html/static_files.rs index 767b974cc91..5d2e4b073c1 100644 --- a/src/librustdoc/html/static_files.rs +++ b/src/librustdoc/html/static_files.rs @@ -97,7 +97,7 @@ static_files! { main_js => "static/js/main.js", search_js => "static/js/search.js", settings_js => "static/js/settings.js", - source_script_js => "static/js/source-script.js", + src_script_js => "static/js/src-script.js", storage_js => "static/js/storage.js", scrape_examples_js => "static/js/scrape-examples.js", wheel_svg => "static/images/wheel.svg", diff --git a/src/librustdoc/html/templates/page.html b/src/librustdoc/html/templates/page.html index d4ec9c34b6f..60ccfe4da44 100644 --- a/src/librustdoc/html/templates/page.html +++ b/src/librustdoc/html/templates/page.html @@ -42,9 +42,9 @@ <script src="{{static_root_path|safe}}{{files.storage_js}}"></script> {# #} {% if page.css_class.contains("crate") %} <script defer src="{{page.root_path|safe}}crates{{page.resource_suffix}}.js"></script> {# #} - {% else if page.css_class == "source" %} - <script defer src="{{static_root_path|safe}}{{files.source_script_js}}"></script> {# #} - <script defer src="{{page.root_path|safe}}source-files{{page.resource_suffix}}.js"></script> {# #} + {% else if page.css_class == "src" %} + <script defer src="{{static_root_path|safe}}{{files.src_script_js}}"></script> {# #} + <script defer src="{{page.root_path|safe}}src-files{{page.resource_suffix}}.js"></script> {# #} {% else if !page.css_class.contains("mod") %} <script defer src="sidebar-items{{page.resource_suffix}}.js"></script> {# #} {% endif %} @@ -85,7 +85,7 @@ </div> {# #} <![endif]--> {# #} {{ layout.external_html.before_content|safe }} - {% if page.css_class != "source" %} + {% if page.css_class != "src" %} <nav class="mobile-topbar"> {# #} <button class="sidebar-menu-toggle">☰</button> {# #} <a class="logo-container" href="{{page.root_path|safe}}{{krate_with_trailing_slash|safe}}index.html"> {# #} @@ -99,7 +99,7 @@ </nav> {# #} {% endif %} <nav class="sidebar"> {# #} - {% if page.css_class != "source" %} + {% if page.css_class != "src" %} <a class="logo-container" href="{{page.root_path|safe}}{{krate_with_trailing_slash|safe}}index.html"> {# #} {% if !layout.logo.is_empty() %} <img src="{{layout.logo}}" alt="logo"> {# #} @@ -111,9 +111,9 @@ {{ sidebar|safe }} </nav> {# #} <main> {# #} - {% if page.css_class != "source" %}<div class="width-limiter">{% endif %} + {% if page.css_class != "src" %}<div class="width-limiter">{% endif %} <nav class="sub"> {# #} - {% if page.css_class == "source" %} + {% if page.css_class == "src" %} <a class="sub-logo-container" href="{{page.root_path|safe}}{{krate_with_trailing_slash|safe}}index.html"> {# #} {% if !layout.logo.is_empty() %} <img src="{{layout.logo}}" alt="logo"> {# #} @@ -144,7 +144,7 @@ </form> {# #} </nav> {# #} <section id="main-content" class="content">{{ content|safe }}</section> {# #} - {% if page.css_class != "source" %}</div>{% endif %} + {% if page.css_class != "src" %}</div>{% endif %} </main> {# #} {{ layout.external_html.after_content|safe }} </body> {# #} diff --git a/src/librustdoc/html/templates/print_item.html b/src/librustdoc/html/templates/print_item.html index 68a295ae095..1d215c26968 100644 --- a/src/librustdoc/html/templates/print_item.html +++ b/src/librustdoc/html/templates/print_item.html @@ -18,7 +18,7 @@ {% endif %} {% match src_href %} {% when Some with (href) %} - <a class="srclink" href="{{href|safe}}">source</a> · {#+ #} + <a class="src" href="{{href|safe}}">source</a> · {#+ #} {% else %} {% endmatch %} <button id="toggle-all-docs" title="collapse all docs"> {# #} diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index f28deae791a..36d087a7d5b 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -744,9 +744,6 @@ fn main_args(handler: &mut EarlyErrorHandler, at_args: &[String]) -> MainResult } }; - // Set parallel mode before error handler creation, which will create `Lock`s. - interface::set_thread_safe_mode(&options.unstable_opts); - let diag = core::new_handler( options.error_format, None, diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 6df2b973551..91f3729bfa2 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -298,7 +298,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> { let ty_res = self.resolve_path(&path, TypeNS, item_id, module_id).ok_or_else(no_res)?; match ty_res { - Res::Def(DefKind::Enum, did) => match tcx.type_of(did).subst_identity().kind() { + Res::Def(DefKind::Enum, did) => match tcx.type_of(did).instantiate_identity().kind() { ty::Adt(def, _) if def.is_enum() => { if let Some(variant) = def.variants().iter().find(|v| v.name == variant_name) && let Some(field) = variant.fields.iter().find(|f| f.name == variant_field_name) { @@ -493,7 +493,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> { /// This is used for resolving type aliases. fn def_id_to_res(&self, ty_id: DefId) -> Option<Res> { use PrimitiveType::*; - Some(match *self.cx.tcx.type_of(ty_id).subst_identity().kind() { + Some(match *self.cx.tcx.type_of(ty_id).instantiate_identity().kind() { ty::Bool => Res::Primitive(Bool), ty::Char => Res::Primitive(Char), ty::Int(ity) => Res::Primitive(ity.into()), @@ -601,7 +601,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> { debug!("looking for associated item named {} for item {:?}", item_name, did); // Checks if item_name is a variant of the `SomeItem` enum if ns == TypeNS && def_kind == DefKind::Enum { - match tcx.type_of(did).subst_identity().kind() { + match tcx.type_of(did).instantiate_identity().kind() { ty::Adt(adt_def, _) => { for variant in adt_def.variants() { if variant.name == item_name { @@ -635,7 +635,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> { // To handle that properly resolve() would have to support // something like [`ambi_fn`](<SomeStruct as SomeTrait>::ambi_fn) assoc_items = resolve_associated_trait_item( - tcx.type_of(did).subst_identity(), + tcx.type_of(did).instantiate_identity(), module_id, item_name, ns, @@ -671,7 +671,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> { // they also look like associated items (`module::Type::Variant`), // because they are real Rust syntax (unlike the intra-doc links // field syntax) and are handled by the compiler's resolver. - let def = match tcx.type_of(did).subst_identity().kind() { + let def = match tcx.type_of(did).instantiate_identity().kind() { ty::Adt(def, _) if !def.is_enum() => def, _ => return Vec::new(), }; @@ -1810,7 +1810,7 @@ fn resolution_failure( Res::Primitive(_) => None, }; let is_struct_variant = |did| { - if let ty::Adt(def, _) = tcx.type_of(did).subst_identity().kind() + if let ty::Adt(def, _) = tcx.type_of(did).instantiate_identity().kind() && def.is_enum() && let Some(variant) = def.variants().iter().find(|v| v.name == res.name(tcx)) { // ctor is `None` if variant is a struct diff --git a/src/librustdoc/passes/collect_trait_impls.rs b/src/librustdoc/passes/collect_trait_impls.rs index fbf827cce09..ff89d4e0887 100644 --- a/src/librustdoc/passes/collect_trait_impls.rs +++ b/src/librustdoc/passes/collect_trait_impls.rs @@ -103,11 +103,11 @@ pub(crate) fn collect_trait_impls(mut krate: Crate, cx: &mut DocContext<'_>) -> // nothing to do with the inherent impl. // // Rustdoc currently uses these `impl` block as a source of - // the `Ty`, as well as the `ParamEnv`, `SubstsRef`, and + // the `Ty`, as well as the `ParamEnv`, `GenericArgsRef`, and // `Generics`. To avoid relying on the `impl` block, these // things would need to be created from wholecloth, in a // form that is valid for use in type inference. - let ty = tcx.type_of(def_id).subst_identity(); + let ty = tcx.type_of(def_id).instantiate_identity(); match ty.kind() { ty::Slice(ty) | ty::Ref(_, ty, _) diff --git a/src/librustdoc/scrape_examples.rs b/src/librustdoc/scrape_examples.rs index d2fa7769bbd..647d8358840 100644 --- a/src/librustdoc/scrape_examples.rs +++ b/src/librustdoc/scrape_examples.rs @@ -169,7 +169,7 @@ where }; let ident_span = path.ident.span; - (tcx.type_of(def_id).subst_identity(), call_span, ident_span) + (tcx.type_of(def_id).instantiate_identity(), call_span, ident_span) } _ => { return; diff --git a/src/tools/build_helper/src/ci.rs b/src/tools/build_helper/src/ci.rs index 893195b69c2..b70ea5ec113 100644 --- a/src/tools/build_helper/src/ci.rs +++ b/src/tools/build_helper/src/ci.rs @@ -36,15 +36,25 @@ impl CiEnv { } pub mod gha { + use std::sync::atomic::{AtomicBool, Ordering}; + + static GROUP_ACTIVE: AtomicBool = AtomicBool::new(false); + /// All github actions log messages from this call to the Drop of the return value /// will be grouped and hidden by default in logs. Note that nesting these does /// not really work. + #[track_caller] pub fn group(name: impl std::fmt::Display) -> Group { if std::env::var_os("GITHUB_ACTIONS").is_some() { eprintln!("::group::{name}"); } else { eprintln!("{name}") } + // https://github.com/actions/toolkit/issues/1001 + assert!( + !GROUP_ACTIVE.swap(true, Ordering::Relaxed), + "nested groups are not supported by GHA!" + ); Group(()) } @@ -57,6 +67,10 @@ pub mod gha { if std::env::var_os("GITHUB_ACTIONS").is_some() { eprintln!("::endgroup::"); } + assert!( + GROUP_ACTIVE.swap(false, Ordering::Relaxed), + "group dropped but no group active!" + ); } } } diff --git a/src/tools/build_helper/src/util.rs b/src/tools/build_helper/src/util.rs index 11b8a228b8a..5801a8648f2 100644 --- a/src/tools/build_helper/src/util.rs +++ b/src/tools/build_helper/src/util.rs @@ -1,10 +1,12 @@ use std::process::Command; /// Invokes `build_helper::util::detail_exit` with `cfg!(test)` +/// +/// This is a macro instead of a function so that it uses `cfg(test)` in the *calling* crate, not in build helper. #[macro_export] -macro_rules! detail_exit_macro { +macro_rules! exit { ($code:expr) => { - build_helper::util::detail_exit($code, cfg!(test)); + $crate::util::detail_exit($code, cfg!(test)); }; } diff --git a/src/tools/clippy/clippy_lints/src/assertions_on_result_states.rs b/src/tools/clippy/clippy_lints/src/assertions_on_result_states.rs index f6d6c23bb6e..2980c9d6db3 100644 --- a/src/tools/clippy/clippy_lints/src/assertions_on_result_states.rs +++ b/src/tools/clippy/clippy_lints/src/assertions_on_result_states.rs @@ -47,7 +47,7 @@ impl<'tcx> LateLintPass<'tcx> for AssertionsOnResultStates { && let result_type_with_refs = cx.typeck_results().expr_ty(recv) && let result_type = result_type_with_refs.peel_refs() && is_type_diagnostic_item(cx, result_type, sym::Result) - && let ty::Adt(_, substs) = result_type.kind() + && let ty::Adt(_, args) = result_type.kind() { if !is_copy(cx, result_type) { if result_type_with_refs != result_type { @@ -61,7 +61,7 @@ impl<'tcx> LateLintPass<'tcx> for AssertionsOnResultStates { let semicolon = if is_expr_final_block_expr(cx.tcx, e) {";"} else {""}; let mut app = Applicability::MachineApplicable; match method_segment.ident.as_str() { - "is_ok" if type_suitable_to_unwrap(cx, substs.type_at(1)) => { + "is_ok" if type_suitable_to_unwrap(cx, args.type_at(1)) => { span_lint_and_sugg( cx, ASSERTIONS_ON_RESULT_STATES, @@ -75,7 +75,7 @@ impl<'tcx> LateLintPass<'tcx> for AssertionsOnResultStates { app, ); } - "is_err" if type_suitable_to_unwrap(cx, substs.type_at(0)) => { + "is_err" if type_suitable_to_unwrap(cx, args.type_at(0)) => { span_lint_and_sugg( cx, ASSERTIONS_ON_RESULT_STATES, diff --git a/src/tools/clippy/clippy_lints/src/bool_assert_comparison.rs b/src/tools/clippy/clippy_lints/src/bool_assert_comparison.rs index e8775b08144..d984fddc57a 100644 --- a/src/tools/clippy/clippy_lints/src/bool_assert_comparison.rs +++ b/src/tools/clippy/clippy_lints/src/bool_assert_comparison.rs @@ -61,7 +61,7 @@ fn is_impl_not_trait_with_bool_out<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) - ) }) .map_or(false, |assoc_item| { - let proj = Ty::new_projection(cx.tcx,assoc_item.def_id, cx.tcx.mk_substs_trait(ty, [])); + let proj = Ty::new_projection(cx.tcx,assoc_item.def_id, cx.tcx.mk_args_trait(ty, [])); let nty = cx.tcx.normalize_erasing_regions(cx.param_env, proj); nty.is_bool() diff --git a/src/tools/clippy/clippy_lints/src/casts/as_ptr_cast_mut.rs b/src/tools/clippy/clippy_lints/src/casts/as_ptr_cast_mut.rs index 1633ffd589c..fa1550a0ef9 100644 --- a/src/tools/clippy/clippy_lints/src/casts/as_ptr_cast_mut.rs +++ b/src/tools/clippy/clippy_lints/src/casts/as_ptr_cast_mut.rs @@ -17,7 +17,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, cast_expr: &Expr<'_>, && let ExprKind::MethodCall(method_name, receiver, [], _) = cast_expr.peel_blocks().kind && method_name.ident.name == rustc_span::sym::as_ptr && let Some(as_ptr_did) = cx.typeck_results().type_dependent_def_id(cast_expr.peel_blocks().hir_id) - && let as_ptr_sig = cx.tcx.fn_sig(as_ptr_did).subst_identity() + && let as_ptr_sig = cx.tcx.fn_sig(as_ptr_did).instantiate_identity() && let Some(first_param_ty) = as_ptr_sig.skip_binder().inputs().iter().next() && let ty::Ref(_, _, Mutability::Not) = first_param_ty.kind() && let Some(recv) = snippet_opt(cx, receiver.span) diff --git a/src/tools/clippy/clippy_lints/src/casts/cast_ptr_alignment.rs b/src/tools/clippy/clippy_lints/src/casts/cast_ptr_alignment.rs index 6c8ee296c75..5bf467efa0f 100644 --- a/src/tools/clippy/clippy_lints/src/casts/cast_ptr_alignment.rs +++ b/src/tools/clippy/clippy_lints/src/casts/cast_ptr_alignment.rs @@ -66,7 +66,7 @@ fn is_used_as_unaligned(cx: &LateContext<'_>, e: &Expr<'_>) -> bool { if matches!(name.ident.as_str(), "read_unaligned" | "write_unaligned") && let Some(def_id) = cx.typeck_results().type_dependent_def_id(parent.hir_id) && let Some(def_id) = cx.tcx.impl_of_method(def_id) - && cx.tcx.type_of(def_id).subst_identity().is_unsafe_ptr() + && cx.tcx.type_of(def_id).instantiate_identity().is_unsafe_ptr() { true } else { diff --git a/src/tools/clippy/clippy_lints/src/copy_iterator.rs b/src/tools/clippy/clippy_lints/src/copy_iterator.rs index 0fc11523298..5d04ad0112d 100644 --- a/src/tools/clippy/clippy_lints/src/copy_iterator.rs +++ b/src/tools/clippy/clippy_lints/src/copy_iterator.rs @@ -43,7 +43,7 @@ impl<'tcx> LateLintPass<'tcx> for CopyIterator { of_trait: Some(ref trait_ref), .. }) = item.kind; - let ty = cx.tcx.type_of(item.owner_id).subst_identity(); + let ty = cx.tcx.type_of(item.owner_id).instantiate_identity(); if is_copy(cx, ty); if let Some(trait_id) = trait_ref.trait_def_id(); if cx.tcx.is_diagnostic_item(sym::Iterator, trait_id); diff --git a/src/tools/clippy/clippy_lints/src/default.rs b/src/tools/clippy/clippy_lints/src/default.rs index 80c22742ba4..763ad0264ad 100644 --- a/src/tools/clippy/clippy_lints/src/default.rs +++ b/src/tools/clippy/clippy_lints/src/default.rs @@ -150,7 +150,7 @@ impl<'tcx> LateLintPass<'tcx> for Default { .fields .iter() .all(|field| { - is_copy(cx, cx.tcx.type_of(field.did).subst_identity()) + is_copy(cx, cx.tcx.type_of(field.did).instantiate_identity()) }); if !has_drop(cx, binding_type) || all_fields_are_copy; then { @@ -219,11 +219,11 @@ impl<'tcx> LateLintPass<'tcx> for Default { // give correct suggestion if generics are involved (see #6944) let binding_type = if_chain! { - if let ty::Adt(adt_def, substs) = binding_type.kind(); - if !substs.is_empty(); + if let ty::Adt(adt_def, args) = binding_type.kind(); + if !args.is_empty(); then { let adt_def_ty_name = cx.tcx.item_name(adt_def.did()); - let generic_args = substs.iter().collect::<Vec<_>>(); + let generic_args = args.iter().collect::<Vec<_>>(); let tys_str = generic_args .iter() .map(ToString::to_string) diff --git a/src/tools/clippy/clippy_lints/src/default_numeric_fallback.rs b/src/tools/clippy/clippy_lints/src/default_numeric_fallback.rs index e53a9877b20..9217edcef07 100644 --- a/src/tools/clippy/clippy_lints/src/default_numeric_fallback.rs +++ b/src/tools/clippy/clippy_lints/src/default_numeric_fallback.rs @@ -141,7 +141,7 @@ impl<'a, 'tcx> Visitor<'tcx> for NumericFallbackVisitor<'a, 'tcx> { ExprKind::MethodCall(_, receiver, args, _) => { if let Some(def_id) = self.cx.typeck_results().type_dependent_def_id(expr.hir_id) { - let fn_sig = self.cx.tcx.fn_sig(def_id).subst_identity().skip_binder(); + let fn_sig = self.cx.tcx.fn_sig(def_id).instantiate_identity().skip_binder(); for (expr, bound) in iter::zip(std::iter::once(*receiver).chain(args.iter()), fn_sig.inputs()) { self.ty_bounds.push((*bound).into()); self.visit_expr(expr); @@ -167,7 +167,7 @@ impl<'a, 'tcx> Visitor<'tcx> for NumericFallbackVisitor<'a, 'tcx> { .iter() .find_map(|f_def| { if f_def.ident(self.cx.tcx) == field.ident - { Some(self.cx.tcx.type_of(f_def.did).subst_identity()) } + { Some(self.cx.tcx.type_of(f_def.did).instantiate_identity()) } else { None } }); self.ty_bounds.push(bound.into()); @@ -213,9 +213,9 @@ impl<'a, 'tcx> Visitor<'tcx> for NumericFallbackVisitor<'a, 'tcx> { fn fn_sig_opt<'tcx>(cx: &LateContext<'tcx>, hir_id: HirId) -> Option<PolyFnSig<'tcx>> { let node_ty = cx.typeck_results().node_type_opt(hir_id)?; - // We can't use `Ty::fn_sig` because it automatically performs substs, this may result in FNs. + // We can't use `Ty::fn_sig` because it automatically performs args, this may result in FNs. match node_ty.kind() { - ty::FnDef(def_id, _) => Some(cx.tcx.fn_sig(*def_id).subst_identity()), + ty::FnDef(def_id, _) => Some(cx.tcx.fn_sig(*def_id).instantiate_identity()), ty::FnPtr(fn_sig) => Some(*fn_sig), _ => None, } diff --git a/src/tools/clippy/clippy_lints/src/dereference.rs b/src/tools/clippy/clippy_lints/src/dereference.rs index 73556c1053e..0e7efd53390 100644 --- a/src/tools/clippy/clippy_lints/src/dereference.rs +++ b/src/tools/clippy/clippy_lints/src/dereference.rs @@ -739,7 +739,7 @@ fn walk_parents<'tcx>( span, .. }) if span.ctxt() == ctxt => { - let ty = cx.tcx.type_of(owner_id.def_id).subst_identity(); + let ty = cx.tcx.type_of(owner_id.def_id).instantiate_identity(); Some(ty_auto_deref_stability(cx.tcx, cx.param_env, ty, precedence).position_for_result(cx)) }, @@ -763,7 +763,7 @@ fn walk_parents<'tcx>( }) if span.ctxt() == ctxt => { let output = cx .tcx - .erase_late_bound_regions(cx.tcx.fn_sig(owner_id).subst_identity().output()); + .erase_late_bound_regions(cx.tcx.fn_sig(owner_id).instantiate_identity().output()); Some(ty_auto_deref_stability(cx.tcx, cx.param_env, output, precedence).position_for_result(cx)) }, @@ -785,7 +785,7 @@ fn walk_parents<'tcx>( cx.tcx, // Use the param_env of the target type. cx.tcx.param_env(adt.did()), - cx.tcx.type_of(field_def.did).subst_identity(), + cx.tcx.type_of(field_def.did).instantiate_identity(), precedence, ) .position_for_arg() @@ -808,7 +808,7 @@ fn walk_parents<'tcx>( } else { let output = cx .tcx - .erase_late_bound_regions(cx.tcx.fn_sig(owner_id).subst_identity().output()); + .erase_late_bound_regions(cx.tcx.fn_sig(owner_id).instantiate_identity().output()); ty_auto_deref_stability(cx.tcx, cx.param_env, output, precedence).position_for_result(cx) }, ) @@ -879,9 +879,9 @@ fn walk_parents<'tcx>( && let ty::Ref(_, sub_ty, _) = *arg_ty.kind() && let subs = cx .typeck_results() - .node_substs_opt(parent.hir_id).map(|subs| &subs[1..]).unwrap_or_default() + .node_args_opt(parent.hir_id).map(|subs| &subs[1..]).unwrap_or_default() && let impl_ty = if cx.tcx.fn_sig(fn_id) - .subst_identity() + .instantiate_identity() .skip_binder() .inputs()[0].is_ref() { @@ -905,7 +905,7 @@ fn walk_parents<'tcx>( return Some(Position::MethodReceiver); } args.iter().position(|arg| arg.hir_id == child_id).map(|i| { - let ty = cx.tcx.fn_sig(fn_id).subst_identity().input(i + 1); + let ty = cx.tcx.fn_sig(fn_id).instantiate_identity().input(i + 1); // `e.hir_id == child_id` for https://github.com/rust-lang/rust-clippy/issues/9739 // `method.args.is_none()` for https://github.com/rust-lang/rust-clippy/issues/9782 if e.hir_id == child_id @@ -1124,10 +1124,10 @@ fn needless_borrow_impl_arg_position<'tcx>( let sized_trait_def_id = cx.tcx.lang_items().sized_trait(); let Some(callee_def_id) = fn_def_id(cx, parent) else { return Position::Other(precedence) }; - let fn_sig = cx.tcx.fn_sig(callee_def_id).subst_identity().skip_binder(); - let substs_with_expr_ty = cx + let fn_sig = cx.tcx.fn_sig(callee_def_id).instantiate_identity().skip_binder(); + let args_with_expr_ty = cx .typeck_results() - .node_substs(if let ExprKind::Call(callee, _) = parent.kind { + .node_args(if let ExprKind::Call(callee, _) = parent.kind { callee.hir_id } else { parent.hir_id @@ -1181,9 +1181,9 @@ fn needless_borrow_impl_arg_position<'tcx>( return Position::Other(precedence); } - // `substs_with_referent_ty` can be constructed outside of `check_referent` because the same + // `args_with_referent_ty` can be constructed outside of `check_referent` because the same // elements are modified each time `check_referent` is called. - let mut substs_with_referent_ty = substs_with_expr_ty.to_vec(); + let mut args_with_referent_ty = args_with_expr_ty.to_vec(); let mut check_reference_and_referent = |reference, referent| { let referent_ty = cx.typeck_results().expr_ty(referent); @@ -1207,7 +1207,7 @@ fn needless_borrow_impl_arg_position<'tcx>( fn_sig, arg_index, &projection_predicates, - &mut substs_with_referent_ty, + &mut args_with_referent_ty, ) { return false; } @@ -1216,14 +1216,14 @@ fn needless_borrow_impl_arg_position<'tcx>( if let ClauseKind::Trait(trait_predicate) = predicate.kind().skip_binder() && cx.tcx.is_diagnostic_item(sym::IntoIterator, trait_predicate.trait_ref.def_id) && let ty::Param(param_ty) = trait_predicate.self_ty().kind() - && let GenericArgKind::Type(ty) = substs_with_referent_ty[param_ty.index as usize].unpack() + && let GenericArgKind::Type(ty) = args_with_referent_ty[param_ty.index as usize].unpack() && ty.is_array() && !msrv.meets(msrvs::ARRAY_INTO_ITERATOR) { return false; } - let predicate = EarlyBinder::bind(predicate).subst(cx.tcx, &substs_with_referent_ty); + let predicate = EarlyBinder::bind(predicate).instantiate(cx.tcx, &args_with_referent_ty); let obligation = Obligation::new(cx.tcx, ObligationCause::dummy(), cx.param_env, predicate); let infcx = cx.tcx.infer_ctxt().build(); infcx.predicate_must_hold_modulo_regions(&obligation) @@ -1252,7 +1252,7 @@ fn has_ref_mut_self_method(cx: &LateContext<'_>, trait_def_id: DefId) -> bool { .in_definition_order() .any(|assoc_item| { if assoc_item.fn_has_self_parameter { - let self_ty = cx.tcx.fn_sig(assoc_item.def_id).subst_identity().skip_binder().inputs()[0]; + let self_ty = cx.tcx.fn_sig(assoc_item.def_id).instantiate_identity().skip_binder().inputs()[0]; matches!(self_ty.kind(), ty::Ref(_, _, Mutability::Mut)) } else { false @@ -1323,7 +1323,7 @@ fn referent_used_exactly_once<'tcx>( } } -// Iteratively replaces `param_ty` with `new_ty` in `substs`, and similarly for each resulting +// Iteratively replaces `param_ty` with `new_ty` in `args`, and similarly for each resulting // projected type that is a type parameter. Returns `false` if replacing the types would have an // effect on the function signature beyond substituting `new_ty` for `param_ty`. // See: https://github.com/rust-lang/rust-clippy/pull/9136#discussion_r927212757 @@ -1334,11 +1334,11 @@ fn replace_types<'tcx>( fn_sig: FnSig<'tcx>, arg_index: usize, projection_predicates: &[ProjectionPredicate<'tcx>], - substs: &mut [ty::GenericArg<'tcx>], + args: &mut [ty::GenericArg<'tcx>], ) -> bool { - let mut replaced = BitSet::new_empty(substs.len()); + let mut replaced = BitSet::new_empty(args.len()); - let mut deque = VecDeque::with_capacity(substs.len()); + let mut deque = VecDeque::with_capacity(args.len()); deque.push_back((param_ty, new_ty)); while let Some((param_ty, new_ty)) = deque.pop_front() { @@ -1352,7 +1352,7 @@ fn replace_types<'tcx>( return false; } - substs[param_ty.index as usize] = ty::GenericArg::from(new_ty); + args[param_ty.index as usize] = ty::GenericArg::from(new_ty); // The `replaced.insert(...)` check provides some protection against infinite loops. if replaced.insert(param_ty.index) { @@ -1367,7 +1367,7 @@ fn replace_types<'tcx>( )); if let Ok(projected_ty) = cx.tcx.try_normalize_erasing_regions(cx.param_env, projection) - && substs[term_param_ty.index as usize] != ty::GenericArg::from(projected_ty) + && args[term_param_ty.index as usize] != ty::GenericArg::from(projected_ty) { deque.push_back((*term_param_ty, projected_ty)); } @@ -1442,7 +1442,7 @@ fn ty_auto_deref_stability<'tcx>( ty::Adt(..) if ty.has_placeholders() || ty.has_opaque_types() => { Position::ReborrowStable(precedence).into() }, - ty::Adt(_, substs) if substs.has_non_region_param() => { + ty::Adt(_, args) if args.has_non_region_param() => { TyPosition::new_deref_stable_for_result(precedence, ty) }, ty::Bool diff --git a/src/tools/clippy/clippy_lints/src/derivable_impls.rs b/src/tools/clippy/clippy_lints/src/derivable_impls.rs index 020ffe7f8fa..71b5104bed8 100644 --- a/src/tools/clippy/clippy_lints/src/derivable_impls.rs +++ b/src/tools/clippy/clippy_lints/src/derivable_impls.rs @@ -10,7 +10,7 @@ use rustc_hir::{ }; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::ty::adjustment::{Adjust, PointerCoercion}; -use rustc_middle::ty::{self, Adt, AdtDef, SubstsRef, Ty, TypeckResults}; +use rustc_middle::ty::{self, Adt, AdtDef, GenericArgsRef, Ty, TypeckResults}; use rustc_session::{declare_tool_lint, impl_lint_pass}; use rustc_span::sym; @@ -80,7 +80,7 @@ fn is_path_self(e: &Expr<'_>) -> bool { fn contains_trait_object(ty: Ty<'_>) -> bool { match ty.kind() { ty::Ref(_, ty, _) => contains_trait_object(*ty), - ty::Adt(def, substs) => def.is_box() && substs[0].as_type().map_or(false, contains_trait_object), + ty::Adt(def, args) => def.is_box() && args[0].as_type().map_or(false, contains_trait_object), ty::Dynamic(..) => true, _ => false, } @@ -92,18 +92,18 @@ fn check_struct<'tcx>( self_ty: &hir::Ty<'_>, func_expr: &Expr<'_>, adt_def: AdtDef<'_>, - substs: SubstsRef<'_>, + ty_args: GenericArgsRef<'_>, typeck_results: &'tcx TypeckResults<'tcx>, ) { if let TyKind::Path(QPath::Resolved(_, p)) = self_ty.kind { if let Some(PathSegment { args, .. }) = p.segments.last() { let args = args.map(|a| a.args).unwrap_or(&[]); - // substs contains the generic parameters of the type declaration, while args contains the arguments + // ty_args contains the generic parameters of the type declaration, while args contains the arguments // used at instantiation time. If both len are not equal, it means that some parameters were not // provided (which means that the default values were used); in this case we will not risk // suggesting too broad a rewrite. We won't either if any argument is a type or a const. - if substs.len() != args.len() || args.iter().any(|arg| !matches!(arg, GenericArg::Lifetime(_))) { + if ty_args.len() != args.len() || args.iter().any(|arg| !matches!(arg, GenericArg::Lifetime(_))) { return; } } @@ -214,7 +214,7 @@ impl<'tcx> LateLintPass<'tcx> for DerivableImpls { if let Some(Node::ImplItem(impl_item)) = cx.tcx.hir().find(impl_item_hir); if let ImplItemKind::Fn(_, b) = &impl_item.kind; if let Body { value: func_expr, .. } = cx.tcx.hir().body(*b); - if let &Adt(adt_def, substs) = cx.tcx.type_of(item.owner_id).subst_identity().kind(); + if let &Adt(adt_def, args) = cx.tcx.type_of(item.owner_id).instantiate_identity().kind(); if let attrs = cx.tcx.hir().attrs(item.hir_id()); if !attrs.iter().any(|attr| attr.doc_str().is_some()); if let child_attrs = cx.tcx.hir().attrs(impl_item_hir); @@ -222,7 +222,7 @@ impl<'tcx> LateLintPass<'tcx> for DerivableImpls { then { if adt_def.is_struct() { - check_struct(cx, item, self_ty, func_expr, adt_def, substs, cx.tcx.typeck_body(*b)); + check_struct(cx, item, self_ty, func_expr, adt_def, args, cx.tcx.typeck_body(*b)); } else if adt_def.is_enum() && self.msrv.meets(msrvs::DEFAULT_ENUM_ATTRIBUTE) { check_enum(cx, item, func_expr, adt_def); } diff --git a/src/tools/clippy/clippy_lints/src/derive.rs b/src/tools/clippy/clippy_lints/src/derive.rs index a005a360e9c..78e7f93e2bf 100644 --- a/src/tools/clippy/clippy_lints/src/derive.rs +++ b/src/tools/clippy/clippy_lints/src/derive.rs @@ -211,7 +211,7 @@ impl<'tcx> LateLintPass<'tcx> for Derive { .. }) = item.kind { - let ty = cx.tcx.type_of(item.owner_id).subst_identity(); + let ty = cx.tcx.type_of(item.owner_id).instantiate_identity(); let is_automatically_derived = cx.tcx.has_attr(item.owner_id, sym::automatically_derived); check_hash_peq(cx, item.span, trait_ref, ty, is_automatically_derived); @@ -252,7 +252,7 @@ fn check_hash_peq<'tcx>( // Only care about `impl PartialEq<Foo> for Foo` // For `impl PartialEq<B> for A, input_types is [A, B] - if trait_ref.subst_identity().substs.type_at(1) == ty { + if trait_ref.instantiate_identity().args.type_at(1) == ty { span_lint_and_then( cx, DERIVED_HASH_WITH_MANUAL_EQ, @@ -300,7 +300,7 @@ fn check_ord_partial_ord<'tcx>( // Only care about `impl PartialOrd<Foo> for Foo` // For `impl PartialOrd<B> for A, input_types is [A, B] - if trait_ref.subst_identity().substs.type_at(1) == ty { + if trait_ref.instantiate_identity().args.type_at(1) == ty { let mess = if partial_ord_is_automatically_derived { "you are implementing `Ord` explicitly but have derived `PartialOrd`" } else { @@ -347,7 +347,7 @@ fn check_copy_clone<'tcx>(cx: &LateContext<'tcx>, item: &Item<'_>, trait_ref: &h let has_copy_impl = cx.tcx.all_local_trait_impls(()).get(©_id).map_or(false, |impls| { impls .iter() - .any(|&id| matches!(cx.tcx.type_of(id).subst_identity().kind(), ty::Adt(adt, _) if ty_adt.did() == adt.did())) + .any(|&id| matches!(cx.tcx.type_of(id).instantiate_identity().kind(), ty::Adt(adt, _) if ty_adt.did() == adt.did())) }); if !has_copy_impl { return; @@ -464,7 +464,7 @@ impl<'tcx> Visitor<'tcx> for UnsafeVisitor<'_, 'tcx> { /// Implementation of the `DERIVE_PARTIAL_EQ_WITHOUT_EQ` lint. fn check_partial_eq_without_eq<'tcx>(cx: &LateContext<'tcx>, span: Span, trait_ref: &hir::TraitRef<'_>, ty: Ty<'tcx>) { if_chain! { - if let ty::Adt(adt, substs) = ty.kind(); + if let ty::Adt(adt, args) = ty.kind(); if cx.tcx.visibility(adt.did()).is_public(); if let Some(eq_trait_def_id) = cx.tcx.get_diagnostic_item(sym::Eq); if let Some(def_id) = trait_ref.trait_def_id(); @@ -474,7 +474,7 @@ fn check_partial_eq_without_eq<'tcx>(cx: &LateContext<'tcx>, span: Span, trait_r // If all of our fields implement `Eq`, we can implement `Eq` too if adt .all_fields() - .map(|f| f.ty(cx.tcx, substs)) + .map(|f| f.ty(cx.tcx, args)) .all(|ty| implements_trait_with_env(cx.tcx, param_env, ty, eq_trait_def_id, [])); then { span_lint_and_sugg( diff --git a/src/tools/clippy/clippy_lints/src/empty_enum.rs b/src/tools/clippy/clippy_lints/src/empty_enum.rs index d94664daa56..1701d061128 100644 --- a/src/tools/clippy/clippy_lints/src/empty_enum.rs +++ b/src/tools/clippy/clippy_lints/src/empty_enum.rs @@ -49,7 +49,7 @@ impl<'tcx> LateLintPass<'tcx> for EmptyEnum { } if let ItemKind::Enum(..) = item.kind { - let ty = cx.tcx.type_of(item.owner_id).subst_identity(); + let ty = cx.tcx.type_of(item.owner_id).instantiate_identity(); let adt = ty.ty_adt_def().expect("already checked whether this is an enum"); if adt.variants().is_empty() { span_lint_and_help( diff --git a/src/tools/clippy/clippy_lints/src/enum_clike.rs b/src/tools/clippy/clippy_lints/src/enum_clike.rs index d85650712db..96c5c7fc509 100644 --- a/src/tools/clippy/clippy_lints/src/enum_clike.rs +++ b/src/tools/clippy/clippy_lints/src/enum_clike.rs @@ -45,7 +45,7 @@ impl<'tcx> LateLintPass<'tcx> for UnportableVariant { for var in def.variants { if let Some(anon_const) = &var.disr_expr { let def_id = cx.tcx.hir().body_owner_def_id(anon_const.body); - let mut ty = cx.tcx.type_of(def_id.to_def_id()).subst_identity(); + let mut ty = cx.tcx.type_of(def_id.to_def_id()).instantiate_identity(); let constant = cx .tcx .const_eval_poly(def_id.to_def_id()) diff --git a/src/tools/clippy/clippy_lints/src/eta_reduction.rs b/src/tools/clippy/clippy_lints/src/eta_reduction.rs index 58e62d1f3d3..22e10accd35 100644 --- a/src/tools/clippy/clippy_lints/src/eta_reduction.rs +++ b/src/tools/clippy/clippy_lints/src/eta_reduction.rs @@ -11,7 +11,7 @@ use rustc_hir::{Closure, Expr, ExprKind, Param, PatKind, Unsafety}; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow}; use rustc_middle::ty::binding::BindingMode; -use rustc_middle::ty::{self, EarlyBinder, SubstsRef, Ty, TypeVisitableExt}; +use rustc_middle::ty::{self, EarlyBinder, GenericArgsRef, Ty, TypeVisitableExt}; use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::symbol::sym; @@ -108,18 +108,18 @@ impl<'tcx> LateLintPass<'tcx> for EtaReduction { if check_inputs(cx, body.params, None, args); let callee_ty = cx.typeck_results().expr_ty_adjusted(callee); let call_ty = cx.typeck_results().type_dependent_def_id(body.value.hir_id) - .map_or(callee_ty, |id| cx.tcx.type_of(id).subst_identity()); + .map_or(callee_ty, |id| cx.tcx.type_of(id).instantiate_identity()); if check_sig(cx, closure_ty, call_ty); - let substs = cx.typeck_results().node_substs(callee.hir_id); + let args = cx.typeck_results().node_args(callee.hir_id); // This fixes some false positives that I don't entirely understand - if substs.is_empty() || !cx.typeck_results().expr_ty(expr).has_late_bound_regions(); + if args.is_empty() || !cx.typeck_results().expr_ty(expr).has_late_bound_regions(); // A type param function ref like `T::f` is not 'static, however // it is if cast like `T::f as fn()`. This seems like a rustc bug. - if !substs.types().any(|t| matches!(t.kind(), ty::Param(_))); + if !args.types().any(|t| matches!(t.kind(), ty::Param(_))); let callee_ty_unadjusted = cx.typeck_results().expr_ty(callee).peel_refs(); if !is_type_diagnostic_item(cx, callee_ty_unadjusted, sym::Arc); if !is_type_diagnostic_item(cx, callee_ty_unadjusted, sym::Rc); - if let ty::Closure(_, substs) = *closure_ty.kind(); + if let ty::Closure(_, args) = *closure_ty.kind(); // Don't lint if this is an inclusive range expression. // They desugar to a call to `RangeInclusiveNew` which would have odd suggestions. (#10684) if !matches!(higher::Range::hir(body.value), Some(higher::Range { @@ -131,7 +131,7 @@ impl<'tcx> LateLintPass<'tcx> for EtaReduction { span_lint_and_then(cx, REDUNDANT_CLOSURE, expr.span, "redundant closure", |diag| { if let Some(mut snippet) = snippet_opt(cx, callee.span) { if let Some(fn_mut_id) = cx.tcx.lang_items().fn_mut_trait() - && let args = cx.tcx.erase_late_bound_regions(substs.as_closure().sig()).inputs() + && let args = cx.tcx.erase_late_bound_regions(args.as_closure().sig()).inputs() && implements_trait( cx, callee_ty.peel_refs(), @@ -160,12 +160,12 @@ impl<'tcx> LateLintPass<'tcx> for EtaReduction { if let ExprKind::MethodCall(path, receiver, args, _) = body.value.kind; if check_inputs(cx, body.params, Some(receiver), args); let method_def_id = cx.typeck_results().type_dependent_def_id(body.value.hir_id).unwrap(); - let substs = cx.typeck_results().node_substs(body.value.hir_id); - let call_ty = cx.tcx.type_of(method_def_id).subst(cx.tcx, substs); + let args = cx.typeck_results().node_args(body.value.hir_id); + let call_ty = cx.tcx.type_of(method_def_id).instantiate(cx.tcx, args); if check_sig(cx, closure_ty, call_ty); then { span_lint_and_then(cx, REDUNDANT_CLOSURE_FOR_METHOD_CALLS, expr.span, "redundant closure", |diag| { - let name = get_ufcs_type_name(cx, method_def_id, substs); + let name = get_ufcs_type_name(cx, method_def_id, args); diag.span_suggestion( expr.span, "replace the closure with the method itself", @@ -228,14 +228,14 @@ fn check_sig<'tcx>(cx: &LateContext<'tcx>, closure_ty: Ty<'tcx>, call_ty: Ty<'tc if !closure_ty.has_late_bound_regions() { return true; } - let ty::Closure(_, substs) = closure_ty.kind() else { + let ty::Closure(_, args) = closure_ty.kind() else { return false; }; - let closure_sig = cx.tcx.signature_unclosure(substs.as_closure().sig(), Unsafety::Normal); + let closure_sig = cx.tcx.signature_unclosure(args.as_closure().sig(), Unsafety::Normal); cx.tcx.erase_late_bound_regions(closure_sig) == cx.tcx.erase_late_bound_regions(call_sig) } -fn get_ufcs_type_name<'tcx>(cx: &LateContext<'tcx>, method_def_id: DefId, substs: SubstsRef<'tcx>) -> String { +fn get_ufcs_type_name<'tcx>(cx: &LateContext<'tcx>, method_def_id: DefId, args: GenericArgsRef<'tcx>) -> String { let assoc_item = cx.tcx.associated_item(method_def_id); let def_id = assoc_item.container_id(cx.tcx); match assoc_item.container { @@ -251,7 +251,7 @@ fn get_ufcs_type_name<'tcx>(cx: &LateContext<'tcx>, method_def_id: DefId, substs | ty::Ref(..) | ty::Slice(_) | ty::Tuple(_) => { - format!("<{}>", EarlyBinder::bind(ty).subst(cx.tcx, substs)) + format!("<{}>", EarlyBinder::bind(ty).instantiate(cx.tcx, args)) }, _ => ty.to_string(), } diff --git a/src/tools/clippy/clippy_lints/src/from_over_into.rs b/src/tools/clippy/clippy_lints/src/from_over_into.rs index 92d67ef359d..35061fc64c9 100644 --- a/src/tools/clippy/clippy_lints/src/from_over_into.rs +++ b/src/tools/clippy/clippy_lints/src/from_over_into.rs @@ -76,9 +76,9 @@ impl<'tcx> LateLintPass<'tcx> for FromOverInto { && let Some(into_trait_seg) = hir_trait_ref.path.segments.last() // `impl Into<target_ty> for self_ty` && let Some(GenericArgs { args: [GenericArg::Type(target_ty)], .. }) = into_trait_seg.args - && let Some(middle_trait_ref) = cx.tcx.impl_trait_ref(item.owner_id).map(ty::EarlyBinder::subst_identity) + && let Some(middle_trait_ref) = cx.tcx.impl_trait_ref(item.owner_id).map(ty::EarlyBinder::instantiate_identity) && cx.tcx.is_diagnostic_item(sym::Into, middle_trait_ref.def_id) - && !matches!(middle_trait_ref.substs.type_at(1).kind(), ty::Alias(ty::Opaque, _)) + && !matches!(middle_trait_ref.args.type_at(1).kind(), ty::Alias(ty::Opaque, _)) { span_lint_and_then( cx, diff --git a/src/tools/clippy/clippy_lints/src/functions/must_use.rs b/src/tools/clippy/clippy_lints/src/functions/must_use.rs index d0ad2628264..1b173de856b 100644 --- a/src/tools/clippy/clippy_lints/src/functions/must_use.rs +++ b/src/tools/clippy/clippy_lints/src/functions/must_use.rs @@ -198,14 +198,14 @@ fn is_mutable_ty<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>, tys: &mut DefIdSet) match *ty.kind() { // primitive types are never mutable ty::Bool | ty::Char | ty::Int(_) | ty::Uint(_) | ty::Float(_) | ty::Str => false, - ty::Adt(adt, substs) => { + ty::Adt(adt, args) => { tys.insert(adt.did()) && !ty.is_freeze(cx.tcx, cx.param_env) || KNOWN_WRAPPER_TYS .iter() .any(|&sym| cx.tcx.is_diagnostic_item(sym, adt.did())) - && substs.types().any(|ty| is_mutable_ty(cx, ty, tys)) + && args.types().any(|ty| is_mutable_ty(cx, ty, tys)) }, - ty::Tuple(substs) => substs.iter().any(|ty| is_mutable_ty(cx, ty, tys)), + ty::Tuple(args) => args.iter().any(|ty| is_mutable_ty(cx, ty, tys)), ty::Array(ty, _) | ty::Slice(ty) => is_mutable_ty(cx, ty, tys), ty::RawPtr(ty::TypeAndMut { ty, mutbl }) | ty::Ref(_, ty, mutbl) => { mutbl == hir::Mutability::Mut || is_mutable_ty(cx, ty, tys) diff --git a/src/tools/clippy/clippy_lints/src/functions/result.rs b/src/tools/clippy/clippy_lints/src/functions/result.rs index fa2a9b30c05..90fc0d4f662 100644 --- a/src/tools/clippy/clippy_lints/src/functions/result.rs +++ b/src/tools/clippy/clippy_lints/src/functions/result.rs @@ -21,11 +21,11 @@ fn result_err_ty<'tcx>( ) -> Option<(&'tcx hir::Ty<'tcx>, Ty<'tcx>)> { if !in_external_macro(cx.sess(), item_span) && let hir::FnRetTy::Return(hir_ty) = decl.output - && let ty = cx.tcx.erase_late_bound_regions(cx.tcx.fn_sig(id).subst_identity().output()) + && let ty = cx.tcx.erase_late_bound_regions(cx.tcx.fn_sig(id).instantiate_identity().output()) && is_type_diagnostic_item(cx, ty, sym::Result) - && let ty::Adt(_, substs) = ty.kind() + && let ty::Adt(_, args) = ty.kind() { - let err_ty = substs.type_at(1); + let err_ty = args.type_at(1); Some((hir_ty, err_ty)) } else { None diff --git a/src/tools/clippy/clippy_lints/src/future_not_send.rs b/src/tools/clippy/clippy_lints/src/future_not_send.rs index 818ebd1134d..e54429aee8e 100644 --- a/src/tools/clippy/clippy_lints/src/future_not_send.rs +++ b/src/tools/clippy/clippy_lints/src/future_not_send.rs @@ -63,10 +63,10 @@ impl<'tcx> LateLintPass<'tcx> for FutureNotSend { return; } let ret_ty = return_ty(cx, cx.tcx.hir().local_def_id_to_hir_id(fn_def_id).expect_owner()); - if let ty::Alias(ty::Opaque, AliasTy { def_id, substs, .. }) = *ret_ty.kind() { + if let ty::Alias(ty::Opaque, AliasTy { def_id, args, .. }) = *ret_ty.kind() { let preds = cx.tcx.explicit_item_bounds(def_id); let mut is_future = false; - for (p, _span) in preds.subst_iter_copied(cx.tcx, substs) { + for (p, _span) in preds.arg_iter_copied(cx.tcx, args) { if let Some(trait_pred) = p.as_trait_clause() { if Some(trait_pred.skip_binder().trait_ref.def_id) == cx.tcx.lang_items().future_trait() { is_future = true; diff --git a/src/tools/clippy/clippy_lints/src/implicit_saturating_sub.rs b/src/tools/clippy/clippy_lints/src/implicit_saturating_sub.rs index 1e99b6faa6c..b99d4544681 100644 --- a/src/tools/clippy/clippy_lints/src/implicit_saturating_sub.rs +++ b/src/tools/clippy/clippy_lints/src/implicit_saturating_sub.rs @@ -102,7 +102,7 @@ impl<'tcx> LateLintPass<'tcx> for ImplicitSaturatingSub { if let Some(const_id) = cx.typeck_results().type_dependent_def_id(cond_num_val.hir_id); if let Some(impl_id) = cx.tcx.impl_of_method(const_id); if let None = cx.tcx.impl_trait_ref(impl_id); // An inherent impl - if cx.tcx.type_of(impl_id).subst_identity().is_integral(); + if cx.tcx.type_of(impl_id).instantiate_identity().is_integral(); then { print_lint_and_sugg(cx, var_name, expr) } @@ -115,7 +115,7 @@ impl<'tcx> LateLintPass<'tcx> for ImplicitSaturatingSub { if let Some(func_id) = cx.typeck_results().type_dependent_def_id(func.hir_id); if let Some(impl_id) = cx.tcx.impl_of_method(func_id); if let None = cx.tcx.impl_trait_ref(impl_id); // An inherent impl - if cx.tcx.type_of(impl_id).subst_identity().is_integral(); + if cx.tcx.type_of(impl_id).instantiate_identity().is_integral(); then { print_lint_and_sugg(cx, var_name, expr) } diff --git a/src/tools/clippy/clippy_lints/src/inherent_impl.rs b/src/tools/clippy/clippy_lints/src/inherent_impl.rs index 7c41699f307..3ac40401e89 100644 --- a/src/tools/clippy/clippy_lints/src/inherent_impl.rs +++ b/src/tools/clippy/clippy_lints/src/inherent_impl.rs @@ -66,7 +66,7 @@ impl<'tcx> LateLintPass<'tcx> for MultipleInherentImpl { ) }) { for impl_id in impl_ids.iter().map(|id| id.expect_local()) { - let impl_ty = cx.tcx.type_of(impl_id).subst_identity(); + let impl_ty = cx.tcx.type_of(impl_id).instantiate_identity(); match type_map.entry(impl_ty) { Entry::Vacant(e) => { // Store the id for the first impl block of this type. The span is retrieved lazily. diff --git a/src/tools/clippy/clippy_lints/src/iter_not_returning_iterator.rs b/src/tools/clippy/clippy_lints/src/iter_not_returning_iterator.rs index c924d7361ce..bb100ec632e 100644 --- a/src/tools/clippy/clippy_lints/src/iter_not_returning_iterator.rs +++ b/src/tools/clippy/clippy_lints/src/iter_not_returning_iterator.rs @@ -68,7 +68,7 @@ fn check_sig(cx: &LateContext<'_>, name: &str, sig: &FnSig<'_>, fn_id: LocalDefI if sig.decl.implicit_self.has_implicit_self() { let ret_ty = cx .tcx - .erase_late_bound_regions(cx.tcx.fn_sig(fn_id).subst_identity().output()); + .erase_late_bound_regions(cx.tcx.fn_sig(fn_id).instantiate_identity().output()); let ret_ty = cx .tcx .try_normalize_erasing_regions(cx.param_env, ret_ty) diff --git a/src/tools/clippy/clippy_lints/src/large_enum_variant.rs b/src/tools/clippy/clippy_lints/src/large_enum_variant.rs index 1c99bd2f3d0..693218f8a9c 100644 --- a/src/tools/clippy/clippy_lints/src/large_enum_variant.rs +++ b/src/tools/clippy/clippy_lints/src/large_enum_variant.rs @@ -83,7 +83,7 @@ impl<'tcx> LateLintPass<'tcx> for LargeEnumVariant { return; } if let ItemKind::Enum(ref def, _) = item.kind { - let ty = cx.tcx.type_of(item.owner_id).subst_identity(); + let ty = cx.tcx.type_of(item.owner_id).instantiate_identity(); let Adt(adt, subst) = ty.kind() else { panic!("already checked whether this is an enum") }; @@ -169,8 +169,8 @@ impl<'tcx> LateLintPass<'tcx> for LargeEnumVariant { } fn maybe_copy<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool { - if let Adt(_def, substs) = ty.kind() - && substs.types().next().is_some() + if let Adt(_def, args) = ty.kind() + && args.types().next().is_some() && let Some(copy_trait) = cx.tcx.lang_items().copy_trait() { return cx.tcx.non_blanket_impls_for_ty(copy_trait, ty).next().is_some(); diff --git a/src/tools/clippy/clippy_lints/src/len_zero.rs b/src/tools/clippy/clippy_lints/src/len_zero.rs index 17bd89efaee..83fa25c795a 100644 --- a/src/tools/clippy/clippy_lints/src/len_zero.rs +++ b/src/tools/clippy/clippy_lints/src/len_zero.rs @@ -145,7 +145,7 @@ impl<'tcx> LateLintPass<'tcx> for LenZero { if let Some(local_id) = ty_id.as_local(); let ty_hir_id = cx.tcx.hir().local_def_id_to_hir_id(local_id); if !is_lint_allowed(cx, LEN_WITHOUT_IS_EMPTY, ty_hir_id); - if let Some(output) = parse_len_output(cx, cx.tcx.fn_sig(item.owner_id).subst_identity().skip_binder()); + if let Some(output) = parse_len_output(cx, cx.tcx.fn_sig(item.owner_id).instantiate_identity().skip_binder()); then { let (name, kind) = match cx.tcx.hir().find(ty_hir_id) { Some(Node::ForeignItem(x)) => (x.ident.name, "extern type"), @@ -425,7 +425,7 @@ fn check_for_is_empty( if !(is_empty.fn_has_self_parameter && check_is_empty_sig( cx, - cx.tcx.fn_sig(is_empty.def_id).subst_identity().skip_binder(), + cx.tcx.fn_sig(is_empty.def_id).instantiate_identity().skip_binder(), self_kind, output, )) => diff --git a/src/tools/clippy/clippy_lints/src/let_underscore.rs b/src/tools/clippy/clippy_lints/src/let_underscore.rs index e6614180920..b7a47002080 100644 --- a/src/tools/clippy/clippy_lints/src/let_underscore.rs +++ b/src/tools/clippy/clippy_lints/src/let_underscore.rs @@ -5,7 +5,7 @@ use clippy_utils::{is_must_use_func_call, paths}; use rustc_hir::{Local, PatKind}; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::lint::in_external_macro; -use rustc_middle::ty::subst::GenericArgKind; +use rustc_middle::ty::GenericArgKind; use rustc_middle::ty::IsSuggestable; use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::{BytePos, Span}; diff --git a/src/tools/clippy/clippy_lints/src/loops/explicit_iter_loop.rs b/src/tools/clippy/clippy_lints/src/loops/explicit_iter_loop.rs index 5c5a4cfce88..a84a0a6eeb8 100644 --- a/src/tools/clippy/clippy_lints/src/loops/explicit_iter_loop.rs +++ b/src/tools/clippy/clippy_lints/src/loops/explicit_iter_loop.rs @@ -125,7 +125,7 @@ fn is_ref_iterable<'tcx>( } let res_ty = cx.tcx.erase_regions(EarlyBinder::bind(req_res_ty) - .subst(cx.tcx, typeck.node_substs(call_expr.hir_id))); + .instantiate(cx.tcx, typeck.node_args(call_expr.hir_id))); let mutbl = if let ty::Ref(_, _, mutbl) = *req_self_ty.kind() { Some(mutbl) } else { diff --git a/src/tools/clippy/clippy_lints/src/loops/missing_spin_loop.rs b/src/tools/clippy/clippy_lints/src/loops/missing_spin_loop.rs index 8412875b11b..0e49f08d898 100644 --- a/src/tools/clippy/clippy_lints/src/loops/missing_spin_loop.rs +++ b/src/tools/clippy/clippy_lints/src/loops/missing_spin_loop.rs @@ -35,7 +35,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, cond: &'tcx Expr<'_>, body: &' if let ExprKind::Block(Block { stmts: [], expr: None, ..}, _) = body.kind; if let ExprKind::MethodCall(method, callee, ..) = unpack_cond(cond).kind; if [sym::load, sym::compare_exchange, sym::compare_exchange_weak].contains(&method.ident.name); - if let ty::Adt(def, _substs) = cx.typeck_results().expr_ty(callee).kind(); + if let ty::Adt(def, _args) = cx.typeck_results().expr_ty(callee).kind(); if cx.tcx.is_diagnostic_item(sym::AtomicBool, def.did()); then { span_lint_and_sugg( diff --git a/src/tools/clippy/clippy_lints/src/loops/needless_range_loop.rs b/src/tools/clippy/clippy_lints/src/loops/needless_range_loop.rs index cb446567506..2c20e9e8693 100644 --- a/src/tools/clippy/clippy_lints/src/loops/needless_range_loop.rs +++ b/src/tools/clippy/clippy_lints/src/loops/needless_range_loop.rs @@ -370,7 +370,7 @@ impl<'a, 'tcx> Visitor<'tcx> for VarVisitor<'a, 'tcx> { ExprKind::MethodCall(_, receiver, args, _) => { let def_id = self.cx.typeck_results().type_dependent_def_id(expr.hir_id).unwrap(); for (ty, expr) in iter::zip( - self.cx.tcx.fn_sig(def_id).subst_identity().inputs().skip_binder(), + self.cx.tcx.fn_sig(def_id).instantiate_identity().inputs().skip_binder(), std::iter::once(receiver).chain(args.iter()), ) { self.prefer_mutable = false; diff --git a/src/tools/clippy/clippy_lints/src/manual_bits.rs b/src/tools/clippy/clippy_lints/src/manual_bits.rs index 4629b22d171..6c7c57ba1d6 100644 --- a/src/tools/clippy/clippy_lints/src/manual_bits.rs +++ b/src/tools/clippy/clippy_lints/src/manual_bits.rs @@ -110,7 +110,7 @@ fn get_size_of_ty<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) -> Option< if let Some(def_id) = cx.qpath_res(count_func_qpath, count_func.hir_id).opt_def_id(); if cx.tcx.is_diagnostic_item(sym::mem_size_of, def_id); then { - cx.typeck_results().node_substs(count_func.hir_id).types().next().map(|resolved_ty| (*real_ty, resolved_ty)) + cx.typeck_results().node_args(count_func.hir_id).types().next().map(|resolved_ty| (*real_ty, resolved_ty)) } else { None } diff --git a/src/tools/clippy/clippy_lints/src/manual_slice_size_calculation.rs b/src/tools/clippy/clippy_lints/src/manual_slice_size_calculation.rs index 703a6b25840..f97600b53e4 100644 --- a/src/tools/clippy/clippy_lints/src/manual_slice_size_calculation.rs +++ b/src/tools/clippy/clippy_lints/src/manual_slice_size_calculation.rs @@ -92,7 +92,7 @@ fn simplify_half<'tcx>( && let ExprKind::Path(ref func_qpath) = func.kind && let Some(def_id) = cx.qpath_res(func_qpath, func.hir_id).opt_def_id() && cx.tcx.is_diagnostic_item(sym::mem_size_of, def_id) - && let Some(ty2) = cx.typeck_results().node_substs(func.hir_id).types().next() + && let Some(ty2) = cx.typeck_results().node_args(func.hir_id).types().next() // T1 == T2? && *ty1 == ty2 { diff --git a/src/tools/clippy/clippy_lints/src/map_unit_fn.rs b/src/tools/clippy/clippy_lints/src/map_unit_fn.rs index edcab6968cb..75605fb3091 100644 --- a/src/tools/clippy/clippy_lints/src/map_unit_fn.rs +++ b/src/tools/clippy/clippy_lints/src/map_unit_fn.rs @@ -104,7 +104,7 @@ fn is_unit_function(cx: &LateContext<'_>, expr: &hir::Expr<'_>) -> bool { let ty = cx.typeck_results().expr_ty(expr); if let ty::FnDef(id, _) = *ty.kind() { - if let Some(fn_type) = cx.tcx.fn_sig(id).subst_identity().no_bound_vars() { + if let Some(fn_type) = cx.tcx.fn_sig(id).instantiate_identity().no_bound_vars() { return is_unit_type(fn_type.output()); } } diff --git a/src/tools/clippy/clippy_lints/src/matches/match_as_ref.rs b/src/tools/clippy/clippy_lints/src/matches/match_as_ref.rs index 2818f030b7a..29c6e11134f 100644 --- a/src/tools/clippy/clippy_lints/src/matches/match_as_ref.rs +++ b/src/tools/clippy/clippy_lints/src/matches/match_as_ref.rs @@ -27,10 +27,10 @@ pub(crate) fn check(cx: &LateContext<'_>, ex: &Expr<'_>, arms: &[Arm<'_>], expr: let input_ty = cx.typeck_results().expr_ty(ex); let cast = if_chain! { - if let ty::Adt(_, substs) = input_ty.kind(); - let input_ty = substs.type_at(0); - if let ty::Adt(_, substs) = output_ty.kind(); - let output_ty = substs.type_at(0); + if let ty::Adt(_, args) = input_ty.kind(); + let input_ty = args.type_at(0); + if let ty::Adt(_, args) = output_ty.kind(); + let output_ty = args.type_at(0); if let ty::Ref(_, output_ty, _) = *output_ty.kind(); if input_ty != output_ty; then { diff --git a/src/tools/clippy/clippy_lints/src/matches/redundant_pattern_match.rs b/src/tools/clippy/clippy_lints/src/matches/redundant_pattern_match.rs index 479cfd83512..039c2134cf8 100644 --- a/src/tools/clippy/clippy_lints/src/matches/redundant_pattern_match.rs +++ b/src/tools/clippy/clippy_lints/src/matches/redundant_pattern_match.rs @@ -12,7 +12,7 @@ use rustc_hir::def::{DefKind, Res}; use rustc_hir::LangItem::{self, OptionNone, OptionSome, PollPending, PollReady, ResultErr, ResultOk}; use rustc_hir::{Arm, Expr, ExprKind, Node, Pat, PatKind, QPath, UnOp}; use rustc_lint::LateContext; -use rustc_middle::ty::{self, subst::GenericArgKind, Ty}; +use rustc_middle::ty::{self, GenericArgKind, Ty}; use rustc_span::{sym, Symbol}; pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) { diff --git a/src/tools/clippy/clippy_lints/src/matches/rest_pat_in_fully_bound_struct.rs b/src/tools/clippy/clippy_lints/src/matches/rest_pat_in_fully_bound_struct.rs index d06bcdaa27f..4efe93d4b54 100644 --- a/src/tools/clippy/clippy_lints/src/matches/rest_pat_in_fully_bound_struct.rs +++ b/src/tools/clippy/clippy_lints/src/matches/rest_pat_in_fully_bound_struct.rs @@ -10,7 +10,7 @@ pub(crate) fn check(cx: &LateContext<'_>, pat: &Pat<'_>) { if !pat.span.from_expansion(); if let PatKind::Struct(QPath::Resolved(_, path), fields, true) = pat.kind; if let Some(def_id) = path.res.opt_def_id(); - let ty = cx.tcx.type_of(def_id).subst_identity(); + let ty = cx.tcx.type_of(def_id).instantiate_identity(); if let ty::Adt(def, _) = ty.kind(); if def.is_struct() || def.is_union(); if fields.len() == def.non_enum_variant().fields.len(); diff --git a/src/tools/clippy/clippy_lints/src/matches/significant_drop_in_scrutinee.rs b/src/tools/clippy/clippy_lints/src/matches/significant_drop_in_scrutinee.rs index 37528d9f7f2..02500fac293 100644 --- a/src/tools/clippy/clippy_lints/src/matches/significant_drop_in_scrutinee.rs +++ b/src/tools/clippy/clippy_lints/src/matches/significant_drop_in_scrutinee.rs @@ -6,7 +6,7 @@ use rustc_errors::{Applicability, Diagnostic}; use rustc_hir::intravisit::{walk_expr, Visitor}; use rustc_hir::{Arm, Expr, ExprKind, MatchSource}; use rustc_lint::{LateContext, LintContext}; -use rustc_middle::ty::subst::GenericArgKind; +use rustc_middle::ty::GenericArgKind; use rustc_middle::ty::{Ty, TypeAndMut}; use rustc_span::Span; diff --git a/src/tools/clippy/clippy_lints/src/methods/bytes_count_to_len.rs b/src/tools/clippy/clippy_lints/src/methods/bytes_count_to_len.rs index 46a20ad412b..649fc46e4ad 100644 --- a/src/tools/clippy/clippy_lints/src/methods/bytes_count_to_len.rs +++ b/src/tools/clippy/clippy_lints/src/methods/bytes_count_to_len.rs @@ -17,7 +17,7 @@ pub(super) fn check<'tcx>( if_chain! { if let Some(bytes_id) = cx.typeck_results().type_dependent_def_id(count_recv.hir_id); if let Some(impl_id) = cx.tcx.impl_of_method(bytes_id); - if cx.tcx.type_of(impl_id).subst_identity().is_str(); + if cx.tcx.type_of(impl_id).instantiate_identity().is_str(); let ty = cx.typeck_results().expr_ty(bytes_recv).peel_refs(); if ty.is_str() || is_type_lang_item(cx, ty, hir::LangItem::String); then { diff --git a/src/tools/clippy/clippy_lints/src/methods/case_sensitive_file_extension_comparisons.rs b/src/tools/clippy/clippy_lints/src/methods/case_sensitive_file_extension_comparisons.rs index 7711aa78b23..fb10f782f7a 100644 --- a/src/tools/clippy/clippy_lints/src/methods/case_sensitive_file_extension_comparisons.rs +++ b/src/tools/clippy/clippy_lints/src/methods/case_sensitive_file_extension_comparisons.rs @@ -30,7 +30,7 @@ pub(super) fn check<'tcx>( if_chain! { if let Some(method_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id); if let Some(impl_id) = cx.tcx.impl_of_method(method_id); - if cx.tcx.type_of(impl_id).subst_identity().is_str(); + if cx.tcx.type_of(impl_id).instantiate_identity().is_str(); if let ExprKind::Lit(Spanned { node: LitKind::Str(ext_literal, ..), ..}) = arg.kind; if (2..=6).contains(&ext_literal.as_str().len()); let ext_str = ext_literal.as_str(); diff --git a/src/tools/clippy/clippy_lints/src/methods/err_expect.rs b/src/tools/clippy/clippy_lints/src/methods/err_expect.rs index ae03da0d3f9..4ab06bf2ae8 100644 --- a/src/tools/clippy/clippy_lints/src/methods/err_expect.rs +++ b/src/tools/clippy/clippy_lints/src/methods/err_expect.rs @@ -47,7 +47,7 @@ pub(super) fn check( /// Given a `Result<T, E>` type, return its data (`T`). fn get_data_type<'a>(cx: &LateContext<'_>, ty: Ty<'a>) -> Option<Ty<'a>> { match ty.kind() { - ty::Adt(_, substs) if is_type_diagnostic_item(cx, ty, sym::Result) => substs.types().next(), + ty::Adt(_, args) if is_type_diagnostic_item(cx, ty, sym::Result) => args.types().next(), _ => None, } } diff --git a/src/tools/clippy/clippy_lints/src/methods/expect_fun_call.rs b/src/tools/clippy/clippy_lints/src/methods/expect_fun_call.rs index 92d21bb8932..9af11f08c26 100644 --- a/src/tools/clippy/clippy_lints/src/methods/expect_fun_call.rs +++ b/src/tools/clippy/clippy_lints/src/methods/expect_fun_call.rs @@ -70,7 +70,7 @@ pub(super) fn check<'tcx>( if let hir::ExprKind::Path(ref p) = fun.kind { match cx.qpath_res(p, fun.hir_id) { hir::def::Res::Def(hir::def::DefKind::Fn | hir::def::DefKind::AssocFn, def_id) => matches!( - cx.tcx.fn_sig(def_id).subst_identity().output().skip_binder().kind(), + cx.tcx.fn_sig(def_id).instantiate_identity().output().skip_binder().kind(), ty::Ref(re, ..) if re.is_static(), ), _ => false, @@ -84,7 +84,7 @@ pub(super) fn check<'tcx>( .type_dependent_def_id(arg.hir_id) .map_or(false, |method_id| { matches!( - cx.tcx.fn_sig(method_id).subst_identity().output().skip_binder().kind(), + cx.tcx.fn_sig(method_id).instantiate_identity().output().skip_binder().kind(), ty::Ref(re, ..) if re.is_static() ) }) diff --git a/src/tools/clippy/clippy_lints/src/methods/flat_map_option.rs b/src/tools/clippy/clippy_lints/src/methods/flat_map_option.rs index 615bde94133..4737a101345 100644 --- a/src/tools/clippy/clippy_lints/src/methods/flat_map_option.rs +++ b/src/tools/clippy/clippy_lints/src/methods/flat_map_option.rs @@ -15,7 +15,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>, arg } let arg_ty = cx.typeck_results().expr_ty_adjusted(arg); let sig = match arg_ty.kind() { - ty::Closure(_, substs) => substs.as_closure().sig(), + ty::Closure(_, args) => args.as_closure().sig(), _ if arg_ty.is_fn() => arg_ty.fn_sig(cx.tcx), _ => return, }; diff --git a/src/tools/clippy/clippy_lints/src/methods/get_first.rs b/src/tools/clippy/clippy_lints/src/methods/get_first.rs index 945bbf53bcf..ee063adac64 100644 --- a/src/tools/clippy/clippy_lints/src/methods/get_first.rs +++ b/src/tools/clippy/clippy_lints/src/methods/get_first.rs @@ -19,7 +19,7 @@ pub(super) fn check<'tcx>( if_chain! { if let Some(method_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id); if let Some(impl_id) = cx.tcx.impl_of_method(method_id); - if cx.tcx.type_of(impl_id).subst_identity().is_slice(); + if cx.tcx.type_of(impl_id).instantiate_identity().is_slice(); if let Some(_) = is_slice_of_primitives(cx, recv); if let hir::ExprKind::Lit(Spanned { node: LitKind::Int(0, _), .. }) = arg.kind; then { diff --git a/src/tools/clippy/clippy_lints/src/methods/implicit_clone.rs b/src/tools/clippy/clippy_lints/src/methods/implicit_clone.rs index 5a78a416877..043425300d8 100644 --- a/src/tools/clippy/clippy_lints/src/methods/implicit_clone.rs +++ b/src/tools/clippy/clippy_lints/src/methods/implicit_clone.rs @@ -54,7 +54,7 @@ pub fn is_clone_like(cx: &LateContext<'_>, method_name: &str, method_def_id: hir .tcx .impl_of_method(method_def_id) .filter(|&impl_did| { - cx.tcx.type_of(impl_did).subst_identity().is_slice() && cx.tcx.impl_trait_ref(impl_did).is_none() + cx.tcx.type_of(impl_did).instantiate_identity().is_slice() && cx.tcx.impl_trait_ref(impl_did).is_none() }) .is_some(), _ => false, diff --git a/src/tools/clippy/clippy_lints/src/methods/inefficient_to_string.rs b/src/tools/clippy/clippy_lints/src/methods/inefficient_to_string.rs index 424482859ee..37da52dc733 100644 --- a/src/tools/clippy/clippy_lints/src/methods/inefficient_to_string.rs +++ b/src/tools/clippy/clippy_lints/src/methods/inefficient_to_string.rs @@ -23,9 +23,9 @@ pub fn check( if args.is_empty() && method_name == sym::to_string; if let Some(to_string_meth_did) = cx.typeck_results().type_dependent_def_id(expr.hir_id); if match_def_path(cx, to_string_meth_did, &paths::TO_STRING_METHOD); - if let Some(substs) = cx.typeck_results().node_substs_opt(expr.hir_id); + if let Some(args) = cx.typeck_results().node_args_opt(expr.hir_id); let arg_ty = cx.typeck_results().expr_ty_adjusted(receiver); - let self_ty = substs.type_at(0); + let self_ty = args.type_at(0); let (deref_self_ty, deref_count) = walk_ptrs_ty_depth(self_ty); if deref_count >= 1; if specializes_tostring(cx, deref_self_ty); @@ -64,8 +64,8 @@ fn specializes_tostring(cx: &LateContext<'_>, ty: Ty<'_>) -> bool { return true; } - if let ty::Adt(adt, substs) = ty.kind() { - cx.tcx.is_diagnostic_item(sym::Cow, adt.did()) && substs.type_at(1).is_str() + if let ty::Adt(adt, args) = ty.kind() { + cx.tcx.is_diagnostic_item(sym::Cow, adt.did()) && args.type_at(1).is_str() } else { false } diff --git a/src/tools/clippy/clippy_lints/src/methods/manual_ok_or.rs b/src/tools/clippy/clippy_lints/src/methods/manual_ok_or.rs index b9a0ec77996..3031193e531 100644 --- a/src/tools/clippy/clippy_lints/src/methods/manual_ok_or.rs +++ b/src/tools/clippy/clippy_lints/src/methods/manual_ok_or.rs @@ -21,7 +21,7 @@ pub(super) fn check<'tcx>( if_chain! { if let Some(method_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id); if let Some(impl_id) = cx.tcx.impl_of_method(method_id); - if is_type_diagnostic_item(cx, cx.tcx.type_of(impl_id).subst_identity(), sym::Option); + if is_type_diagnostic_item(cx, cx.tcx.type_of(impl_id).instantiate_identity(), sym::Option); if let ExprKind::Call(err_path, [err_arg]) = or_expr.kind; if is_res_lang_ctor(cx, path_res(cx, err_path), ResultErr); if is_ok_wrapping(cx, map_expr); diff --git a/src/tools/clippy/clippy_lints/src/methods/map_clone.rs b/src/tools/clippy/clippy_lints/src/methods/map_clone.rs index 2b26ef01410..880efe60c1a 100644 --- a/src/tools/clippy/clippy_lints/src/methods/map_clone.rs +++ b/src/tools/clippy/clippy_lints/src/methods/map_clone.rs @@ -19,7 +19,7 @@ pub(super) fn check(cx: &LateContext<'_>, e: &hir::Expr<'_>, recv: &hir::Expr<'_ if_chain! { if let Some(method_id) = cx.typeck_results().type_dependent_def_id(e.hir_id); if cx.tcx.impl_of_method(method_id) - .map_or(false, |id| is_type_diagnostic_item(cx, cx.tcx.type_of(id).subst_identity(), sym::Option)) + .map_or(false, |id| is_type_diagnostic_item(cx, cx.tcx.type_of(id).instantiate_identity(), sym::Option)) || is_diag_trait_item(cx, method_id, sym::Iterator); if let hir::ExprKind::Closure(&hir::Closure{ body, .. }) = arg.kind; then { diff --git a/src/tools/clippy/clippy_lints/src/methods/map_collect_result_unit.rs b/src/tools/clippy/clippy_lints/src/methods/map_collect_result_unit.rs index a0300d27870..042bab805b8 100644 --- a/src/tools/clippy/clippy_lints/src/methods/map_collect_result_unit.rs +++ b/src/tools/clippy/clippy_lints/src/methods/map_collect_result_unit.rs @@ -15,8 +15,8 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, iter: &hir::Expr let collect_ret_ty = cx.typeck_results().expr_ty(expr); if_chain! { if is_type_diagnostic_item(cx, collect_ret_ty, sym::Result); - if let ty::Adt(_, substs) = collect_ret_ty.kind(); - if let Some(result_t) = substs.types().next(); + if let ty::Adt(_, args) = collect_ret_ty.kind(); + if let Some(result_t) = args.types().next(); if result_t.is_unit(); // get parts for snippet then { diff --git a/src/tools/clippy/clippy_lints/src/methods/map_err_ignore.rs b/src/tools/clippy/clippy_lints/src/methods/map_err_ignore.rs index a5beb291f32..fbb83c8ce56 100644 --- a/src/tools/clippy/clippy_lints/src/methods/map_err_ignore.rs +++ b/src/tools/clippy/clippy_lints/src/methods/map_err_ignore.rs @@ -9,7 +9,7 @@ use super::MAP_ERR_IGNORE; pub(super) fn check(cx: &LateContext<'_>, e: &Expr<'_>, arg: &Expr<'_>) { if let Some(method_id) = cx.typeck_results().type_dependent_def_id(e.hir_id) && let Some(impl_id) = cx.tcx.impl_of_method(method_id) - && is_type_diagnostic_item(cx, cx.tcx.type_of(impl_id).subst_identity(), sym::Result) + && is_type_diagnostic_item(cx, cx.tcx.type_of(impl_id).instantiate_identity(), sym::Result) && let ExprKind::Closure(&Closure { capture_clause: CaptureBy::Ref, body, diff --git a/src/tools/clippy/clippy_lints/src/methods/map_flatten.rs b/src/tools/clippy/clippy_lints/src/methods/map_flatten.rs index 361ffcb5ef3..950902d455b 100644 --- a/src/tools/clippy/clippy_lints/src/methods/map_flatten.rs +++ b/src/tools/clippy/clippy_lints/src/methods/map_flatten.rs @@ -59,7 +59,7 @@ fn is_map_to_option(cx: &LateContext<'_>, map_arg: &Expr<'_>) -> bool { match map_closure_ty.kind() { ty::Closure(_, _) | ty::FnDef(_, _) | ty::FnPtr(_) => { let map_closure_sig = match map_closure_ty.kind() { - ty::Closure(_, substs) => substs.as_closure().sig(), + ty::Closure(_, args) => args.as_closure().sig(), _ => map_closure_ty.fn_sig(cx.tcx), }; let map_closure_return_ty = cx.tcx.erase_late_bound_regions(map_closure_sig.output()); diff --git a/src/tools/clippy/clippy_lints/src/methods/mod.rs b/src/tools/clippy/clippy_lints/src/methods/mod.rs index 24dbe8c1d75..9ab78c6f8e0 100644 --- a/src/tools/clippy/clippy_lints/src/methods/mod.rs +++ b/src/tools/clippy/clippy_lints/src/methods/mod.rs @@ -3508,11 +3508,11 @@ impl<'tcx> LateLintPass<'tcx> for Methods { let name = impl_item.ident.name.as_str(); let parent = cx.tcx.hir().get_parent_item(impl_item.hir_id()).def_id; let item = cx.tcx.hir().expect_item(parent); - let self_ty = cx.tcx.type_of(item.owner_id).subst_identity(); + let self_ty = cx.tcx.type_of(item.owner_id).instantiate_identity(); let implements_trait = matches!(item.kind, hir::ItemKind::Impl(hir::Impl { of_trait: Some(_), .. })); if let hir::ImplItemKind::Fn(ref sig, id) = impl_item.kind { - let method_sig = cx.tcx.fn_sig(impl_item.owner_id).subst_identity(); + let method_sig = cx.tcx.fn_sig(impl_item.owner_id).instantiate_identity(); let method_sig = cx.tcx.erase_late_bound_regions(method_sig); let first_arg_ty_opt = method_sig.inputs().iter().next().copied(); // if this impl block implements a trait, lint in trait definition instead @@ -4113,8 +4113,8 @@ impl SelfKind { } else if ty.is_box() { ty.boxed_ty() == parent_ty } else if is_type_diagnostic_item(cx, ty, sym::Rc) || is_type_diagnostic_item(cx, ty, sym::Arc) { - if let ty::Adt(_, substs) = ty.kind() { - substs.types().next().map_or(false, |t| t == parent_ty) + if let ty::Adt(_, args) = ty.kind() { + args.types().next().map_or(false, |t| t == parent_ty) } else { false } diff --git a/src/tools/clippy/clippy_lints/src/methods/mut_mutex_lock.rs b/src/tools/clippy/clippy_lints/src/methods/mut_mutex_lock.rs index d0aa39d0627..fe024ee8dff 100644 --- a/src/tools/clippy/clippy_lints/src/methods/mut_mutex_lock.rs +++ b/src/tools/clippy/clippy_lints/src/methods/mut_mutex_lock.rs @@ -15,7 +15,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, ex: &'tcx Expr<'tcx>, recv: &' if let ty::Ref(_, _, Mutability::Mut) = cx.typeck_results().expr_ty(recv).kind(); if let Some(method_id) = cx.typeck_results().type_dependent_def_id(ex.hir_id); if let Some(impl_id) = cx.tcx.impl_of_method(method_id); - if is_type_diagnostic_item(cx, cx.tcx.type_of(impl_id).subst_identity(), sym::Mutex); + if is_type_diagnostic_item(cx, cx.tcx.type_of(impl_id).instantiate_identity(), sym::Mutex); then { span_lint_and_sugg( cx, diff --git a/src/tools/clippy/clippy_lints/src/methods/needless_collect.rs b/src/tools/clippy/clippy_lints/src/methods/needless_collect.rs index 8ca7af8107f..f34f1cf2704 100644 --- a/src/tools/clippy/clippy_lints/src/methods/needless_collect.rs +++ b/src/tools/clippy/clippy_lints/src/methods/needless_collect.rs @@ -163,7 +163,7 @@ fn check_collect_into_intoiterator<'tcx>( // that contains `collect_expr` let inputs = cx .tcx - .liberate_late_bound_regions(id, cx.tcx.fn_sig(id).subst_identity()) + .liberate_late_bound_regions(id, cx.tcx.fn_sig(id).instantiate_identity()) .inputs(); // map IntoIterator generic bounds to their signature @@ -201,7 +201,7 @@ fn check_collect_into_intoiterator<'tcx>( /// Checks if the given method call matches the expected signature of `([&[mut]] self) -> bool` fn is_is_empty_sig(cx: &LateContext<'_>, call_id: HirId) -> bool { cx.typeck_results().type_dependent_def_id(call_id).map_or(false, |id| { - let sig = cx.tcx.fn_sig(id).subst_identity().skip_binder(); + let sig = cx.tcx.fn_sig(id).instantiate_identity().skip_binder(); sig.inputs().len() == 1 && sig.output().is_bool() }) } @@ -215,7 +215,7 @@ fn iterates_same_ty<'tcx>(cx: &LateContext<'tcx>, iter_ty: Ty<'tcx>, collect_ty: && let Some(into_iter_item_proj) = make_projection(cx.tcx, into_iter_trait, item, [collect_ty]) && let Ok(into_iter_item_ty) = cx.tcx.try_normalize_erasing_regions( cx.param_env, - Ty::new_projection(cx.tcx,into_iter_item_proj.def_id, into_iter_item_proj.substs) + Ty::new_projection(cx.tcx,into_iter_item_proj.def_id, into_iter_item_proj.args) ) { iter_item_ty == into_iter_item_ty @@ -229,7 +229,7 @@ fn iterates_same_ty<'tcx>(cx: &LateContext<'tcx>, iter_ty: Ty<'tcx>, collect_ty: fn is_contains_sig(cx: &LateContext<'_>, call_id: HirId, iter_expr: &Expr<'_>) -> bool { let typeck = cx.typeck_results(); if let Some(id) = typeck.type_dependent_def_id(call_id) - && let sig = cx.tcx.fn_sig(id).subst_identity() + && let sig = cx.tcx.fn_sig(id).instantiate_identity() && sig.skip_binder().output().is_bool() && let [_, search_ty] = *sig.skip_binder().inputs() && let ty::Ref(_, search_ty, Mutability::Not) = *cx.tcx.erase_late_bound_regions(sig.rebind(search_ty)).kind() @@ -237,11 +237,11 @@ fn is_contains_sig(cx: &LateContext<'_>, call_id: HirId, iter_expr: &Expr<'_>) - && let Some(iter_item) = cx.tcx .associated_items(iter_trait) .find_by_name_and_kind(cx.tcx, Ident::with_dummy_span(Symbol::intern("Item")), AssocKind::Type, iter_trait) - && let substs = cx.tcx.mk_substs(&[GenericArg::from(typeck.expr_ty_adjusted(iter_expr))]) - && let proj_ty = Ty::new_projection(cx.tcx,iter_item.def_id, substs) + && let args = cx.tcx.mk_args(&[GenericArg::from(typeck.expr_ty_adjusted(iter_expr))]) + && let proj_ty = Ty::new_projection(cx.tcx,iter_item.def_id, args) && let Ok(item_ty) = cx.tcx.try_normalize_erasing_regions(cx.param_env, proj_ty) { - item_ty == EarlyBinder::bind(search_ty).subst(cx.tcx, cx.typeck_results().node_substs(call_id)) + item_ty == EarlyBinder::bind(search_ty).instantiate(cx.tcx, cx.typeck_results().node_args(call_id)) } else { false } diff --git a/src/tools/clippy/clippy_lints/src/methods/ok_expect.rs b/src/tools/clippy/clippy_lints/src/methods/ok_expect.rs index 646fc4a7bcf..f2ef42933df 100644 --- a/src/tools/clippy/clippy_lints/src/methods/ok_expect.rs +++ b/src/tools/clippy/clippy_lints/src/methods/ok_expect.rs @@ -33,7 +33,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, recv: &hir::Expr /// Given a `Result<T, E>` type, return its error type (`E`). fn get_error_type<'a>(cx: &LateContext<'_>, ty: Ty<'a>) -> Option<Ty<'a>> { match ty.kind() { - ty::Adt(_, substs) if is_type_diagnostic_item(cx, ty, sym::Result) => substs.types().nth(1), + ty::Adt(_, args) if is_type_diagnostic_item(cx, ty, sym::Result) => args.types().nth(1), _ => None, } } diff --git a/src/tools/clippy/clippy_lints/src/methods/open_options.rs b/src/tools/clippy/clippy_lints/src/methods/open_options.rs index bd625a6914c..1c664e76d74 100644 --- a/src/tools/clippy/clippy_lints/src/methods/open_options.rs +++ b/src/tools/clippy/clippy_lints/src/methods/open_options.rs @@ -11,7 +11,7 @@ use super::NONSENSICAL_OPEN_OPTIONS; pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>, recv: &'tcx Expr<'_>) { if let Some(method_id) = cx.typeck_results().type_dependent_def_id(e.hir_id) && let Some(impl_id) = cx.tcx.impl_of_method(method_id) - && match_type(cx, cx.tcx.type_of(impl_id).subst_identity(), &paths::OPEN_OPTIONS) + && match_type(cx, cx.tcx.type_of(impl_id).instantiate_identity(), &paths::OPEN_OPTIONS) { let mut options = Vec::new(); get_open_options(cx, recv, &mut options); diff --git a/src/tools/clippy/clippy_lints/src/methods/path_buf_push_overwrite.rs b/src/tools/clippy/clippy_lints/src/methods/path_buf_push_overwrite.rs index 0284d9dea30..1c07d2a3a59 100644 --- a/src/tools/clippy/clippy_lints/src/methods/path_buf_push_overwrite.rs +++ b/src/tools/clippy/clippy_lints/src/methods/path_buf_push_overwrite.rs @@ -14,7 +14,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, arg: &'t if_chain! { if let Some(method_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id); if let Some(impl_id) = cx.tcx.impl_of_method(method_id); - if is_type_diagnostic_item(cx, cx.tcx.type_of(impl_id).subst_identity(), sym::PathBuf); + if is_type_diagnostic_item(cx, cx.tcx.type_of(impl_id).instantiate_identity(), sym::PathBuf); if let ExprKind::Lit(lit) = arg.kind; if let LitKind::Str(ref path_lit, _) = lit.node; if let pushed_path = Path::new(path_lit.as_str()); diff --git a/src/tools/clippy/clippy_lints/src/methods/stable_sort_primitive.rs b/src/tools/clippy/clippy_lints/src/methods/stable_sort_primitive.rs index b5fd0ad8ce5..0f4c97022db 100644 --- a/src/tools/clippy/clippy_lints/src/methods/stable_sort_primitive.rs +++ b/src/tools/clippy/clippy_lints/src/methods/stable_sort_primitive.rs @@ -10,7 +10,7 @@ use super::STABLE_SORT_PRIMITIVE; pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>, recv: &'tcx Expr<'_>) { if let Some(method_id) = cx.typeck_results().type_dependent_def_id(e.hir_id) && let Some(impl_id) = cx.tcx.impl_of_method(method_id) - && cx.tcx.type_of(impl_id).subst_identity().is_slice() + && cx.tcx.type_of(impl_id).instantiate_identity().is_slice() && let Some(slice_type) = is_slice_of_primitives(cx, recv) { span_lint_and_then( diff --git a/src/tools/clippy/clippy_lints/src/methods/suspicious_splitn.rs b/src/tools/clippy/clippy_lints/src/methods/suspicious_splitn.rs index 90ca66bd70c..3cb2719e4a0 100644 --- a/src/tools/clippy/clippy_lints/src/methods/suspicious_splitn.rs +++ b/src/tools/clippy/clippy_lints/src/methods/suspicious_splitn.rs @@ -13,7 +13,7 @@ pub(super) fn check(cx: &LateContext<'_>, method_name: &str, expr: &Expr<'_>, se if let Some(call_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id); if let Some(impl_id) = cx.tcx.impl_of_method(call_id); if cx.tcx.impl_trait_ref(impl_id).is_none(); - let self_ty = cx.tcx.type_of(impl_id).subst_identity(); + let self_ty = cx.tcx.type_of(impl_id).instantiate_identity(); if self_ty.is_slice() || self_ty.is_str(); then { // Ignore empty slice and string literals when used with a literal count. diff --git a/src/tools/clippy/clippy_lints/src/methods/unnecessary_sort_by.rs b/src/tools/clippy/clippy_lints/src/methods/unnecessary_sort_by.rs index 67618f7038a..e62a65a2712 100644 --- a/src/tools/clippy/clippy_lints/src/methods/unnecessary_sort_by.rs +++ b/src/tools/clippy/clippy_lints/src/methods/unnecessary_sort_by.rs @@ -6,7 +6,7 @@ use if_chain::if_chain; use rustc_errors::Applicability; use rustc_hir::{Closure, Expr, ExprKind, Mutability, Param, Pat, PatKind, Path, PathSegment, QPath}; use rustc_lint::LateContext; -use rustc_middle::ty::{self, subst::GenericArgKind}; +use rustc_middle::ty::{self, GenericArgKind}; use rustc_span::sym; use rustc_span::symbol::Ident; use std::iter; @@ -118,7 +118,7 @@ fn detect_lint(cx: &LateContext<'_>, expr: &Expr<'_>, recv: &Expr<'_>, arg: &Exp if_chain! { if let Some(method_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id); if let Some(impl_id) = cx.tcx.impl_of_method(method_id); - if cx.tcx.type_of(impl_id).subst_identity().is_slice(); + if cx.tcx.type_of(impl_id).instantiate_identity().is_slice(); if let ExprKind::Closure(&Closure { body, .. }) = arg.kind; if let closure_body = cx.tcx.hir().body(body); if let &[ diff --git a/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs b/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs index 6bd5e9e88c8..21e2638e5b9 100644 --- a/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs +++ b/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs @@ -13,7 +13,7 @@ use rustc_infer::infer::TyCtxtInferExt; use rustc_lint::LateContext; use rustc_middle::mir::Mutability; use rustc_middle::ty::adjustment::{Adjust, Adjustment, OverloadedDeref}; -use rustc_middle::ty::subst::{GenericArg, GenericArgKind, SubstsRef}; +use rustc_middle::ty::{GenericArg, GenericArgKind, GenericArgsRef}; use rustc_middle::ty::{self, ClauseKind, EarlyBinder, ParamTy, ProjectionPredicate, TraitPredicate, Ty}; use rustc_span::{sym, Symbol}; use rustc_trait_selection::traits::{query::evaluate_obligation::InferCtxtExt as _, Obligation, ObligationCause}; @@ -250,8 +250,8 @@ fn check_other_call_arg<'tcx>( ) -> bool { if_chain! { if let Some((maybe_call, maybe_arg)) = skip_addr_of_ancestors(cx, expr); - if let Some((callee_def_id, _, recv, call_args)) = get_callee_substs_and_args(cx, maybe_call); - let fn_sig = cx.tcx.fn_sig(callee_def_id).subst_identity().skip_binder(); + if let Some((callee_def_id, _, recv, call_args)) = get_callee_generic_args_and_args(cx, maybe_call); + let fn_sig = cx.tcx.fn_sig(callee_def_id).instantiate_identity().skip_binder(); if let Some(i) = recv.into_iter().chain(call_args).position(|arg| arg.hir_id == maybe_arg.hir_id); if let Some(input) = fn_sig.inputs().get(i); let (input, n_refs) = peel_mid_ty_refs(*input); @@ -315,26 +315,26 @@ fn skip_addr_of_ancestors<'tcx>( } /// Checks whether an expression is a function or method call and, if so, returns its `DefId`, -/// `Substs`, and arguments. -fn get_callee_substs_and_args<'tcx>( +/// `GenericArgs`, and arguments. +fn get_callee_generic_args_and_args<'tcx>( cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>, -) -> Option<(DefId, SubstsRef<'tcx>, Option<&'tcx Expr<'tcx>>, &'tcx [Expr<'tcx>])> { +) -> Option<(DefId, GenericArgsRef<'tcx>, Option<&'tcx Expr<'tcx>>, &'tcx [Expr<'tcx>])> { if_chain! { if let ExprKind::Call(callee, args) = expr.kind; let callee_ty = cx.typeck_results().expr_ty(callee); if let ty::FnDef(callee_def_id, _) = callee_ty.kind(); then { - let substs = cx.typeck_results().node_substs(callee.hir_id); - return Some((*callee_def_id, substs, None, args)); + let generic_args = cx.typeck_results().node_args(callee.hir_id); + return Some((*callee_def_id, generic_args, None, args)); } } if_chain! { if let ExprKind::MethodCall(_, recv, args, _) = expr.kind; if let Some(method_def_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id); then { - let substs = cx.typeck_results().node_substs(expr.hir_id); - return Some((method_def_id, substs, Some(recv), args)); + let generic_args = cx.typeck_results().node_args(expr.hir_id); + return Some((method_def_id, generic_args, Some(recv), args)); } } None @@ -388,17 +388,17 @@ fn can_change_type<'a>(cx: &LateContext<'a>, mut expr: &'a Expr<'a>, mut ty: Ty< } } Node::Expr(parent_expr) => { - if let Some((callee_def_id, call_substs, recv, call_args)) = get_callee_substs_and_args(cx, parent_expr) + if let Some((callee_def_id, call_generic_args, recv, call_args)) = get_callee_generic_args_and_args(cx, parent_expr) { - // FIXME: the `subst_identity()` below seems incorrect, since we eventually + // FIXME: the `instantiate_identity()` below seems incorrect, since we eventually // call `tcx.try_subst_and_normalize_erasing_regions` further down // (i.e., we are explicitly not in the identity context). - let fn_sig = cx.tcx.fn_sig(callee_def_id).subst_identity().skip_binder(); + let fn_sig = cx.tcx.fn_sig(callee_def_id).instantiate_identity().skip_binder(); if let Some(arg_index) = recv.into_iter().chain(call_args).position(|arg| arg.hir_id == expr.hir_id) && let Some(param_ty) = fn_sig.inputs().get(arg_index) && let ty::Param(ParamTy { index: param_index , ..}) = param_ty.kind() // https://github.com/rust-lang/rust-clippy/issues/9504 and https://github.com/rust-lang/rust-clippy/issues/10021 - && (*param_index as usize) < call_substs.len() + && (*param_index as usize) < call_generic_args.len() { if fn_sig .inputs() @@ -422,8 +422,8 @@ fn can_change_type<'a>(cx: &LateContext<'a>, mut expr: &'a Expr<'a>, mut ty: Ty< } }); - let new_subst = cx.tcx.mk_substs_from_iter( - call_substs.iter() + let new_subst = cx.tcx.mk_args_from_iter( + call_generic_args.iter() .enumerate() .map(|(i, t)| if i == (*param_index as usize) { @@ -433,7 +433,7 @@ fn can_change_type<'a>(cx: &LateContext<'a>, mut expr: &'a Expr<'a>, mut ty: Ty< })); if trait_predicates.any(|predicate| { - let predicate = EarlyBinder::bind(predicate).subst(cx.tcx, new_subst); + let predicate = EarlyBinder::bind(predicate).instantiate(cx.tcx, new_subst); let obligation = Obligation::new(cx.tcx, ObligationCause::dummy(), cx.param_env, predicate); !cx.tcx.infer_ctxt().build().predicate_must_hold_modulo_regions(&obligation) }) { @@ -500,8 +500,8 @@ fn is_to_string_on_string_like<'a>( return false; } - if let Some(substs) = cx.typeck_results().node_substs_opt(call_expr.hir_id) - && let [generic_arg] = substs.as_slice() + if let Some(args) = cx.typeck_results().node_args_opt(call_expr.hir_id) + && let [generic_arg] = args.as_slice() && let GenericArgKind::Type(ty) = generic_arg.unpack() && let Some(deref_trait_id) = cx.tcx.get_diagnostic_item(sym::Deref) && let Some(as_ref_trait_id) = cx.tcx.get_diagnostic_item(sym::AsRef) diff --git a/src/tools/clippy/clippy_lints/src/methods/utils.rs b/src/tools/clippy/clippy_lints/src/methods/utils.rs index c96d6922697..9f1f73e6021 100644 --- a/src/tools/clippy/clippy_lints/src/methods/utils.rs +++ b/src/tools/clippy/clippy_lints/src/methods/utils.rs @@ -143,7 +143,7 @@ impl<'cx, 'tcx> Visitor<'tcx> for CloneOrCopyVisitor<'cx, 'tcx> { if_chain! { if args.iter().all(|arg| !self.is_binding(arg)); if let Some(method_def_id) = self.cx.typeck_results().type_dependent_def_id(parent.hir_id); - let method_ty = self.cx.tcx.type_of(method_def_id).subst_identity(); + let method_ty = self.cx.tcx.type_of(method_def_id).instantiate_identity(); let self_ty = method_ty.fn_sig(self.cx.tcx).input(0).skip_binder(); if matches!(self_ty.kind(), ty::Ref(_, _, Mutability::Not)); then { diff --git a/src/tools/clippy/clippy_lints/src/methods/vec_resize_to_zero.rs b/src/tools/clippy/clippy_lints/src/methods/vec_resize_to_zero.rs index b0cfc163fd0..73072718678 100644 --- a/src/tools/clippy/clippy_lints/src/methods/vec_resize_to_zero.rs +++ b/src/tools/clippy/clippy_lints/src/methods/vec_resize_to_zero.rs @@ -20,7 +20,7 @@ pub(super) fn check<'tcx>( if_chain! { if let Some(method_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id); if let Some(impl_id) = cx.tcx.impl_of_method(method_id); - if is_type_diagnostic_item(cx, cx.tcx.type_of(impl_id).subst_identity(), sym::Vec); + if is_type_diagnostic_item(cx, cx.tcx.type_of(impl_id).instantiate_identity(), sym::Vec); if let ExprKind::Lit(Spanned { node: LitKind::Int(0, _), .. }) = count_arg.kind; if let ExprKind::Lit(Spanned { node: LitKind::Int(..), .. }) = default_arg.kind; then { diff --git a/src/tools/clippy/clippy_lints/src/mut_key.rs b/src/tools/clippy/clippy_lints/src/mut_key.rs index 309f67521a3..5878f899541 100644 --- a/src/tools/clippy/clippy_lints/src/mut_key.rs +++ b/src/tools/clippy/clippy_lints/src/mut_key.rs @@ -139,7 +139,7 @@ impl MutableKeyType { } fn check_sig(&self, cx: &LateContext<'_>, fn_def_id: LocalDefId, decl: &hir::FnDecl<'_>) { - let fn_sig = cx.tcx.fn_sig(fn_def_id).subst_identity(); + let fn_sig = cx.tcx.fn_sig(fn_def_id).instantiate_identity(); for (hir_ty, ty) in iter::zip(decl.inputs, fn_sig.inputs().skip_binder()) { self.check_ty_(cx, hir_ty.span, *ty); } @@ -150,7 +150,7 @@ impl MutableKeyType { // generics (because the compiler cannot ensure immutability for unknown types). fn check_ty_<'tcx>(&self, cx: &LateContext<'tcx>, span: Span, ty: Ty<'tcx>) { let ty = ty.peel_refs(); - if let Adt(def, substs) = ty.kind() { + if let Adt(def, args) = ty.kind() { let is_keyed_type = [sym::HashMap, sym::BTreeMap, sym::HashSet, sym::BTreeSet] .iter() .any(|diag_item| cx.tcx.is_diagnostic_item(*diag_item, def.did())); @@ -158,7 +158,7 @@ impl MutableKeyType { return; } - let subst_ty = substs.type_at(0); + let subst_ty = args.type_at(0); // Determines if a type contains interior mutability which would affect its implementation of // [`Hash`] or [`Ord`]. if is_interior_mut_ty(cx, subst_ty) diff --git a/src/tools/clippy/clippy_lints/src/mut_reference.rs b/src/tools/clippy/clippy_lints/src/mut_reference.rs index e91aac41bc4..4b20aecad4a 100644 --- a/src/tools/clippy/clippy_lints/src/mut_reference.rs +++ b/src/tools/clippy/clippy_lints/src/mut_reference.rs @@ -51,8 +51,8 @@ impl<'tcx> LateLintPass<'tcx> for UnnecessaryMutPassed { }, ExprKind::MethodCall(path, receiver, arguments, _) => { let def_id = cx.typeck_results().type_dependent_def_id(e.hir_id).unwrap(); - let substs = cx.typeck_results().node_substs(e.hir_id); - let method_type = cx.tcx.type_of(def_id).subst(cx.tcx, substs); + let args = cx.typeck_results().node_args(e.hir_id); + let method_type = cx.tcx.type_of(def_id).instantiate(cx.tcx, args); check_arguments( cx, std::iter::once(receiver).chain(arguments.iter()).collect(), diff --git a/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs b/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs index f11d5773d04..55b6e1606ee 100644 --- a/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs +++ b/src/tools/clippy/clippy_lints/src/needless_pass_by_value.rs @@ -140,7 +140,7 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByValue { ctx }; - let fn_sig = cx.tcx.fn_sig(fn_def_id).subst_identity(); + let fn_sig = cx.tcx.fn_sig(fn_def_id).instantiate_identity(); let fn_sig = cx.tcx.liberate_late_bound_regions(fn_def_id.to_def_id(), fn_sig); for (idx, ((input, &ty), arg)) in decl.inputs.iter().zip(fn_sig.inputs()).zip(body.params).enumerate() { @@ -170,7 +170,7 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByValue { !preds.is_empty() && { let ty_empty_region = Ty::new_imm_ref(cx.tcx,cx.tcx.lifetimes.re_erased, ty); preds.iter().all(|t| { - let ty_params = t.trait_ref.substs.iter().skip(1).collect::<Vec<_>>(); + let ty_params = t.trait_ref.args.iter().skip(1).collect::<Vec<_>>(); implements_trait(cx, ty_empty_region, t.def_id(), &ty_params) }) }, diff --git a/src/tools/clippy/clippy_lints/src/new_without_default.rs b/src/tools/clippy/clippy_lints/src/new_without_default.rs index 653b1a8a05f..cf7cd671dca 100644 --- a/src/tools/clippy/clippy_lints/src/new_without_default.rs +++ b/src/tools/clippy/clippy_lints/src/new_without_default.rs @@ -98,14 +98,14 @@ impl<'tcx> LateLintPass<'tcx> for NewWithoutDefault { if name == sym::new; if cx.effective_visibilities.is_reachable(impl_item.owner_id.def_id); let self_def_id = cx.tcx.hir().get_parent_item(id.into()); - let self_ty = cx.tcx.type_of(self_def_id).subst_identity(); + let self_ty = cx.tcx.type_of(self_def_id).instantiate_identity(); if self_ty == return_ty(cx, id); if let Some(default_trait_id) = cx.tcx.get_diagnostic_item(sym::Default); then { if self.impling_types.is_none() { let mut impls = HirIdSet::default(); cx.tcx.for_each_impl(default_trait_id, |d| { - let ty = cx.tcx.type_of(d).subst_identity(); + let ty = cx.tcx.type_of(d).instantiate_identity(); if let Some(ty_def) = ty.ty_adt_def() { if let Some(local_def_id) = ty_def.did().as_local() { impls.insert(cx.tcx.hir().local_def_id_to_hir_id(local_def_id)); @@ -119,7 +119,7 @@ impl<'tcx> LateLintPass<'tcx> for NewWithoutDefault { // generics if_chain! { if let Some(ref impling_types) = self.impling_types; - let self_def = cx.tcx.type_of(self_def_id).subst_identity(); + let self_def = cx.tcx.type_of(self_def_id).instantiate_identity(); if let Some(self_def) = self_def.ty_adt_def(); if let Some(self_local_did) = self_def.did().as_local(); let self_id = cx.tcx.hir().local_def_id_to_hir_id(self_local_did); diff --git a/src/tools/clippy/clippy_lints/src/non_copy_const.rs b/src/tools/clippy/clippy_lints/src/non_copy_const.rs index 75f1e95276a..12d4f33d428 100644 --- a/src/tools/clippy/clippy_lints/src/non_copy_const.rs +++ b/src/tools/clippy/clippy_lints/src/non_copy_const.rs @@ -158,7 +158,7 @@ fn is_value_unfrozen_raw<'tcx>( val.unwrap_branch().iter().any(|field| inner(cx, *field, ty)) }, ty::Adt(def, _) if def.is_union() => false, - ty::Adt(def, substs) if def.is_enum() => { + ty::Adt(def, args) if def.is_enum() => { let (&variant_index, fields) = val.unwrap_branch().split_first().unwrap(); let variant_index = VariantIdx::from_u32(variant_index.unwrap_leaf().try_to_u32().ok().unwrap()); @@ -166,10 +166,10 @@ fn is_value_unfrozen_raw<'tcx>( def.variants()[variant_index] .fields .iter() - .map(|field| field.ty(cx.tcx, substs))).any(|(field, ty)| inner(cx, field, ty)) + .map(|field| field.ty(cx.tcx, args))).any(|(field, ty)| inner(cx, field, ty)) } - ty::Adt(def, substs) => { - val.unwrap_branch().iter().zip(def.non_enum_variant().fields.iter().map(|field| field.ty(cx.tcx, substs))).any(|(field, ty)| inner(cx, *field, ty)) + ty::Adt(def, args) => { + val.unwrap_branch().iter().zip(def.non_enum_variant().fields.iter().map(|field| field.ty(cx.tcx, args))).any(|(field, ty)| inner(cx, *field, ty)) } ty::Tuple(tys) => val.unwrap_branch().iter().zip(tys).any(|(field, ty)| inner(cx, *field, ty)), _ => false, @@ -206,8 +206,8 @@ fn is_value_unfrozen_raw<'tcx>( fn is_value_unfrozen_poly<'tcx>(cx: &LateContext<'tcx>, body_id: BodyId, ty: Ty<'tcx>) -> bool { let def_id = body_id.hir_id.owner.to_def_id(); - let substs = ty::InternalSubsts::identity_for_item(cx.tcx, def_id); - let instance = ty::Instance::new(def_id, substs); + let args = ty::GenericArgs::identity_for_item(cx.tcx, def_id); + let instance = ty::Instance::new(def_id, args); let cid = rustc_middle::mir::interpret::GlobalId { instance, promoted: None }; let param_env = cx.tcx.param_env(def_id).with_reveal_all_normalized(cx.tcx); let result = cx.tcx.const_eval_global_id_for_typeck(param_env, cid, None); @@ -215,9 +215,9 @@ fn is_value_unfrozen_poly<'tcx>(cx: &LateContext<'tcx>, body_id: BodyId, ty: Ty< } fn is_value_unfrozen_expr<'tcx>(cx: &LateContext<'tcx>, hir_id: HirId, def_id: DefId, ty: Ty<'tcx>) -> bool { - let substs = cx.typeck_results().node_substs(hir_id); + let args = cx.typeck_results().node_args(hir_id); - let result = const_eval_resolve(cx.tcx, cx.param_env, ty::UnevaluatedConst::new(def_id, substs), None); + let result = const_eval_resolve(cx.tcx, cx.param_env, ty::UnevaluatedConst::new(def_id, args), None); is_value_unfrozen_raw(cx, result, ty) } @@ -228,7 +228,7 @@ pub fn const_eval_resolve<'tcx>( ct: ty::UnevaluatedConst<'tcx>, span: Option<Span>, ) -> EvalToValTreeResult<'tcx> { - match ty::Instance::resolve(tcx, param_env, ct.def, ct.substs) { + match ty::Instance::resolve(tcx, param_env, ct.def, ct.args) { Ok(Some(instance)) => { let cid = GlobalId { instance, promoted: None }; tcx.const_eval_global_id_for_typeck(param_env, cid, span) @@ -347,7 +347,7 @@ impl<'tcx> LateLintPass<'tcx> for NonCopyConst { // and, in that case, the definition is *not* generic. cx.tcx.normalize_erasing_regions( cx.tcx.param_env(of_trait_def_id), - cx.tcx.type_of(of_assoc_item).subst_identity(), + cx.tcx.type_of(of_assoc_item).instantiate_identity(), ), )) .is_err(); diff --git a/src/tools/clippy/clippy_lints/src/non_send_fields_in_send_ty.rs b/src/tools/clippy/clippy_lints/src/non_send_fields_in_send_ty.rs index 7eaa7db78a4..c5e777c2070 100644 --- a/src/tools/clippy/clippy_lints/src/non_send_fields_in_send_ty.rs +++ b/src/tools/clippy/clippy_lints/src/non_send_fields_in_send_ty.rs @@ -7,7 +7,7 @@ use rustc_hir::def_id::DefId; use rustc_hir::{FieldDef, Item, ItemKind, Node}; use rustc_lint::{LateContext, LateLintPass}; use rustc_middle::lint::in_external_macro; -use rustc_middle::ty::{self, subst::GenericArgKind, Ty}; +use rustc_middle::ty::{self, GenericArgKind, Ty}; use rustc_session::{declare_tool_lint, impl_lint_pass}; use rustc_span::sym; @@ -90,8 +90,8 @@ impl<'tcx> LateLintPass<'tcx> for NonSendFieldInSendTy { if send_trait == trait_id; if hir_impl.polarity == ImplPolarity::Positive; if let Some(ty_trait_ref) = cx.tcx.impl_trait_ref(item.owner_id); - if let self_ty = ty_trait_ref.subst_identity().self_ty(); - if let ty::Adt(adt_def, impl_trait_substs) = self_ty.kind(); + if let self_ty = ty_trait_ref.instantiate_identity().self_ty(); + if let ty::Adt(adt_def, impl_trait_args) = self_ty.kind(); then { let mut non_send_fields = Vec::new(); @@ -104,7 +104,7 @@ impl<'tcx> LateLintPass<'tcx> for NonSendFieldInSendTy { .as_local() .map(|local_def_id| hir_map.local_def_id_to_hir_id(local_def_id)); if !is_lint_allowed(cx, NON_SEND_FIELDS_IN_SEND_TY, field_hir_id); - if let field_ty = field.ty(cx.tcx, impl_trait_substs); + if let field_ty = field.ty(cx.tcx, impl_trait_args); if !ty_allowed_in_send(cx, field_ty, send_trait); if let Node::Field(field_def) = hir_map.get(field_hir_id); then { @@ -206,10 +206,10 @@ fn ty_allowed_with_raw_pointer_heuristic<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'t .iter() .all(|ty| ty_allowed_with_raw_pointer_heuristic(cx, ty, send_trait)), ty::Array(ty, _) | ty::Slice(ty) => ty_allowed_with_raw_pointer_heuristic(cx, *ty, send_trait), - ty::Adt(_, substs) => { + ty::Adt(_, args) => { if contains_pointer_like(cx, ty) { // descends only if ADT contains any raw pointers - substs.iter().all(|generic_arg| match generic_arg.unpack() { + args.iter().all(|generic_arg| match generic_arg.unpack() { GenericArgKind::Type(ty) => ty_allowed_with_raw_pointer_heuristic(cx, ty, send_trait), // Lifetimes and const generics are not solid part of ADT and ignored GenericArgKind::Lifetime(_) | GenericArgKind::Const(_) => true, @@ -224,7 +224,7 @@ fn ty_allowed_with_raw_pointer_heuristic<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'t } } -/// Checks if the type contains any pointer-like types in substs (including nested ones) +/// Checks if the type contains any pointer-like types in args (including nested ones) fn contains_pointer_like<'tcx>(cx: &LateContext<'tcx>, target_ty: Ty<'tcx>) -> bool { for ty_node in target_ty.walk() { if let GenericArgKind::Type(inner_ty) = ty_node.unpack() { diff --git a/src/tools/clippy/clippy_lints/src/only_used_in_recursion.rs b/src/tools/clippy/clippy_lints/src/only_used_in_recursion.rs index 8b77a5c99f7..3615c7ec9bf 100644 --- a/src/tools/clippy/clippy_lints/src/only_used_in_recursion.rs +++ b/src/tools/clippy/clippy_lints/src/only_used_in_recursion.rs @@ -7,7 +7,7 @@ use rustc_hir::def_id::DefId; use rustc_hir::hir_id::HirIdMap; use rustc_hir::{Body, Expr, ExprKind, HirId, ImplItem, ImplItemKind, Node, PatKind, TraitItem, TraitItemKind}; use rustc_lint::{LateContext, LateLintPass}; -use rustc_middle::ty::subst::{EarlyBinder, GenericArgKind, SubstsRef}; +use rustc_middle::ty::{EarlyBinder, GenericArgKind, GenericArgsRef}; use rustc_middle::ty::{self, ConstKind}; use rustc_session::{declare_tool_lint, impl_lint_pass}; use rustc_span::symbol::{kw, Ident}; @@ -90,7 +90,7 @@ impl_lint_pass!(OnlyUsedInRecursion => [ONLY_USED_IN_RECURSION]); enum FnKind { Fn, TraitFn, - // This is a hack. Ideally we would store a `SubstsRef<'tcx>` type here, but a lint pass must be `'static`. + // This is a hack. Ideally we would store a `GenericArgsRef<'tcx>` type here, but a lint pass must be `'static`. // Substitutions are, however, interned. This allows us to store the pointer as a `usize` when comparing for // equality. ImplTraitFn(usize), @@ -244,12 +244,12 @@ impl<'tcx> LateLintPass<'tcx> for OnlyUsedInRecursion { })) => { #[allow(trivial_casts)] if let Some(Node::Item(item)) = get_parent_node(cx.tcx, owner_id.into()) - && let Some(trait_ref) = cx.tcx.impl_trait_ref(item.owner_id).map(EarlyBinder::subst_identity) + && let Some(trait_ref) = cx.tcx.impl_trait_ref(item.owner_id).map(EarlyBinder::instantiate_identity) && let Some(trait_item_id) = cx.tcx.associated_item(owner_id).trait_item_def_id { ( trait_item_id, - FnKind::ImplTraitFn(cx.tcx.erase_regions(trait_ref.substs) as *const _ as usize), + FnKind::ImplTraitFn(cx.tcx.erase_regions(trait_ref.args) as *const _ as usize), usize::from(sig.decl.implicit_self.has_implicit_self()), ) } else { @@ -289,7 +289,7 @@ impl<'tcx> LateLintPass<'tcx> for OnlyUsedInRecursion { ExprKind::Call(callee, args) if path_def_id(cx, callee).map_or(false, |id| { id == param.fn_id - && has_matching_substs(param.fn_kind, typeck.node_substs(callee.hir_id)) + && has_matching_args(param.fn_kind, typeck.node_args(callee.hir_id)) }) => { if let Some(idx) = args.iter().position(|arg| arg.hir_id == child_id) { @@ -300,7 +300,7 @@ impl<'tcx> LateLintPass<'tcx> for OnlyUsedInRecursion { ExprKind::MethodCall(_, receiver, args, _) if typeck.type_dependent_def_id(parent.hir_id).map_or(false, |id| { id == param.fn_id - && has_matching_substs(param.fn_kind, typeck.node_substs(parent.hir_id)) + && has_matching_args(param.fn_kind, typeck.node_args(parent.hir_id)) }) => { if let Some(idx) = iter::once(receiver).chain(args).position(|arg| arg.hir_id == child_id) { @@ -381,15 +381,15 @@ impl<'tcx> LateLintPass<'tcx> for OnlyUsedInRecursion { } } -fn has_matching_substs(kind: FnKind, substs: SubstsRef<'_>) -> bool { +fn has_matching_args(kind: FnKind, args: GenericArgsRef<'_>) -> bool { match kind { FnKind::Fn => true, - FnKind::TraitFn => substs.iter().enumerate().all(|(idx, subst)| match subst.unpack() { + FnKind::TraitFn => args.iter().enumerate().all(|(idx, subst)| match subst.unpack() { GenericArgKind::Lifetime(_) => true, GenericArgKind::Type(ty) => matches!(*ty.kind(), ty::Param(ty) if ty.index as usize == idx), GenericArgKind::Const(c) => matches!(c.kind(), ConstKind::Param(c) if c.index as usize == idx), }), #[allow(trivial_casts)] - FnKind::ImplTraitFn(expected_substs) => substs as *const _ as usize == expected_substs, + FnKind::ImplTraitFn(expected_args) => args as *const _ as usize == expected_args, } } diff --git a/src/tools/clippy/clippy_lints/src/pass_by_ref_or_value.rs b/src/tools/clippy/clippy_lints/src/pass_by_ref_or_value.rs index eab725de17f..7b4812e98d8 100644 --- a/src/tools/clippy/clippy_lints/src/pass_by_ref_or_value.rs +++ b/src/tools/clippy/clippy_lints/src/pass_by_ref_or_value.rs @@ -143,7 +143,7 @@ impl<'tcx> PassByRefOrValue { return; } - let fn_sig = cx.tcx.fn_sig(def_id).subst_identity(); + let fn_sig = cx.tcx.fn_sig(def_id).instantiate_identity(); let fn_body = cx.enclosing_body.map(|id| cx.tcx.hir().body(id)); // Gather all the lifetimes found in the output type which may affect whether diff --git a/src/tools/clippy/clippy_lints/src/ptr.rs b/src/tools/clippy/clippy_lints/src/ptr.rs index 32213718b27..eb7c008c7a4 100644 --- a/src/tools/clippy/clippy_lints/src/ptr.rs +++ b/src/tools/clippy/clippy_lints/src/ptr.rs @@ -166,7 +166,7 @@ impl<'tcx> LateLintPass<'tcx> for Ptr { check_mut_from_ref(cx, sig, None); for arg in check_fn_args( cx, - cx.tcx.fn_sig(item.owner_id).subst_identity().skip_binder().inputs(), + cx.tcx.fn_sig(item.owner_id).instantiate_identity().skip_binder().inputs(), sig.decl.inputs, &sig.decl.output, &[], @@ -220,7 +220,7 @@ impl<'tcx> LateLintPass<'tcx> for Ptr { check_mut_from_ref(cx, sig, Some(body)); let decl = sig.decl; - let sig = cx.tcx.fn_sig(item_id).subst_identity().skip_binder(); + let sig = cx.tcx.fn_sig(item_id).instantiate_identity().skip_binder(); let lint_args: Vec<_> = check_fn_args(cx, sig.inputs(), decl.inputs, &decl.output, body.params) .filter(|arg| !is_trait_item || arg.mutability() == Mutability::Not) .collect(); @@ -423,7 +423,7 @@ fn check_fn_args<'cx, 'tcx: 'cx>( .enumerate() .filter_map(move |(i, (ty, hir_ty))| { if let ty::Ref(_, ty, mutability) = *ty.kind() - && let ty::Adt(adt, substs) = *ty.kind() + && let ty::Adt(adt, args) = *ty.kind() && let TyKind::Ref(lt, ref ty) = hir_ty.kind && let TyKind::Path(QPath::Resolved(None, path)) = ty.ty.kind // Check that the name as typed matches the actual name of the type. @@ -443,7 +443,7 @@ fn check_fn_args<'cx, 'tcx: 'cx>( } else { None }), - substs.type_at(0), + args.type_at(0), ), ), _ if Some(adt.did()) == cx.tcx.lang_items().string() => ( @@ -496,7 +496,7 @@ fn check_fn_args<'cx, 'tcx: 'cx>( } let ty_name = - snippet_opt(cx, ty.span()).unwrap_or_else(|| substs.type_at(1).to_string()); + snippet_opt(cx, ty.span()).unwrap_or_else(|| args.type_at(1).to_string()); span_lint_hir_and_then( cx, @@ -659,7 +659,7 @@ fn check_ptr_arg_usage<'tcx>(cx: &LateContext<'tcx>, body: &'tcx Body<'_>, args: return; }; - match *self.cx.tcx.fn_sig(id).subst_identity().skip_binder().inputs()[i] + match *self.cx.tcx.fn_sig(id).instantiate_identity().skip_binder().inputs()[i] .peel_refs() .kind() { @@ -725,7 +725,7 @@ fn matches_preds<'tcx>( let infcx = cx.tcx.infer_ctxt().build(); preds.iter().all(|&p| match cx.tcx.erase_late_bound_regions(p) { ExistentialPredicate::Trait(p) => infcx - .type_implements_trait(p.def_id, [ty.into()].into_iter().chain(p.substs.iter()), cx.param_env) + .type_implements_trait(p.def_id, [ty.into()].into_iter().chain(p.args.iter()), cx.param_env) .must_apply_modulo_regions(), ExistentialPredicate::Projection(p) => infcx.predicate_must_hold_modulo_regions(&Obligation::new( cx.tcx, diff --git a/src/tools/clippy/clippy_lints/src/redundant_slicing.rs b/src/tools/clippy/clippy_lints/src/redundant_slicing.rs index c70ce83a9c4..2b65c08d25d 100644 --- a/src/tools/clippy/clippy_lints/src/redundant_slicing.rs +++ b/src/tools/clippy/clippy_lints/src/redundant_slicing.rs @@ -9,7 +9,7 @@ use rustc_hir::{BorrowKind, Expr, ExprKind, LangItem, Mutability}; use rustc_lint::{LateContext, LateLintPass, Lint}; use rustc_middle::ty::Ty; use rustc_middle::ty::adjustment::{Adjust, AutoBorrow, AutoBorrowMutability}; -use rustc_middle::ty::subst::GenericArg; +use rustc_middle::ty::GenericArg; use rustc_session::{declare_lint_pass, declare_tool_lint}; declare_clippy_lint! { @@ -135,7 +135,7 @@ impl<'tcx> LateLintPass<'tcx> for RedundantSlicing { } else if let Some(target_id) = cx.tcx.lang_items().deref_target() { if let Ok(deref_ty) = cx.tcx.try_normalize_erasing_regions( cx.param_env, - Ty::new_projection(cx.tcx,target_id, cx.tcx.mk_substs(&[GenericArg::from(indexed_ty)])), + Ty::new_projection(cx.tcx,target_id, cx.tcx.mk_args(&[GenericArg::from(indexed_ty)])), ) { if deref_ty == expr_ty { let snip = snippet_with_context(cx, indexed.span, ctxt, "..", &mut app).0; diff --git a/src/tools/clippy/clippy_lints/src/returns.rs b/src/tools/clippy/clippy_lints/src/returns.rs index 958351ad81b..4977df6c83f 100644 --- a/src/tools/clippy/clippy_lints/src/returns.rs +++ b/src/tools/clippy/clippy_lints/src/returns.rs @@ -9,7 +9,7 @@ use rustc_hir::intravisit::FnKind; use rustc_hir::{Block, Body, Expr, ExprKind, FnDecl, LangItem, MatchSource, PatKind, QPath, StmtKind}; use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_middle::lint::in_external_macro; -use rustc_middle::ty::{self, subst::GenericArgKind, Ty}; +use rustc_middle::ty::{self, GenericArgKind, Ty}; use rustc_session::{declare_lint_pass, declare_tool_lint}; use rustc_span::def_id::LocalDefId; use rustc_span::source_map::Span; @@ -333,7 +333,7 @@ fn last_statement_borrows<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) && cx .tcx .fn_sig(def_id) - .subst_identity() + .instantiate_identity() .skip_binder() .output() .walk() diff --git a/src/tools/clippy/clippy_lints/src/self_named_constructors.rs b/src/tools/clippy/clippy_lints/src/self_named_constructors.rs index beca203c868..b92014f68b3 100644 --- a/src/tools/clippy/clippy_lints/src/self_named_constructors.rs +++ b/src/tools/clippy/clippy_lints/src/self_named_constructors.rs @@ -53,7 +53,7 @@ impl<'tcx> LateLintPass<'tcx> for SelfNamedConstructors { let parent = cx.tcx.hir().get_parent_item(impl_item.hir_id()).def_id; let item = cx.tcx.hir().expect_item(parent); - let self_ty = cx.tcx.type_of(item.owner_id).subst_identity(); + let self_ty = cx.tcx.type_of(item.owner_id).instantiate_identity(); let ret_ty = return_ty(cx, impl_item.owner_id); // Do not check trait impls diff --git a/src/tools/clippy/clippy_lints/src/significant_drop_tightening.rs b/src/tools/clippy/clippy_lints/src/significant_drop_tightening.rs index fffa8a380c2..1493ad44ee5 100644 --- a/src/tools/clippy/clippy_lints/src/significant_drop_tightening.rs +++ b/src/tools/clippy/clippy_lints/src/significant_drop_tightening.rs @@ -10,7 +10,7 @@ use rustc_hir::{ intravisit::{walk_expr, Visitor}, }; use rustc_lint::{LateContext, LateLintPass, LintContext}; -use rustc_middle::ty::{subst::GenericArgKind, Ty, TypeAndMut}; +use rustc_middle::ty::{GenericArgKind, Ty, TypeAndMut}; use rustc_session::{declare_tool_lint, impl_lint_pass}; use rustc_span::{symbol::Ident, Span, DUMMY_SP}; use std::borrow::Cow; diff --git a/src/tools/clippy/clippy_lints/src/size_of_in_element_count.rs b/src/tools/clippy/clippy_lints/src/size_of_in_element_count.rs index ac4e29e9dfd..80c834066bb 100644 --- a/src/tools/clippy/clippy_lints/src/size_of_in_element_count.rs +++ b/src/tools/clippy/clippy_lints/src/size_of_in_element_count.rs @@ -47,7 +47,7 @@ fn get_size_of_ty<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, inverted: if let Some(def_id) = cx.qpath_res(count_func_qpath, count_func.hir_id).opt_def_id(); if matches!(cx.tcx.get_diagnostic_name(def_id), Some(sym::mem_size_of | sym::mem_size_of_val)); then { - cx.typeck_results().node_substs(count_func.hir_id).types().next() + cx.typeck_results().node_args(count_func.hir_id).types().next() } else { None } @@ -101,7 +101,7 @@ fn get_pointee_ty_and_count_expr<'tcx>( if FUNCTIONS.iter().any(|func_path| match_def_path(cx, def_id, func_path)); // Get the pointee type - if let Some(pointee_ty) = cx.typeck_results().node_substs(func.hir_id).types().next(); + if let Some(pointee_ty) = cx.typeck_results().node_args(func.hir_id).types().next(); then { return Some((pointee_ty, count)); } diff --git a/src/tools/clippy/clippy_lints/src/transmute/transmute_undefined_repr.rs b/src/tools/clippy/clippy_lints/src/transmute/transmute_undefined_repr.rs index 5e24213d07f..9e5d7662426 100644 --- a/src/tools/clippy/clippy_lints/src/transmute/transmute_undefined_repr.rs +++ b/src/tools/clippy/clippy_lints/src/transmute/transmute_undefined_repr.rs @@ -3,7 +3,7 @@ use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::ty::is_c_void; use rustc_hir::Expr; use rustc_lint::LateContext; -use rustc_middle::ty::SubstsRef; +use rustc_middle::ty::GenericArgsRef; use rustc_middle::ty::{self, IntTy, Ty, TypeAndMut, UintTy}; #[expect(clippy::too_many_lines)] @@ -268,12 +268,12 @@ fn reduce_ty<'tcx>(cx: &LateContext<'tcx>, mut ty: Ty<'tcx>) -> ReducedTy<'tcx> } ReducedTy::UnorderedFields(ty) }, - ty::Adt(def, substs) if def.is_struct() => { + ty::Adt(def, args) if def.is_struct() => { let mut iter = def .non_enum_variant() .fields .iter() - .map(|f| cx.tcx.type_of(f.did).subst(cx.tcx, substs)); + .map(|f| cx.tcx.type_of(f.did).instantiate(cx.tcx, args)); let Some(sized_ty) = iter.find(|&ty| !is_zero_sized_ty(cx, ty)) else { return ReducedTy::TypeErasure { raw_ptr_only: false }; }; @@ -322,7 +322,7 @@ fn is_size_pair(ty: Ty<'_>) -> bool { } } -fn same_except_params<'tcx>(subs1: SubstsRef<'tcx>, subs2: SubstsRef<'tcx>) -> bool { +fn same_except_params<'tcx>(subs1: GenericArgsRef<'tcx>, subs2: GenericArgsRef<'tcx>) -> bool { // TODO: check const parameters as well. Currently this will consider `Array<5>` the same as // `Array<6>` for (ty1, ty2) in subs1.types().zip(subs2.types()).filter(|(ty1, ty2)| ty1 != ty2) { diff --git a/src/tools/clippy/clippy_lints/src/transmute/unsound_collection_transmute.rs b/src/tools/clippy/clippy_lints/src/transmute/unsound_collection_transmute.rs index b1445311b71..891fefc17a6 100644 --- a/src/tools/clippy/clippy_lints/src/transmute/unsound_collection_transmute.rs +++ b/src/tools/clippy/clippy_lints/src/transmute/unsound_collection_transmute.rs @@ -10,7 +10,7 @@ use rustc_span::symbol::sym; /// Returns `true` if it's triggered, otherwise returns `false`. pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>, from_ty: Ty<'tcx>, to_ty: Ty<'tcx>) -> bool { match (&from_ty.kind(), &to_ty.kind()) { - (ty::Adt(from_adt, from_substs), ty::Adt(to_adt, to_substs)) => { + (ty::Adt(from_adt, from_args), ty::Adt(to_adt, to_args)) => { if from_adt.did() != to_adt.did() { return false; } @@ -28,9 +28,9 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>, from_ty: Ty ) { return false; } - if from_substs + if from_args .types() - .zip(to_substs.types()) + .zip(to_args.types()) .any(|(from_ty, to_ty)| is_layout_incompatible(cx, from_ty, to_ty)) { span_lint( diff --git a/src/tools/clippy/clippy_lints/src/uninit_vec.rs b/src/tools/clippy/clippy_lints/src/uninit_vec.rs index 1ab0162a881..6756df8e716 100644 --- a/src/tools/clippy/clippy_lints/src/uninit_vec.rs +++ b/src/tools/clippy/clippy_lints/src/uninit_vec.rs @@ -88,7 +88,7 @@ fn handle_uninit_vec_pair<'tcx>( if let Some((set_len_self, call_span)) = extract_set_len_self(cx, maybe_set_len); if vec.location.eq_expr(cx, set_len_self); if let ty::Ref(_, vec_ty, _) = cx.typeck_results().expr_ty_adjusted(set_len_self).kind(); - if let ty::Adt(_, substs) = vec_ty.kind(); + if let ty::Adt(_, args) = vec_ty.kind(); // `#[allow(...)]` attribute can be set on enclosing unsafe block of `set_len()` if !is_lint_allowed(cx, UNINIT_VEC, maybe_set_len.hir_id); then { @@ -96,7 +96,7 @@ fn handle_uninit_vec_pair<'tcx>( // with_capacity / reserve -> set_len // Check T of Vec<T> - if !is_uninit_value_valid_for_ty(cx, substs.type_at(0)) { + if !is_uninit_value_valid_for_ty(cx, args.type_at(0)) { // FIXME: #7698, false positive of the internal lints #[expect(clippy::collapsible_span_lint_calls)] span_lint_and_then( diff --git a/src/tools/clippy/clippy_lints/src/unit_return_expecting_ord.rs b/src/tools/clippy/clippy_lints/src/unit_return_expecting_ord.rs index 99a1d197678..dd829ded0d0 100644 --- a/src/tools/clippy/clippy_lints/src/unit_return_expecting_ord.rs +++ b/src/tools/clippy/clippy_lints/src/unit_return_expecting_ord.rs @@ -65,7 +65,7 @@ fn get_projection_pred<'tcx>( generics.predicates.iter().find_map(|(proj_pred, _)| { if let ClauseKind::Projection(pred) = proj_pred.kind().skip_binder() { let projection_pred = cx.tcx.erase_late_bound_regions(proj_pred.kind().rebind(pred)); - if projection_pred.projection_ty.substs == trait_pred.trait_ref.substs { + if projection_pred.projection_ty.args == trait_pred.trait_ref.args { return Some(projection_pred); } } @@ -76,7 +76,7 @@ fn get_projection_pred<'tcx>( fn get_args_to_check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) -> Vec<(usize, String)> { let mut args_to_check = Vec::new(); if let Some(def_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id) { - let fn_sig = cx.tcx.fn_sig(def_id).subst_identity(); + let fn_sig = cx.tcx.fn_sig(def_id).instantiate_identity(); let generics = cx.tcx.predicates_of(def_id); let fn_mut_preds = get_trait_predicates_for_trait_id(cx, generics, cx.tcx.lang_items().fn_mut_trait()); let ord_preds = get_trait_predicates_for_trait_id(cx, generics, cx.tcx.get_diagnostic_item(sym::Ord)); @@ -120,8 +120,8 @@ fn get_args_to_check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) -> Ve fn check_arg<'tcx>(cx: &LateContext<'tcx>, arg: &'tcx Expr<'tcx>) -> Option<(Span, Option<Span>)> { if_chain! { if let ExprKind::Closure(&Closure { body, fn_decl_span, .. }) = arg.kind; - if let ty::Closure(_def_id, substs) = &cx.typeck_results().node_type(arg.hir_id).kind(); - let ret_ty = substs.as_closure().sig().output(); + if let ty::Closure(_def_id, args) = &cx.typeck_results().node_type(arg.hir_id).kind(); + let ret_ty = args.as_closure().sig().output(); let ty = cx.tcx.erase_late_bound_regions(ret_ty); if ty.is_unit(); then { diff --git a/src/tools/clippy/clippy_lints/src/unit_types/let_unit_value.rs b/src/tools/clippy/clippy_lints/src/unit_types/let_unit_value.rs index cc7c2b039f2..704d7abd7e5 100644 --- a/src/tools/clippy/clippy_lints/src/unit_types/let_unit_value.rs +++ b/src/tools/clippy/clippy_lints/src/unit_types/let_unit_value.rs @@ -161,7 +161,7 @@ fn needs_inferred_result_ty( }, _ => return false, }; - let sig = cx.tcx.fn_sig(id).subst_identity().skip_binder(); + let sig = cx.tcx.fn_sig(id).instantiate_identity().skip_binder(); if let ty::Param(output_ty) = *sig.output().kind() { let args: Vec<&Expr<'_>> = if let Some(receiver) = receiver { std::iter::once(receiver).chain(args.iter()).collect() diff --git a/src/tools/clippy/clippy_lints/src/unnamed_address.rs b/src/tools/clippy/clippy_lints/src/unnamed_address.rs index 0f5cdb6aaea..dea8a1e35bb 100644 --- a/src/tools/clippy/clippy_lints/src/unnamed_address.rs +++ b/src/tools/clippy/clippy_lints/src/unnamed_address.rs @@ -97,7 +97,7 @@ impl LateLintPass<'_> for UnnamedAddress { if let ExprKind::Path(ref func_qpath) = func.kind; if let Some(def_id) = cx.qpath_res(func_qpath, func.hir_id).opt_def_id(); if match_def_path(cx, def_id, &paths::PTR_EQ); - let ty_param = cx.typeck_results().node_substs(func.hir_id).type_at(0); + let ty_param = cx.typeck_results().node_args(func.hir_id).type_at(0); if ty_param.is_trait(); then { span_lint_and_help( diff --git a/src/tools/clippy/clippy_lints/src/use_self.rs b/src/tools/clippy/clippy_lints/src/use_self.rs index 5a02987453c..81dc426b389 100644 --- a/src/tools/clippy/clippy_lints/src/use_self.rs +++ b/src/tools/clippy/clippy_lints/src/use_self.rs @@ -145,7 +145,7 @@ impl<'tcx> LateLintPass<'tcx> for UseSelf { then { // `self_ty` is the semantic self type of `impl <trait> for <type>`. This cannot be // `Self`. - let self_ty = impl_trait_ref.subst_identity().self_ty(); + let self_ty = impl_trait_ref.instantiate_identity().self_ty(); // `trait_method_sig` is the signature of the function, how it is declared in the // trait, not in the impl of the trait. @@ -154,7 +154,7 @@ impl<'tcx> LateLintPass<'tcx> for UseSelf { .associated_item(impl_item.owner_id) .trait_item_def_id .expect("impl method matches a trait method"); - let trait_method_sig = cx.tcx.fn_sig(trait_method).subst_identity(); + let trait_method_sig = cx.tcx.fn_sig(trait_method).instantiate_identity(); let trait_method_sig = cx.tcx.erase_late_bound_regions(trait_method_sig); // `impl_inputs_outputs` is an iterator over the types (`hir::Ty`) declared in the @@ -226,7 +226,7 @@ impl<'tcx> LateLintPass<'tcx> for UseSelf { } else { hir_ty_to_ty(cx.tcx, hir_ty) }; - if same_type_and_consts(ty, cx.tcx.type_of(impl_id).subst_identity()); + if same_type_and_consts(ty, cx.tcx.type_of(impl_id).instantiate_identity()); then { span_lint(cx, hir_ty.span); } @@ -238,7 +238,7 @@ impl<'tcx> LateLintPass<'tcx> for UseSelf { if !expr.span.from_expansion(); if self.msrv.meets(msrvs::TYPE_ALIAS_ENUM_VARIANTS); if let Some(&StackItem::Check { impl_id, .. }) = self.stack.last(); - if cx.typeck_results().expr_ty(expr) == cx.tcx.type_of(impl_id).subst_identity(); + if cx.typeck_results().expr_ty(expr) == cx.tcx.type_of(impl_id).instantiate_identity(); then {} else { return; } } match expr.kind { @@ -262,7 +262,7 @@ impl<'tcx> LateLintPass<'tcx> for UseSelf { if let PatKind::Path(QPath::Resolved(_, path)) | PatKind::TupleStruct(QPath::Resolved(_, path), _, _) | PatKind::Struct(QPath::Resolved(_, path), _, _) = pat.kind; - if cx.typeck_results().pat_ty(pat) == cx.tcx.type_of(impl_id).subst_identity(); + if cx.typeck_results().pat_ty(pat) == cx.tcx.type_of(impl_id).instantiate_identity(); then { check_path(cx, path); } diff --git a/src/tools/clippy/clippy_lints/src/useless_conversion.rs b/src/tools/clippy/clippy_lints/src/useless_conversion.rs index b6c11cfb355..98f7bfb4ba1 100644 --- a/src/tools/clippy/clippy_lints/src/useless_conversion.rs +++ b/src/tools/clippy/clippy_lints/src/useless_conversion.rs @@ -227,8 +227,8 @@ impl<'tcx> LateLintPass<'tcx> for UselessConversion { let a = cx.typeck_results().expr_ty(e); let b = cx.typeck_results().expr_ty(recv); if is_type_diagnostic_item(cx, a, sym::Result); - if let ty::Adt(_, substs) = a.kind(); - if let Some(a_type) = substs.types().next(); + if let ty::Adt(_, args) = a.kind(); + if let Some(a_type) = args.types().next(); if same_type_and_consts(a_type, b); then { @@ -255,8 +255,8 @@ impl<'tcx> LateLintPass<'tcx> for UselessConversion { if_chain! { if match_def_path(cx, def_id, &paths::TRY_FROM); if is_type_diagnostic_item(cx, a, sym::Result); - if let ty::Adt(_, substs) = a.kind(); - if let Some(a_type) = substs.types().next(); + if let ty::Adt(_, args) = a.kind(); + if let Some(a_type) = args.types().next(); if same_type_and_consts(a_type, b); then { diff --git a/src/tools/clippy/clippy_lints/src/utils/internal_lints/interning_defined_symbol.rs b/src/tools/clippy/clippy_lints/src/utils/internal_lints/interning_defined_symbol.rs index dced9fcf9ab..da8654d9388 100644 --- a/src/tools/clippy/clippy_lints/src/utils/internal_lints/interning_defined_symbol.rs +++ b/src/tools/clippy/clippy_lints/src/utils/internal_lints/interning_defined_symbol.rs @@ -78,7 +78,7 @@ impl<'tcx> LateLintPass<'tcx> for InterningDefinedSymbol { for item in cx.tcx.module_children(def_id) { if_chain! { if let Res::Def(DefKind::Const, item_def_id) = item.res; - let ty = cx.tcx.type_of(item_def_id).subst_identity(); + let ty = cx.tcx.type_of(item_def_id).instantiate_identity(); if match_type(cx, ty, &paths::SYMBOL); if let Ok(ConstValue::Scalar(value)) = cx.tcx.const_eval_poly(item_def_id); if let Ok(value) = value.to_u32(); diff --git a/src/tools/clippy/clippy_lints/src/utils/internal_lints/msrv_attr_impl.rs b/src/tools/clippy/clippy_lints/src/utils/internal_lints/msrv_attr_impl.rs index 09f0f0d0adb..bf835f89cfc 100644 --- a/src/tools/clippy/clippy_lints/src/utils/internal_lints/msrv_attr_impl.rs +++ b/src/tools/clippy/clippy_lints/src/utils/internal_lints/msrv_attr_impl.rs @@ -7,7 +7,7 @@ use rustc_errors::Applicability; use rustc_hir as hir; use rustc_hir_analysis::hir_ty_to_ty; use rustc_lint::{LateContext, LateLintPass, LintContext}; -use rustc_middle::ty::{self, subst::GenericArgKind}; +use rustc_middle::ty::{self, GenericArgKind}; use rustc_session::{declare_lint_pass, declare_tool_lint}; declare_clippy_lint! { @@ -39,7 +39,7 @@ impl LateLintPass<'_> for MsrvAttrImpl { if self_ty_def.all_fields().any(|f| { cx.tcx .type_of(f.did) - .subst_identity() + .instantiate_identity() .walk() .filter(|t| matches!(t.unpack(), GenericArgKind::Type(_))) .any(|t| match_type(cx, t.expect_ty(), &paths::MSRV)) diff --git a/src/tools/clippy/clippy_lints/src/utils/internal_lints/unnecessary_def_path.rs b/src/tools/clippy/clippy_lints/src/utils/internal_lints/unnecessary_def_path.rs index 00842376628..f66f33fee16 100644 --- a/src/tools/clippy/clippy_lints/src/utils/internal_lints/unnecessary_def_path.rs +++ b/src/tools/clippy/clippy_lints/src/utils/internal_lints/unnecessary_def_path.rs @@ -229,11 +229,11 @@ fn path_to_matched_type(cx: &LateContext<'_>, expr: &hir::Expr<'_>) -> Option<Ve Res::Def(DefKind::Static(_), def_id) => read_mir_alloc_def_path( cx, cx.tcx.eval_static_initializer(def_id).ok()?.inner(), - cx.tcx.type_of(def_id).subst_identity(), + cx.tcx.type_of(def_id).instantiate_identity(), ), Res::Def(DefKind::Const, def_id) => match cx.tcx.const_eval_poly(def_id).ok()? { ConstValue::ByRef { alloc, offset } if offset.bytes() == 0 => { - read_mir_alloc_def_path(cx, alloc.inner(), cx.tcx.type_of(def_id).subst_identity()) + read_mir_alloc_def_path(cx, alloc.inner(), cx.tcx.type_of(def_id).instantiate_identity()) }, _ => None, }, diff --git a/src/tools/clippy/clippy_lints/src/vec.rs b/src/tools/clippy/clippy_lints/src/vec.rs index 2a594e750b9..d1bf292d711 100644 --- a/src/tools/clippy/clippy_lints/src/vec.rs +++ b/src/tools/clippy/clippy_lints/src/vec.rs @@ -230,8 +230,8 @@ fn size_of(cx: &LateContext<'_>, expr: &Expr<'_>) -> u64 { /// Returns the item type of the vector (i.e., the `T` in `Vec<T>`). fn vec_type(ty: Ty<'_>) -> Ty<'_> { - if let ty::Adt(_, substs) = ty.kind() { - substs.type_at(0) + if let ty::Adt(_, args) = ty.kind() { + args.type_at(0) } else { panic!("The type of `vec!` is a not a struct?"); } diff --git a/src/tools/clippy/clippy_lints/src/zero_sized_map_values.rs b/src/tools/clippy/clippy_lints/src/zero_sized_map_values.rs index 93e4b023c5c..002304f8840 100644 --- a/src/tools/clippy/clippy_lints/src/zero_sized_map_values.rs +++ b/src/tools/clippy/clippy_lints/src/zero_sized_map_values.rs @@ -51,8 +51,8 @@ impl LateLintPass<'_> for ZeroSizedMapValues { if !in_trait_impl(cx, hir_ty.hir_id); let ty = ty_from_hir_ty(cx, hir_ty); if is_type_diagnostic_item(cx, ty, sym::HashMap) || is_type_diagnostic_item(cx, ty, sym::BTreeMap); - if let Adt(_, substs) = ty.kind(); - let ty = substs.type_at(1); + if let Adt(_, args) = ty.kind(); + let ty = args.type_at(1); // Fixes https://github.com/rust-lang/rust-clippy/issues/7447 because of // https://github.com/rust-lang/rust/blob/master/compiler/rustc_middle/src/ty/sty.rs#L968 if !ty.has_escaping_bound_vars(); diff --git a/src/tools/clippy/clippy_utils/src/consts.rs b/src/tools/clippy/clippy_utils/src/consts.rs index d1cfdc49658..4832a38eceb 100644 --- a/src/tools/clippy/clippy_utils/src/consts.rs +++ b/src/tools/clippy/clippy_utils/src/consts.rs @@ -12,7 +12,7 @@ use rustc_lint::LateContext; use rustc_middle::mir; use rustc_middle::mir::interpret::Scalar; use rustc_middle::ty::{self, EarlyBinder, FloatTy, ScalarInt, Ty, TyCtxt}; -use rustc_middle::ty::{List, SubstsRef}; +use rustc_middle::ty::{List, GenericArgsRef}; use rustc_middle::{bug, span_bug}; use rustc_span::symbol::{Ident, Symbol}; use rustc_span::SyntaxContext; @@ -327,7 +327,7 @@ pub struct ConstEvalLateContext<'a, 'tcx> { typeck_results: &'a ty::TypeckResults<'tcx>, param_env: ty::ParamEnv<'tcx>, source: ConstantSource, - substs: SubstsRef<'tcx>, + args: GenericArgsRef<'tcx>, } impl<'a, 'tcx> ConstEvalLateContext<'a, 'tcx> { @@ -337,7 +337,7 @@ impl<'a, 'tcx> ConstEvalLateContext<'a, 'tcx> { typeck_results, param_env: lcx.param_env, source: ConstantSource::Local, - substs: List::empty(), + args: List::empty(), } } @@ -473,16 +473,16 @@ impl<'a, 'tcx> ConstEvalLateContext<'a, 'tcx> { return None; } - let substs = self.typeck_results.node_substs(id); - let substs = if self.substs.is_empty() { - substs + let args = self.typeck_results.node_args(id); + let args = if self.args.is_empty() { + args } else { - EarlyBinder::bind(substs).subst(self.lcx.tcx, self.substs) + EarlyBinder::bind(args).instantiate(self.lcx.tcx, self.args) }; let result = self .lcx .tcx - .const_eval_resolve(self.param_env, mir::UnevaluatedConst::new(def_id, substs), None) + .const_eval_resolve(self.param_env, mir::UnevaluatedConst::new(def_id, args), None) .ok() .map(|val| rustc_middle::mir::ConstantKind::from_value(val, ty))?; let result = miri_to_const(self.lcx, result)?; diff --git a/src/tools/clippy/clippy_utils/src/eager_or_lazy.rs b/src/tools/clippy/clippy_utils/src/eager_or_lazy.rs index 4a845ca63b4..94b9006ed50 100644 --- a/src/tools/clippy/clippy_utils/src/eager_or_lazy.rs +++ b/src/tools/clippy/clippy_utils/src/eager_or_lazy.rs @@ -51,7 +51,7 @@ fn fn_eagerness(cx: &LateContext<'_>, fn_id: DefId, name: Symbol, have_one_arg: let name = name.as_str(); let ty = match cx.tcx.impl_of_method(fn_id) { - Some(id) => cx.tcx.type_of(id).subst_identity(), + Some(id) => cx.tcx.type_of(id).instantiate_identity(), None => return Lazy, }; @@ -72,7 +72,7 @@ fn fn_eagerness(cx: &LateContext<'_>, fn_id: DefId, name: Symbol, have_one_arg: .variants() .iter() .flat_map(|v| v.fields.iter()) - .any(|x| matches!(cx.tcx.type_of(x.did).subst_identity().peel_refs().kind(), ty::Param(_))) + .any(|x| matches!(cx.tcx.type_of(x.did).instantiate_identity().peel_refs().kind(), ty::Param(_))) && all_predicates_of(cx.tcx, fn_id).all(|(pred, _)| match pred.kind().skip_binder() { ty::ClauseKind::Trait(pred) => cx.tcx.trait_def(pred.trait_ref.def_id).is_marker, _ => true, @@ -80,7 +80,7 @@ fn fn_eagerness(cx: &LateContext<'_>, fn_id: DefId, name: Symbol, have_one_arg: && subs.types().all(|x| matches!(x.peel_refs().kind(), ty::Param(_))) { // Limit the function to either `(self) -> bool` or `(&self) -> bool` - match &**cx.tcx.fn_sig(fn_id).subst_identity().skip_binder().inputs_and_output { + match &**cx.tcx.fn_sig(fn_id).instantiate_identity().skip_binder().inputs_and_output { [arg, res] if !arg.is_mutable_ptr() && arg.peel_refs() == ty && res.is_bool() => NoChange, _ => Lazy, } diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs index 727b59f1f43..5eed5ddf9e3 100644 --- a/src/tools/clippy/clippy_utils/src/lib.rs +++ b/src/tools/clippy/clippy_utils/src/lib.rs @@ -305,7 +305,7 @@ pub fn match_trait_method(cx: &LateContext<'_>, expr: &Expr<'_>, path: &[&str]) /// Checks if a method is defined in an impl of a diagnostic item pub fn is_diag_item_method(cx: &LateContext<'_>, def_id: DefId, diag_item: Symbol) -> bool { if let Some(impl_did) = cx.tcx.impl_of_method(def_id) { - if let Some(adt) = cx.tcx.type_of(impl_did).subst_identity().ty_adt_def() { + if let Some(adt) = cx.tcx.type_of(impl_did).instantiate_identity().ty_adt_def() { return cx.tcx.is_diagnostic_item(diag_item, adt.did()); } } @@ -812,7 +812,7 @@ fn is_default_equivalent_ctor(cx: &LateContext<'_>, def_id: DefId, path: &QPath< if let QPath::TypeRelative(_, method) = path { if method.ident.name == sym::new { if let Some(impl_did) = cx.tcx.impl_of_method(def_id) { - if let Some(adt) = cx.tcx.type_of(impl_did).subst_identity().ty_adt_def() { + if let Some(adt) = cx.tcx.type_of(impl_did).instantiate_identity().ty_adt_def() { return std_types_symbols.iter().any(|&symbol| { cx.tcx.is_diagnostic_item(symbol, adt.did()) || Some(adt.did()) == cx.tcx.lang_items().string() }); @@ -1377,7 +1377,7 @@ pub fn get_enclosing_loop_or_multi_call_closure<'tcx>( .chain(args.iter()) .position(|arg| arg.hir_id == id)?; let id = cx.typeck_results().type_dependent_def_id(e.hir_id)?; - let ty = cx.tcx.fn_sig(id).subst_identity().skip_binder().inputs()[i]; + let ty = cx.tcx.fn_sig(id).instantiate_identity().skip_binder().inputs()[i]; ty_is_fn_once_param(cx.tcx, ty, cx.tcx.param_env(id).caller_bounds()).then_some(()) }, _ => None, @@ -1639,13 +1639,13 @@ pub fn is_direct_expn_of(span: Span, name: &str) -> Option<Span> { /// Convenience function to get the return type of a function. pub fn return_ty<'tcx>(cx: &LateContext<'tcx>, fn_def_id: hir::OwnerId) -> Ty<'tcx> { - let ret_ty = cx.tcx.fn_sig(fn_def_id).subst_identity().output(); + let ret_ty = cx.tcx.fn_sig(fn_def_id).instantiate_identity().output(); cx.tcx.erase_late_bound_regions(ret_ty) } /// Convenience function to get the nth argument type of a function. pub fn nth_arg<'tcx>(cx: &LateContext<'tcx>, fn_def_id: hir::OwnerId, nth: usize) -> Ty<'tcx> { - let arg = cx.tcx.fn_sig(fn_def_id).subst_identity().input(nth); + let arg = cx.tcx.fn_sig(fn_def_id).instantiate_identity().input(nth); cx.tcx.erase_late_bound_regions(arg) } diff --git a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs index fbf4ab2722e..515f80e0edf 100644 --- a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs +++ b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs @@ -15,7 +15,7 @@ use rustc_middle::mir::{ Terminator, TerminatorKind, }; use rustc_middle::traits::{ImplSource, ObligationCause}; -use rustc_middle::ty::subst::GenericArgKind; +use rustc_middle::ty::GenericArgKind; use rustc_middle::ty::{self, adjustment::PointerCoercion, Ty, TyCtxt}; use rustc_middle::ty::{BoundConstness, TraitRef}; use rustc_semver::RustcVersion; @@ -35,7 +35,7 @@ pub fn is_min_const_fn<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'tcx>, msrv: &Msrv) // impl trait is gone in MIR, so check the return type manually check_ty( tcx, - tcx.fn_sig(def_id).subst_identity().output().skip_binder(), + tcx.fn_sig(def_id).instantiate_identity().output().skip_binder(), body.local_decls.iter().next().unwrap().source_info.span, )?; diff --git a/src/tools/clippy/clippy_utils/src/sugg.rs b/src/tools/clippy/clippy_utils/src/sugg.rs index cf781e18cd6..3953a7d8fa7 100644 --- a/src/tools/clippy/clippy_utils/src/sugg.rs +++ b/src/tools/clippy/clippy_utils/src/sugg.rs @@ -877,7 +877,7 @@ impl<'tcx> DerefDelegate<'_, 'tcx> { .cx .typeck_results() .type_dependent_def_id(parent_expr.hir_id) - .map(|did| self.cx.tcx.fn_sig(did).subst_identity().skip_binder()) + .map(|did| self.cx.tcx.fn_sig(did).instantiate_identity().skip_binder()) { std::iter::once(receiver) .chain(call_args.iter()) diff --git a/src/tools/clippy/clippy_utils/src/ty.rs b/src/tools/clippy/clippy_utils/src/ty.rs index d650cbe0b13..7687d361923 100644 --- a/src/tools/clippy/clippy_utils/src/ty.rs +++ b/src/tools/clippy/clippy_utils/src/ty.rs @@ -17,7 +17,7 @@ use rustc_lint::LateContext; use rustc_middle::mir::interpret::{ConstValue, Scalar}; use rustc_middle::ty::{ self, layout::ValidityRequirement, AdtDef, AliasTy, AssocKind, Binder, BoundRegion, FnSig, IntTy, List, ParamEnv, - Region, RegionKind, SubstsRef, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, + Region, RegionKind, GenericArgsRef, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, UintTy, VariantDef, VariantDiscr, }; use rustc_middle::ty::{GenericArg, GenericArgKind}; @@ -90,14 +90,14 @@ pub fn contains_ty_adt_constructor_opaque<'tcx>(cx: &LateContext<'tcx>, ty: Ty<' return false; } - for (predicate, _span) in cx.tcx.explicit_item_bounds(def_id).subst_identity_iter_copied() { + for (predicate, _span) in cx.tcx.explicit_item_bounds(def_id).instantiate_identity_iter_copied() { match predicate.kind().skip_binder() { // For `impl Trait<U>`, it will register a predicate of `T: Trait<U>`, so we go through // and check substitutions to find `U`. ty::ClauseKind::Trait(trait_predicate) => { if trait_predicate .trait_ref - .substs + .args .types() .skip(1) // Skip the implicit `Self` generic parameter .any(|ty| contains_ty_adt_constructor_opaque_inner(cx, ty, needle, seen)) @@ -237,7 +237,7 @@ pub fn implements_trait_with_env<'tcx>( kind: TypeVariableOriginKind::MiscVariable, span: DUMMY_SP, }; - let ty_params = tcx.mk_substs_from_iter( + let ty_params = tcx.mk_args_from_iter( ty_params .into_iter() .map(|arg| arg.unwrap_or_else(|| infcx.next_ty_var(orig).into())), @@ -265,7 +265,7 @@ pub fn is_must_use_ty<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool { // because we don't want to lint functions returning empty arrays is_must_use_ty(cx, *ty) }, - ty::Tuple(substs) => substs.iter().any(|ty| is_must_use_ty(cx, ty)), + ty::Tuple(args) => args.iter().any(|ty| is_must_use_ty(cx, ty)), ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }) => { for (predicate, _) in cx.tcx.explicit_item_bounds(def_id).skip_binder() { if let ty::ClauseKind::Trait(trait_predicate) = predicate.kind().skip_binder() { @@ -314,11 +314,11 @@ fn is_normalizable_helper<'tcx>( let cause = rustc_middle::traits::ObligationCause::dummy(); let result = if infcx.at(&cause, param_env).query_normalize(ty).is_ok() { match ty.kind() { - ty::Adt(def, substs) => def.variants().iter().all(|variant| { + ty::Adt(def, args) => def.variants().iter().all(|variant| { variant .fields .iter() - .all(|field| is_normalizable_helper(cx, param_env, field.ty(cx.tcx, substs), cache)) + .all(|field| is_normalizable_helper(cx, param_env, field.ty(cx.tcx, args), cache)) }), _ => ty.walk().all(|generic_arg| match generic_arg.unpack() { GenericArgKind::Type(inner_ty) if inner_ty != ty => { @@ -517,14 +517,14 @@ pub fn walk_ptrs_ty_depth(ty: Ty<'_>) -> (Ty<'_>, usize) { /// otherwise returns `false` pub fn same_type_and_consts<'tcx>(a: Ty<'tcx>, b: Ty<'tcx>) -> bool { match (&a.kind(), &b.kind()) { - (&ty::Adt(did_a, substs_a), &ty::Adt(did_b, substs_b)) => { + (&ty::Adt(did_a, args_a), &ty::Adt(did_b, args_b)) => { if did_a != did_b { return false; } - substs_a + args_a .iter() - .zip(substs_b.iter()) + .zip(args_b.iter()) .all(|(arg_a, arg_b)| match (arg_a.unpack(), arg_b.unpack()) { (GenericArgKind::Const(inner_a), GenericArgKind::Const(inner_b)) => inner_a == inner_b, (GenericArgKind::Type(type_a), GenericArgKind::Type(type_b)) => { @@ -643,7 +643,7 @@ impl<'tcx> ExprFnSig<'tcx> { /// If the expression is function like, get the signature for it. pub fn expr_sig<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>) -> Option<ExprFnSig<'tcx>> { if let Res::Def(DefKind::Fn | DefKind::Ctor(_, CtorKind::Fn) | DefKind::AssocFn, id) = path_res(cx, expr) { - Some(ExprFnSig::Sig(cx.tcx.fn_sig(id).subst_identity(), Some(id))) + Some(ExprFnSig::Sig(cx.tcx.fn_sig(id).instantiate_identity(), Some(id))) } else { ty_sig(cx, cx.typeck_results().expr_ty_adjusted(expr).peel_refs()) } @@ -661,11 +661,11 @@ pub fn ty_sig<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option<ExprFnSig<'t .and_then(|id| cx.tcx.hir().fn_decl_by_hir_id(cx.tcx.hir().local_def_id_to_hir_id(id))); Some(ExprFnSig::Closure(decl, subs.as_closure().sig())) }, - ty::FnDef(id, subs) => Some(ExprFnSig::Sig(cx.tcx.fn_sig(id).subst(cx.tcx, subs), Some(id))), - ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs, .. }) => sig_from_bounds( + ty::FnDef(id, subs) => Some(ExprFnSig::Sig(cx.tcx.fn_sig(id).instantiate(cx.tcx, subs), Some(id))), + ty::Alias(ty::Opaque, ty::AliasTy { def_id, args, .. }) => sig_from_bounds( cx, ty, - cx.tcx.item_bounds(def_id).subst_iter(cx.tcx, substs), + cx.tcx.item_bounds(def_id).arg_iter(cx.tcx, args), cx.tcx.opt_parent(def_id), ), ty::FnPtr(sig) => Some(ExprFnSig::Sig(sig, None)), @@ -681,7 +681,7 @@ pub fn ty_sig<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option<ExprFnSig<'t .projection_bounds() .find(|p| lang_items.fn_once_output().map_or(false, |id| id == p.item_def_id())) .map(|p| p.map_bound(|p| p.term.ty().unwrap())); - Some(ExprFnSig::Trait(bound.map_bound(|b| b.substs.type_at(0)), output, None)) + Some(ExprFnSig::Trait(bound.map_bound(|b| b.args.type_at(0)), output, None)) }, _ => None, } @@ -713,7 +713,7 @@ fn sig_from_bounds<'tcx>( || lang_items.fn_once_trait() == Some(p.def_id())) && p.self_ty() == ty => { - let i = pred.kind().rebind(p.trait_ref.substs.type_at(1)); + let i = pred.kind().rebind(p.trait_ref.args.type_at(1)); if inputs.map_or(false, |inputs| i != inputs) { // Multiple different fn trait impls. Is this even allowed? return None; @@ -744,7 +744,7 @@ fn sig_for_projection<'tcx>(cx: &LateContext<'tcx>, ty: AliasTy<'tcx>) -> Option for (pred, _) in cx .tcx .explicit_item_bounds(ty.def_id) - .subst_iter_copied(cx.tcx, ty.substs) + .arg_iter_copied(cx.tcx, ty.args) { match pred.kind().skip_binder() { ty::ClauseKind::Trait(p) @@ -752,7 +752,7 @@ fn sig_for_projection<'tcx>(cx: &LateContext<'tcx>, ty: AliasTy<'tcx>) -> Option || lang_items.fn_mut_trait() == Some(p.def_id()) || lang_items.fn_once_trait() == Some(p.def_id())) => { - let i = pred.kind().rebind(p.trait_ref.substs.type_at(1)); + let i = pred.kind().rebind(p.trait_ref.args.type_at(1)); if inputs.map_or(false, |inputs| inputs != i) { // Multiple different fn trait impls. Is this even allowed? @@ -793,7 +793,7 @@ impl core::ops::Add<u32> for EnumValue { #[expect(clippy::cast_possible_truncation, clippy::cast_possible_wrap)] pub fn read_explicit_enum_value(tcx: TyCtxt<'_>, id: DefId) -> Option<EnumValue> { if let Ok(ConstValue::Scalar(Scalar::Int(value))) = tcx.const_eval_poly(id) { - match tcx.type_of(id).subst_identity().kind() { + match tcx.type_of(id).instantiate_identity().kind() { ty::Int(_) => Some(EnumValue::Signed(match value.size().bytes() { 1 => i128::from(value.assert_bits(Size::from_bytes(1)) as u8 as i8), 2 => i128::from(value.assert_bits(Size::from_bytes(2)) as u16 as i16), @@ -927,7 +927,7 @@ pub fn adt_and_variant_of_res<'tcx>(cx: &LateContext<'tcx>, res: Res) -> Option< Some((adt, adt.variant_with_id(var_id))) }, Res::SelfCtor(id) => { - let adt = cx.tcx.type_of(id).subst_identity().ty_adt_def().unwrap(); + let adt = cx.tcx.type_of(id).instantiate_identity().ty_adt_def().unwrap(); Some((adt, adt.non_enum_variant())) }, _ => None, @@ -1025,13 +1025,13 @@ pub fn make_projection<'tcx>( tcx: TyCtxt<'tcx>, container_id: DefId, assoc_ty: Symbol, - substs: impl IntoIterator<Item = impl Into<GenericArg<'tcx>>>, + args: impl IntoIterator<Item = impl Into<GenericArg<'tcx>>>, ) -> Option<AliasTy<'tcx>> { fn helper<'tcx>( tcx: TyCtxt<'tcx>, container_id: DefId, assoc_ty: Symbol, - substs: SubstsRef<'tcx>, + args: GenericArgsRef<'tcx>, ) -> Option<AliasTy<'tcx>> { let Some(assoc_item) = tcx .associated_items(container_id) @@ -1052,18 +1052,18 @@ pub fn make_projection<'tcx>( .map(|x| &x.kind); debug_assert!( - generic_count == substs.len(), - "wrong number of substs for `{:?}`: found `{}` expected `{generic_count}`.\n\ + generic_count == args.len(), + "wrong number of args for `{:?}`: found `{}` expected `{generic_count}`.\n\ note: the expected parameters are: {:#?}\n\ - the given arguments are: `{substs:#?}`", + the given arguments are: `{args:#?}`", assoc_item.def_id, - substs.len(), + args.len(), params.map(ty::GenericParamDefKind::descr).collect::<Vec<_>>(), ); if let Some((idx, (param, arg))) = params .clone() - .zip(substs.iter().map(GenericArg::unpack)) + .zip(args.iter().map(GenericArg::unpack)) .enumerate() .find(|(_, (param, arg))| { !matches!( @@ -1078,20 +1078,20 @@ pub fn make_projection<'tcx>( false, "mismatched subst type at index {idx}: expected a {}, found `{arg:?}`\n\ note: the expected parameters are {:#?}\n\ - the given arguments are {substs:#?}", + the given arguments are {args:#?}", param.descr(), params.map(ty::GenericParamDefKind::descr).collect::<Vec<_>>() ); } } - Some(tcx.mk_alias_ty(assoc_item.def_id, substs)) + Some(tcx.mk_alias_ty(assoc_item.def_id, args)) } helper( tcx, container_id, assoc_ty, - tcx.mk_substs_from_iter(substs.into_iter().map(Into::into)), + tcx.mk_args_from_iter(args.into_iter().map(Into::into)), ) } @@ -1106,25 +1106,25 @@ pub fn make_normalized_projection<'tcx>( param_env: ParamEnv<'tcx>, container_id: DefId, assoc_ty: Symbol, - substs: impl IntoIterator<Item = impl Into<GenericArg<'tcx>>>, + args: impl IntoIterator<Item = impl Into<GenericArg<'tcx>>>, ) -> Option<Ty<'tcx>> { fn helper<'tcx>(tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>, ty: AliasTy<'tcx>) -> Option<Ty<'tcx>> { #[cfg(debug_assertions)] if let Some((i, subst)) = ty - .substs + .args .iter() .enumerate() .find(|(_, subst)| subst.has_late_bound_regions()) { debug_assert!( false, - "substs contain late-bound region at index `{i}` which can't be normalized.\n\ + "args contain late-bound region at index `{i}` which can't be normalized.\n\ use `TyCtxt::erase_late_bound_regions`\n\ note: subst is `{subst:#?}`", ); return None; } - match tcx.try_normalize_erasing_regions(param_env, Ty::new_projection(tcx,ty.def_id, ty.substs)) { + match tcx.try_normalize_erasing_regions(param_env, Ty::new_projection(tcx,ty.def_id, ty.args)) { Ok(ty) => Some(ty), Err(e) => { debug_assert!(false, "failed to normalize type `{ty}`: {e:#?}"); @@ -1132,7 +1132,7 @@ pub fn make_normalized_projection<'tcx>( }, } } - helper(tcx, param_env, make_projection(tcx, container_id, assoc_ty, substs)?) + helper(tcx, param_env, make_projection(tcx, container_id, assoc_ty, args)?) } /// Check if given type has inner mutability such as [`std::cell::Cell`] or [`std::cell::RefCell`] @@ -1147,7 +1147,7 @@ pub fn is_interior_mut_ty<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool { && is_interior_mut_ty(cx, inner_ty) }, ty::Tuple(fields) => fields.iter().any(|ty| is_interior_mut_ty(cx, ty)), - ty::Adt(def, substs) => { + ty::Adt(def, args) => { // Special case for collections in `std` who's impl of `Hash` or `Ord` delegates to // that of their type parameters. Note: we don't include `HashSet` and `HashMap` // because they have no impl for `Hash` or `Ord`. @@ -1168,7 +1168,7 @@ pub fn is_interior_mut_ty<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool { let is_box = Some(def_id) == cx.tcx.lang_items().owned_box(); if is_std_collection || is_box { // The type is mutable if any of its type parameters are - substs.types().any(|ty| is_interior_mut_ty(cx, ty)) + args.types().any(|ty| is_interior_mut_ty(cx, ty)) } else { !ty.has_escaping_bound_vars() && cx.tcx.layout_of(cx.param_env.and(ty)).is_ok() @@ -1184,19 +1184,19 @@ pub fn make_normalized_projection_with_regions<'tcx>( param_env: ParamEnv<'tcx>, container_id: DefId, assoc_ty: Symbol, - substs: impl IntoIterator<Item = impl Into<GenericArg<'tcx>>>, + args: impl IntoIterator<Item = impl Into<GenericArg<'tcx>>>, ) -> Option<Ty<'tcx>> { fn helper<'tcx>(tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>, ty: AliasTy<'tcx>) -> Option<Ty<'tcx>> { #[cfg(debug_assertions)] if let Some((i, subst)) = ty - .substs + .args .iter() .enumerate() .find(|(_, subst)| subst.has_late_bound_regions()) { debug_assert!( false, - "substs contain late-bound region at index `{i}` which can't be normalized.\n\ + "args contain late-bound region at index `{i}` which can't be normalized.\n\ use `TyCtxt::erase_late_bound_regions`\n\ note: subst is `{subst:#?}`", ); @@ -1207,7 +1207,7 @@ pub fn make_normalized_projection_with_regions<'tcx>( .infer_ctxt() .build() .at(&cause, param_env) - .query_normalize(Ty::new_projection(tcx,ty.def_id, ty.substs)) + .query_normalize(Ty::new_projection(tcx,ty.def_id, ty.args)) { Ok(ty) => Some(ty.value), Err(e) => { @@ -1216,7 +1216,7 @@ pub fn make_normalized_projection_with_regions<'tcx>( }, } } - helper(tcx, param_env, make_projection(tcx, container_id, assoc_ty, substs)?) + helper(tcx, param_env, make_projection(tcx, container_id, assoc_ty, args)?) } pub fn normalize_with_regions<'tcx>(tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> { diff --git a/src/tools/clippy/tests/ui/crashes/ice-6256.rs b/src/tools/clippy/tests/ui/crashes/ice-6256.rs index 1d336b3cdc0..bb488c2dcb3 100644 --- a/src/tools/clippy/tests/ui/crashes/ice-6256.rs +++ b/src/tools/clippy/tests/ui/crashes/ice-6256.rs @@ -1,5 +1,5 @@ // originally from rustc ./tests/ui/regions/issue-78262.rs -// ICE: to get the signature of a closure, use substs.as_closure().sig() not fn_sig() +// ICE: to get the signature of a closure, use args.as_closure().sig() not fn_sig() #![allow(clippy::upper_case_acronyms)] trait TT {} diff --git a/src/tools/clippy/tests/ui/eta.fixed b/src/tools/clippy/tests/ui/eta.fixed index bf44bcb564e..db7bd99e0ae 100644 --- a/src/tools/clippy/tests/ui/eta.fixed +++ b/src/tools/clippy/tests/ui/eta.fixed @@ -331,7 +331,7 @@ impl dyn TestTrait + '_ { } // https://github.com/rust-lang/rust-clippy/issues/7746 -fn angle_brackets_and_substs() { +fn angle_brackets_and_args() { let array_opt: Option<&[u8; 3]> = Some(&[4, 8, 7]); array_opt.map(<[u8; 3]>::as_slice); diff --git a/src/tools/clippy/tests/ui/eta.rs b/src/tools/clippy/tests/ui/eta.rs index b2af4bf0953..52fc17686fd 100644 --- a/src/tools/clippy/tests/ui/eta.rs +++ b/src/tools/clippy/tests/ui/eta.rs @@ -331,7 +331,7 @@ impl dyn TestTrait + '_ { } // https://github.com/rust-lang/rust-clippy/issues/7746 -fn angle_brackets_and_substs() { +fn angle_brackets_and_args() { let array_opt: Option<&[u8; 3]> = Some(&[4, 8, 7]); array_opt.map(|a| a.as_slice()); diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version index 17b1d2b1120..3bef3be2a53 100644 --- a/src/tools/miri/rust-version +++ b/src/tools/miri/rust-version @@ -1 +1 @@ -743333f3dd90721461c09387ec73d09c080d5f5f +33a2c2487ac5d9927830ea4c1844335c6b9f77db diff --git a/src/tools/miri/src/borrow_tracker/mod.rs b/src/tools/miri/src/borrow_tracker/mod.rs index a2cf7c80950..fcfa8f64570 100644 --- a/src/tools/miri/src/borrow_tracker/mod.rs +++ b/src/tools/miri/src/borrow_tracker/mod.rs @@ -74,7 +74,7 @@ pub struct FrameState { impl VisitTags for FrameState { fn visit_tags(&self, _visit: &mut dyn FnMut(BorTag)) { - // `protected_tags` are fine to GC. + // `protected_tags` are already recorded by `GlobalStateInner`. } } @@ -108,9 +108,12 @@ pub struct GlobalStateInner { } impl VisitTags for GlobalStateInner { - fn visit_tags(&self, _visit: &mut dyn FnMut(BorTag)) { - // The only candidate is base_ptr_tags, and that does not need visiting since we don't ever - // GC the bottommost tag. + fn visit_tags(&self, visit: &mut dyn FnMut(BorTag)) { + for &tag in self.protected_tags.keys() { + visit(tag); + } + // The only other candidate is base_ptr_tags, and that does not need visiting since we don't ever + // GC the bottommost/root tag. } } diff --git a/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs b/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs index e22b352e740..15a7d72edf1 100644 --- a/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs +++ b/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs @@ -996,7 +996,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { /// Protect a place so that it cannot be used any more for the duration of the current function /// call. - /// + /// /// This is used to ensure soundness of in-place function argument/return passing. fn sb_protect_place(&mut self, place: &MPlaceTy<'tcx, Provenance>) -> InterpResult<'tcx> { let this = self.eval_context_mut(); diff --git a/src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs b/src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs index 274a4a0aaba..2afd45829bd 100644 --- a/src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs +++ b/src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs @@ -497,7 +497,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { /// Protect a place so that it cannot be used any more for the duration of the current function /// call. - /// + /// /// This is used to ensure soundness of in-place function argument/return passing. fn tb_protect_place(&mut self, place: &MPlaceTy<'tcx, Provenance>) -> InterpResult<'tcx> { let this = self.eval_context_mut(); diff --git a/src/tools/miri/src/eval.rs b/src/tools/miri/src/eval.rs index aba7dd5a9fe..ed3d741db1c 100644 --- a/src/tools/miri/src/eval.rs +++ b/src/tools/miri/src/eval.rs @@ -380,7 +380,7 @@ pub fn create_ecx<'mir, 'tcx: 'mir>( tcx, ty::ParamEnv::reveal_all(), start_id, - tcx.mk_substs(&[ty::subst::GenericArg::from(main_ret_ty)]), + tcx.mk_args(&[ty::GenericArg::from(main_ret_ty)]), ) .unwrap() .unwrap(); diff --git a/src/tools/miri/src/lib.rs b/src/tools/miri/src/lib.rs index 4a093d7bcc6..5327c2f24e0 100644 --- a/src/tools/miri/src/lib.rs +++ b/src/tools/miri/src/lib.rs @@ -43,19 +43,20 @@ // Needed for rustdoc from bootstrap (with `-Znormalize-docs`). #![recursion_limit = "256"] +extern crate either; // the one from rustc + extern crate rustc_apfloat; extern crate rustc_ast; -extern crate rustc_errors; -#[macro_use] -extern crate rustc_middle; extern crate rustc_const_eval; extern crate rustc_data_structures; +extern crate rustc_errors; extern crate rustc_hir; extern crate rustc_index; +#[macro_use] +extern crate rustc_middle; extern crate rustc_session; extern crate rustc_span; extern crate rustc_target; -extern crate either; // the one from rustc // Necessary to pull in object code as the rest of the rustc crates are shipped only as rmeta // files. diff --git a/src/tools/miri/src/machine.rs b/src/tools/miri/src/machine.rs index 5510e3f94b7..a8f89d56f6d 100644 --- a/src/tools/miri/src/machine.rs +++ b/src/tools/miri/src/machine.rs @@ -972,7 +972,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> { panic!("extern_statics cannot contain wildcards") }; let (shim_size, shim_align, _kind) = ecx.get_alloc_info(alloc_id); - let def_ty = ecx.tcx.type_of(def_id).subst_identity(); + let def_ty = ecx.tcx.type_of(def_id).instantiate_identity(); let extern_decl_layout = ecx.tcx.layout_of(ty::ParamEnv::empty().and(def_ty)).unwrap(); if extern_decl_layout.size != shim_size || extern_decl_layout.align.abi != shim_align { throw_unsup_format!( @@ -1097,9 +1097,8 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> { ptr: Pointer<Self::Provenance>, ) -> InterpResult<'tcx> { match ptr.provenance { - Provenance::Concrete { alloc_id, tag } => { - intptrcast::GlobalStateInner::expose_ptr(ecx, alloc_id, tag) - } + Provenance::Concrete { alloc_id, tag } => + intptrcast::GlobalStateInner::expose_ptr(ecx, alloc_id, tag), Provenance::Wildcard => { // No need to do anything for wildcard pointers as // their provenances have already been previously exposed. diff --git a/src/tools/miri/tests/fail/dangling_pointers/dangling_zst_deref.rs b/src/tools/miri/tests/fail/dangling_pointers/dangling_zst_deref.rs index 534d7d5f42f..e749eb896e2 100644 --- a/src/tools/miri/tests/fail/dangling_pointers/dangling_zst_deref.rs +++ b/src/tools/miri/tests/fail/dangling_pointers/dangling_zst_deref.rs @@ -1,6 +1,5 @@ // Make sure we find these even with many checks disabled. -// Some optimizations remove ZST accesses, thus masking this UB. -//@compile-flags: -Zmir-opt-level=0 -Zmiri-disable-alignment-check -Zmiri-disable-stacked-borrows -Zmiri-disable-validation +//@compile-flags: -Zmiri-disable-alignment-check -Zmiri-disable-stacked-borrows -Zmiri-disable-validation fn main() { let p = { diff --git a/src/tools/miri/tests/fail/dangling_pointers/dyn_size.rs b/src/tools/miri/tests/fail/dangling_pointers/dyn_size.rs index 54f353ebebe..87ca8a6077c 100644 --- a/src/tools/miri/tests/fail/dangling_pointers/dyn_size.rs +++ b/src/tools/miri/tests/fail/dangling_pointers/dyn_size.rs @@ -1,5 +1,5 @@ -// should find the bug even without these, but gets masked by optimizations -//@compile-flags: -Zmiri-disable-validation -Zmiri-disable-stacked-borrows -Zmir-opt-level=0 +// should find the bug even without these +//@compile-flags: -Zmiri-disable-validation -Zmiri-disable-stacked-borrows struct SliceWithHead(u8, [u8]); diff --git a/src/tools/miri/tests/fail/dangling_pointers/maybe_null_pointer_deref_zst.rs b/src/tools/miri/tests/fail/dangling_pointers/maybe_null_pointer_deref_zst.rs index a48a3189db2..73d0b120680 100644 --- a/src/tools/miri/tests/fail/dangling_pointers/maybe_null_pointer_deref_zst.rs +++ b/src/tools/miri/tests/fail/dangling_pointers/maybe_null_pointer_deref_zst.rs @@ -1,6 +1,3 @@ -// Some optimizations remove ZST accesses, thus masking this UB. -//@compile-flags: -Zmir-opt-level=0 - fn main() { // This pointer *could* be NULL so we cannot load from it, not even at ZST let ptr = (&0u8 as *const u8).wrapping_sub(0x800) as *const (); diff --git a/src/tools/miri/tests/fail/dangling_pointers/maybe_null_pointer_write_zst.rs b/src/tools/miri/tests/fail/dangling_pointers/maybe_null_pointer_write_zst.rs index 449c65d218a..5537207ae42 100644 --- a/src/tools/miri/tests/fail/dangling_pointers/maybe_null_pointer_write_zst.rs +++ b/src/tools/miri/tests/fail/dangling_pointers/maybe_null_pointer_write_zst.rs @@ -1,6 +1,3 @@ -// Some optimizations remove ZST accesses, thus masking this UB. -//@compile-flags: -Zmir-opt-level=0 - fn main() { // This pointer *could* be NULL so we cannot load from it, not even at ZST. // Not using the () type here, as writes of that type do not even have MIR generated. diff --git a/src/tools/miri/tests/fail/dangling_pointers/null_pointer_deref_zst.rs b/src/tools/miri/tests/fail/dangling_pointers/null_pointer_deref_zst.rs index d6a607c61cb..4cb805db095 100644 --- a/src/tools/miri/tests/fail/dangling_pointers/null_pointer_deref_zst.rs +++ b/src/tools/miri/tests/fail/dangling_pointers/null_pointer_deref_zst.rs @@ -1,6 +1,3 @@ -// Some optimizations remove ZST accesses, thus masking this UB. -//@compile-flags: -Zmir-opt-level=0 - #[allow(deref_nullptr)] fn main() { let x: () = unsafe { *std::ptr::null() }; //~ ERROR: dereferencing pointer failed: null pointer is a dangling pointer diff --git a/src/tools/miri/tests/fail/dangling_pointers/null_pointer_write_zst.rs b/src/tools/miri/tests/fail/dangling_pointers/null_pointer_write_zst.rs index 21344208130..ec34c631a46 100644 --- a/src/tools/miri/tests/fail/dangling_pointers/null_pointer_write_zst.rs +++ b/src/tools/miri/tests/fail/dangling_pointers/null_pointer_write_zst.rs @@ -1,6 +1,3 @@ -// Some optimizations remove ZST accesses, thus masking this UB. -//@compile-flags: -Zmir-opt-level=0 - #[allow(deref_nullptr)] fn main() { // Not using the () type here, as writes of that type do not even have MIR generated. diff --git a/src/tools/miri/tests/fail/dangling_pointers/stack_temporary.rs b/src/tools/miri/tests/fail/dangling_pointers/stack_temporary.rs index 1373773f68d..c193d5fe0b3 100644 --- a/src/tools/miri/tests/fail/dangling_pointers/stack_temporary.rs +++ b/src/tools/miri/tests/fail/dangling_pointers/stack_temporary.rs @@ -1,5 +1,5 @@ -// This should fail even without validation, but some MIR opts mask the error -//@compile-flags: -Zmiri-disable-validation -Zmir-opt-level=0 +// This should fail even without validation +//@compile-flags: -Zmiri-disable-validation unsafe fn make_ref<'a>(x: *mut i32) -> &'a mut i32 { &mut *x diff --git a/src/tools/miri/tests/fail/dangling_pointers/storage_dead_dangling.rs b/src/tools/miri/tests/fail/dangling_pointers/storage_dead_dangling.rs index 366930a831c..f9983f48c61 100644 --- a/src/tools/miri/tests/fail/dangling_pointers/storage_dead_dangling.rs +++ b/src/tools/miri/tests/fail/dangling_pointers/storage_dead_dangling.rs @@ -1,5 +1,5 @@ -// This should fail even without validation, but some MIR opts mask the error -//@compile-flags: -Zmiri-disable-validation -Zmir-opt-level=0 -Zmiri-permissive-provenance +// This should fail even without validation +//@compile-flags: -Zmiri-disable-validation -Zmiri-permissive-provenance static mut LEAK: usize = 0; diff --git a/src/tools/miri/tests/fail/data_race/read_write_race_stack.rs b/src/tools/miri/tests/fail/data_race/read_write_race_stack.rs index 40224ced12d..c3e5c401d87 100644 --- a/src/tools/miri/tests/fail/data_race/read_write_race_stack.rs +++ b/src/tools/miri/tests/fail/data_race/read_write_race_stack.rs @@ -1,7 +1,4 @@ -//@compile-flags: -Zmir-opt-level=0 -Zmiri-disable-weak-memory-emulation -Zmiri-preemption-rate=0 -Zmiri-disable-stacked-borrows - -// Note: mir-opt-level set to 0 to prevent the read of stack_var in thread 1 -// from being optimized away and preventing the detection of the data-race. +//@compile-flags: -Zmiri-disable-weak-memory-emulation -Zmiri-preemption-rate=0 -Zmiri-disable-stacked-borrows use std::ptr::null_mut; use std::sync::atomic::{AtomicPtr, Ordering}; diff --git a/src/tools/miri/tests/fail/erroneous_const.rs b/src/tools/miri/tests/fail/erroneous_const.rs index d37837c7193..65f7aafc3cc 100644 --- a/src/tools/miri/tests/fail/erroneous_const.rs +++ b/src/tools/miri/tests/fail/erroneous_const.rs @@ -1,7 +1,5 @@ //! Make sure we detect erroneous constants post-monomorphization even when they are unused. //! (https://github.com/rust-lang/miri/issues/1382) -// Inlining changes the error location -//@compile-flags: -Zmir-opt-level=0 #![feature(never_type)] struct PrintName<T>(T); diff --git a/src/tools/miri/tests/fail/function_calls/arg_inplace_observe_after.rs b/src/tools/miri/tests/fail/function_calls/arg_inplace_observe_after.rs index 8eda913feb4..093b55759fd 100644 --- a/src/tools/miri/tests/fail/function_calls/arg_inplace_observe_after.rs +++ b/src/tools/miri/tests/fail/function_calls/arg_inplace_observe_after.rs @@ -5,9 +5,9 @@ pub struct S(i32); #[custom_mir(dialect = "runtime", phase = "optimized")] fn main() { - // FIXME: the span is not great (probably caused by custom MIR) - mir! { //~ERROR: uninitialized + mir! { let unit: (); + let _observe: i32; { let non_copy = S(42); // This could change `non_copy` in-place @@ -15,7 +15,7 @@ fn main() { } after_call = { // So now we must not be allowed to observe non-copy again. - let _observe = non_copy.0; + _observe = non_copy.0; //~ERROR: uninitialized Return() } diff --git a/src/tools/miri/tests/fail/function_calls/arg_inplace_observe_after.stderr b/src/tools/miri/tests/fail/function_calls/arg_inplace_observe_after.stderr index 3ff7976c70b..5d9a3af0c8a 100644 --- a/src/tools/miri/tests/fail/function_calls/arg_inplace_observe_after.stderr +++ b/src/tools/miri/tests/fail/function_calls/arg_inplace_observe_after.stderr @@ -1,20 +1,13 @@ error: Undefined Behavior: using uninitialized data, but this operation requires initialized memory --> $DIR/arg_inplace_observe_after.rs:LL:CC | -LL | / mir! { -LL | | let unit: (); -LL | | { -LL | | let non_copy = S(42); -... | -LL | | -LL | | } - | |_____^ using uninitialized data, but this operation requires initialized memory +LL | _observe = non_copy.0; + | ^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information = note: BACKTRACE: - = note: inside `main` at RUSTLIB/core/src/intrinsics/mir.rs:LL:CC - = note: this error originates in the macro `::core::intrinsics::mir::__internal_remove_let` which comes from the expansion of the macro `mir` (in Nightly builds, run with -Z macro-backtrace for more info) + = note: inside `main` at $DIR/arg_inplace_observe_after.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/src/tools/miri/tests/fail/unaligned_pointers/dyn_alignment.rs b/src/tools/miri/tests/fail/unaligned_pointers/dyn_alignment.rs index 555aa57de30..b5a9b2bf18e 100644 --- a/src/tools/miri/tests/fail/unaligned_pointers/dyn_alignment.rs +++ b/src/tools/miri/tests/fail/unaligned_pointers/dyn_alignment.rs @@ -1,5 +1,5 @@ // should find the bug even without, but gets masked by optimizations -//@compile-flags: -Zmiri-disable-stacked-borrows -Zmir-opt-level=0 -Cdebug-assertions=no +//@compile-flags: -Zmiri-disable-stacked-borrows -Cdebug-assertions=no //@normalize-stderr-test: "but found [0-9]+" -> "but found $$ALIGN" #[repr(align(256))] diff --git a/src/tools/miri/tests/fail/unaligned_pointers/unaligned_ptr_zst.rs b/src/tools/miri/tests/fail/unaligned_pointers/unaligned_ptr_zst.rs index 04dbe3fd8d4..289536287a9 100644 --- a/src/tools/miri/tests/fail/unaligned_pointers/unaligned_ptr_zst.rs +++ b/src/tools/miri/tests/fail/unaligned_pointers/unaligned_ptr_zst.rs @@ -1,6 +1,5 @@ // This should fail even without validation -// Some optimizations remove ZST accesses, thus masking this UB. -//@compile-flags: -Zmir-opt-level=0 -Zmiri-disable-validation -Cdebug-assertions=no +//@compile-flags: -Zmiri-disable-validation -Cdebug-assertions=no fn main() { // Try many times as this might work by chance. diff --git a/src/tools/miri/tests/fail/validity/nonzero.rs b/src/tools/miri/tests/fail/validity/nonzero.rs index 384c94a5569..7cba90bc15d 100644 --- a/src/tools/miri/tests/fail/validity/nonzero.rs +++ b/src/tools/miri/tests/fail/validity/nonzero.rs @@ -1,5 +1,3 @@ -// gets masked by optimizations -//@compile-flags: -Zmir-opt-level=0 #![feature(rustc_attrs)] #![allow(unused_attributes)] diff --git a/src/tools/miri/tests/fail/zst2.rs b/src/tools/miri/tests/fail/zst2.rs index 82470866f17..1d3e8ea9d00 100644 --- a/src/tools/miri/tests/fail/zst2.rs +++ b/src/tools/miri/tests/fail/zst2.rs @@ -1,6 +1,3 @@ -// Some optimizations remove ZST accesses, thus masking this UB. -//@compile-flags: -Zmir-opt-level=0 - fn main() { // Not using the () type here, as writes of that type do not even have MIR generated. // Also not assigning directly as that's array initialization, not assignment. diff --git a/src/tools/miri/tests/fail/zst3.rs b/src/tools/miri/tests/fail/zst3.rs index a511f38998f..454bef25f22 100644 --- a/src/tools/miri/tests/fail/zst3.rs +++ b/src/tools/miri/tests/fail/zst3.rs @@ -1,6 +1,3 @@ -// Some optimizations remove ZST accesses, thus masking this UB. -//@compile-flags: -Zmir-opt-level=0 - fn main() { // Not using the () type here, as writes of that type do not even have MIR generated. // Also not assigning directly as that's array initialization, not assignment. diff --git a/src/tools/opt-dist/src/main.rs b/src/tools/opt-dist/src/main.rs index 39fa7e1fb2a..6fc3c3b64a8 100644 --- a/src/tools/opt-dist/src/main.rs +++ b/src/tools/opt-dist/src/main.rs @@ -7,7 +7,10 @@ use crate::tests::run_tests; use crate::timer::Timer; use crate::training::{gather_llvm_bolt_profiles, gather_llvm_profiles, gather_rustc_profiles}; use crate::utils::io::reset_directory; -use crate::utils::{clear_llvm_files, format_env_variables, print_free_disk_space}; +use crate::utils::{ + clear_llvm_files, format_env_variables, print_binary_sizes, print_free_disk_space, + with_log_group, +}; mod environment; mod exec; @@ -27,7 +30,8 @@ fn execute_pipeline( dist_args: Vec<String>, ) -> anyhow::Result<()> { reset_directory(&env.opt_artifacts())?; - env.prepare_rustc_perf()?; + + with_log_group("Building rustc-perf", || env.prepare_rustc_perf())?; // Stage 1: Build PGO instrumented rustc // We use a normal build of LLVM, because gathering PGO profiles for LLVM and `rustc` at the @@ -139,12 +143,17 @@ fn main() -> anyhow::Result<()> { .init(); let mut build_args: Vec<String> = std::env::args().skip(1).collect(); - log::info!("Running optimized build pipeline with args `{}`", build_args.join(" ")); - log::info!("Environment values\n{}", format_env_variables()); + println!("Running optimized build pipeline with args `{}`", build_args.join(" ")); - if let Ok(config) = std::fs::read_to_string("config.toml") { - log::info!("Contents of `config.toml`:\n{config}"); - } + with_log_group("Environment values", || { + println!("Environment values\n{}", format_env_variables()); + }); + + with_log_group("Printing config.toml", || { + if let Ok(config) = std::fs::read_to_string("config.toml") { + println!("Contents of `config.toml`:\n{config}"); + } + }); // Skip components that are not needed for try builds to speed them up if is_try_build() { @@ -170,6 +179,8 @@ fn main() -> anyhow::Result<()> { log::info!("Timer results\n{}", timer.format_stats()); print_free_disk_space()?; + result.context("Optimized build pipeline has failed")?; + print_binary_sizes(env.as_ref())?; - result.context("Optimized build pipeline has failed") + Ok(()) } diff --git a/src/tools/opt-dist/src/training.rs b/src/tools/opt-dist/src/training.rs index 10f4a603695..951bc6f9264 100644 --- a/src/tools/opt-dist/src/training.rs +++ b/src/tools/opt-dist/src/training.rs @@ -1,6 +1,7 @@ use crate::environment::Environment; use crate::exec::{cmd, CmdBuilder}; use crate::utils::io::{count_files, delete_directory}; +use crate::utils::with_log_group; use anyhow::Context; use camino::{Utf8Path, Utf8PathBuf}; use humansize::BINARY; @@ -108,9 +109,11 @@ pub fn gather_llvm_profiles( ) -> anyhow::Result<LlvmPGOProfile> { log::info!("Running benchmarks with PGO instrumented LLVM"); - init_compiler_benchmarks(env, &["Debug", "Opt"], &["Full"], LLVM_PGO_CRATES) - .run() - .context("Cannot gather LLVM PGO profiles")?; + with_log_group("Running benchmarks", || { + init_compiler_benchmarks(env, &["Debug", "Opt"], &["Full"], LLVM_PGO_CRATES) + .run() + .context("Cannot gather LLVM PGO profiles") + })?; let merged_profile = env.opt_artifacts().join("llvm-pgo.profdata"); log::info!("Merging LLVM PGO profiles to {merged_profile}"); @@ -141,10 +144,12 @@ pub fn gather_rustc_profiles( // Here we're profiling the `rustc` frontend, so we also include `Check`. // The benchmark set includes various stress tests that put the frontend under pressure. - init_compiler_benchmarks(env, &["Check", "Debug", "Opt"], &["All"], RUSTC_PGO_CRATES) - .env("LLVM_PROFILE_FILE", profile_template.as_str()) - .run() - .context("Cannot gather rustc PGO profiles")?; + with_log_group("Running benchmarks", || { + init_compiler_benchmarks(env, &["Check", "Debug", "Opt"], &["All"], RUSTC_PGO_CRATES) + .env("LLVM_PROFILE_FILE", profile_template.as_str()) + .run() + .context("Cannot gather rustc PGO profiles") + })?; let merged_profile = env.opt_artifacts().join("rustc-pgo.profdata"); log::info!("Merging Rustc PGO profiles to {merged_profile}"); @@ -164,9 +169,11 @@ pub struct LlvmBoltProfile(pub Utf8PathBuf); pub fn gather_llvm_bolt_profiles(env: &dyn Environment) -> anyhow::Result<LlvmBoltProfile> { log::info!("Running benchmarks with BOLT instrumented LLVM"); - init_compiler_benchmarks(env, &["Check", "Debug", "Opt"], &["Full"], LLVM_BOLT_CRATES) - .run() - .context("Cannot gather LLVM BOLT profiles")?; + with_log_group("Running benchmarks", || { + init_compiler_benchmarks(env, &["Check", "Debug", "Opt"], &["Full"], LLVM_BOLT_CRATES) + .run() + .context("Cannot gather LLVM BOLT profiles") + })?; let merged_profile = env.opt_artifacts().join("bolt.profdata"); let profile_root = Utf8PathBuf::from("/tmp/prof.fdata"); @@ -178,10 +185,12 @@ pub fn gather_llvm_bolt_profiles(env: &dyn Environment) -> anyhow::Result<LlvmBo let mut merge_args = vec!["merge-fdata"]; merge_args.extend(profiles.iter().map(|p| p.to_str().unwrap())); - cmd(&merge_args) - .redirect_output(merged_profile.clone()) - .run() - .context("Cannot merge BOLT profiles")?; + with_log_group("Merging BOLT profiles", || { + cmd(&merge_args) + .redirect_output(merged_profile.clone()) + .run() + .context("Cannot merge BOLT profiles") + })?; log::info!("LLVM BOLT statistics"); log::info!( diff --git a/src/tools/opt-dist/src/utils/io.rs b/src/tools/opt-dist/src/utils/io.rs index 43546e5fcfa..aab078067af 100644 --- a/src/tools/opt-dist/src/utils/io.rs +++ b/src/tools/opt-dist/src/utils/io.rs @@ -1,5 +1,5 @@ use anyhow::Context; -use camino::Utf8Path; +use camino::{Utf8Path, Utf8PathBuf}; use fs_extra::dir::CopyOptions; use std::fs::File; @@ -46,3 +46,17 @@ pub fn unpack_archive(path: &Utf8Path, dest_dir: &Utf8Path) -> anyhow::Result<() archive.unpack(dest_dir.as_std_path())?; Ok(()) } + +/// Returns paths in the given `dir` (non-recursively), optionally with the given `suffix`. +/// The `suffix` should contain the leading dot. +pub fn get_files_from_dir( + dir: &Utf8Path, + suffix: Option<&str>, +) -> anyhow::Result<Vec<Utf8PathBuf>> { + let path = format!("{dir}/*{}", suffix.unwrap_or("")); + + Ok(glob::glob(&path)? + .into_iter() + .map(|p| p.map(|p| Utf8PathBuf::from_path_buf(p).unwrap())) + .collect::<Result<Vec<_>, _>>()?) +} diff --git a/src/tools/opt-dist/src/utils/mod.rs b/src/tools/opt-dist/src/utils/mod.rs index 9305d4989aa..9a3df15e302 100644 --- a/src/tools/opt-dist/src/utils/mod.rs +++ b/src/tools/opt-dist/src/utils/mod.rs @@ -1,8 +1,8 @@ pub mod io; use crate::environment::Environment; -use crate::utils::io::delete_directory; -use humansize::BINARY; +use crate::utils::io::{delete_directory, get_files_from_dir}; +use humansize::{format_size, BINARY}; use sysinfo::{DiskExt, RefreshKind, System, SystemExt}; pub fn format_env_variables() -> String { @@ -25,6 +25,28 @@ pub fn print_free_disk_space() -> anyhow::Result<()> { Ok(()) } +pub fn print_binary_sizes(env: &dyn Environment) -> anyhow::Result<()> { + use std::fmt::Write; + + let root = env.build_artifacts().join("stage2"); + + let mut files = get_files_from_dir(&root.join("bin"), None)?; + files.extend(get_files_from_dir(&root.join("lib"), Some(".so"))?); + files.sort_unstable(); + + let mut output = String::new(); + for file in files { + let size = std::fs::metadata(file.as_std_path())?.len(); + let size_formatted = format_size(size, BINARY); + let name = format!("{}:", file.file_name().unwrap()); + writeln!(output, "{name:<50}{size_formatted:>10}")?; + } + + log::info!("Rustc artifact size\n{output}"); + + Ok(()) +} + pub fn clear_llvm_files(env: &dyn Environment) -> anyhow::Result<()> { // Bootstrap currently doesn't support rebuilding LLVM when PGO options // change (or any other llvm-related options); so just clear out the relevant @@ -34,3 +56,20 @@ pub fn clear_llvm_files(env: &dyn Environment) -> anyhow::Result<()> { delete_directory(&env.build_artifacts().join("lld"))?; Ok(()) } + +/// Wraps all output produced within the `func` closure in a CI output group, if we're running in +/// CI. +pub fn with_log_group<F: FnOnce() -> R, R>(group: &str, func: F) -> R { + if is_in_ci() { + println!("::group::{group}"); + let result = func(); + println!("::endgroup::"); + result + } else { + func() + } +} + +fn is_in_ci() -> bool { + std::env::var("GITHUB_ACTIONS").is_ok() +} |
