diff options
Diffstat (limited to 'src')
720 files changed, 11426 insertions, 4503 deletions
diff --git a/src/bootstrap/Cargo.toml b/src/bootstrap/Cargo.toml index 4c32547f059..dea8d998bde 100644 --- a/src/bootstrap/Cargo.toml +++ b/src/bootstrap/Cargo.toml @@ -42,10 +42,12 @@ cc = "1.0.69" libc = "0.2" serde = { version = "1.0.8", features = ["derive"] } serde_json = "1.0.2" +tar = "0.4" toml = "0.5" ignore = "0.4.10" opener = "0.5" once_cell = "1.7.2" +xz2 = "0.1" [target.'cfg(windows)'.dependencies.winapi] version = "0.3" diff --git a/src/bootstrap/bin/rustdoc.rs b/src/bootstrap/bin/rustdoc.rs index 0349277a36b..5f85fc5aa59 100644 --- a/src/bootstrap/bin/rustdoc.rs +++ b/src/bootstrap/bin/rustdoc.rs @@ -31,8 +31,8 @@ fn main() { let mut cmd = Command::new(rustdoc); - // I am not actually sure why it's necessary to pass the sysroot for `--test`, - // but `test --doc --stage 0` is broken without it :( + // cfg(bootstrap) + // NOTE: the `--test` special-casing can be removed when https://github.com/rust-lang/cargo/pull/10594 lands on beta. if target.is_some() || args.iter().any(|x| x == "--test") { // The stage0 compiler has a special sysroot distinct from what we // actually downloaded, so we just always pass the `--sysroot` option, @@ -65,13 +65,6 @@ fn main() { } } - // Needed to be able to run all rustdoc tests. - if let Some(ref x) = env::var_os("RUSTDOC_RESOURCE_SUFFIX") { - // This "unstable-options" can be removed when `--resource-suffix` is stabilized - cmd.arg("-Z").arg("unstable-options"); - cmd.arg("--resource-suffix").arg(x); - } - if verbose > 1 { eprintln!( "rustdoc command: {:?}={:?} {:?}", diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py index ac1c47524fd..e38a574ca23 100644 --- a/src/bootstrap/bootstrap.py +++ b/src/bootstrap/bootstrap.py @@ -500,81 +500,6 @@ class RustBuild(object): with output(self.rustfmt_stamp()) as rustfmt_stamp: rustfmt_stamp.write(self.stage0_rustfmt.channel()) - # Avoid downloading LLVM twice (once for stage0 and once for the master rustc) - if self.downloading_llvm() and stage0: - # We want the most recent LLVM submodule update to avoid downloading - # LLVM more often than necessary. - # - # This git command finds that commit SHA, looking for bors-authored - # commits that modified src/llvm-project or other relevant version - # stamp files. - # - # This works even in a repository that has not yet initialized - # submodules. - top_level = subprocess.check_output([ - "git", "rev-parse", "--show-toplevel", - ]).decode(sys.getdefaultencoding()).strip() - llvm_sha = subprocess.check_output([ - "git", "rev-list", "--author=bors@rust-lang.org", "-n1", - "--first-parent", "HEAD", - "--", - "{}/src/llvm-project".format(top_level), - "{}/src/bootstrap/download-ci-llvm-stamp".format(top_level), - # the LLVM shared object file is named `LLVM-12-rust-{version}-nightly` - "{}/src/version".format(top_level) - ]).decode(sys.getdefaultencoding()).strip() - llvm_assertions = self.get_toml('assertions', 'llvm') == 'true' - llvm_root = self.llvm_root() - llvm_lib = os.path.join(llvm_root, "lib") - if self.program_out_of_date(self.llvm_stamp(), llvm_sha + str(llvm_assertions)): - self._download_ci_llvm(llvm_sha, llvm_assertions) - for binary in ["llvm-config", "FileCheck"]: - self.fix_bin_or_dylib(os.path.join(llvm_root, "bin", binary)) - for lib in os.listdir(llvm_lib): - if lib.endswith(".so"): - self.fix_bin_or_dylib(os.path.join(llvm_lib, lib)) - with output(self.llvm_stamp()) as llvm_stamp: - llvm_stamp.write(llvm_sha + str(llvm_assertions)) - - def downloading_llvm(self): - opt = self.get_toml('download-ci-llvm', 'llvm') - # This is currently all tier 1 targets and tier 2 targets with host tools - # (since others may not have CI artifacts) - # https://doc.rust-lang.org/rustc/platform-support.html#tier-1 - supported_platforms = [ - # tier 1 - "aarch64-unknown-linux-gnu", - "i686-pc-windows-gnu", - "i686-pc-windows-msvc", - "i686-unknown-linux-gnu", - "x86_64-unknown-linux-gnu", - "x86_64-apple-darwin", - "x86_64-pc-windows-gnu", - "x86_64-pc-windows-msvc", - # tier 2 with host tools - "aarch64-apple-darwin", - "aarch64-pc-windows-msvc", - "aarch64-unknown-linux-musl", - "arm-unknown-linux-gnueabi", - "arm-unknown-linux-gnueabihf", - "armv7-unknown-linux-gnueabihf", - "mips-unknown-linux-gnu", - "mips64-unknown-linux-gnuabi64", - "mips64el-unknown-linux-gnuabi64", - "mipsel-unknown-linux-gnu", - "powerpc-unknown-linux-gnu", - "powerpc64-unknown-linux-gnu", - "powerpc64le-unknown-linux-gnu", - "riscv64gc-unknown-linux-gnu", - "s390x-unknown-linux-gnu", - "x86_64-unknown-freebsd", - "x86_64-unknown-illumos", - "x86_64-unknown-linux-musl", - "x86_64-unknown-netbsd", - ] - return opt == "true" \ - or (opt == "if-available" and self.build in supported_platforms) - def _download_component_helper( self, filename, pattern, tarball_suffix, stage0=True, key=None ): @@ -606,53 +531,6 @@ class RustBuild(object): ) unpack(tarball, tarball_suffix, self.bin_root(stage0), match=pattern, verbose=self.verbose) - def _download_ci_llvm(self, llvm_sha, llvm_assertions): - if not llvm_sha: - print("error: could not find commit hash for downloading LLVM") - print("help: maybe your repository history is too shallow?") - print("help: consider disabling `download-ci-llvm`") - print("help: or fetch enough history to include one upstream commit") - exit(1) - cache_prefix = "llvm-{}-{}".format(llvm_sha, llvm_assertions) - cache_dst = os.path.join(self.build_dir, "cache") - rustc_cache = os.path.join(cache_dst, cache_prefix) - if not os.path.exists(rustc_cache): - os.makedirs(rustc_cache) - - base = "https://ci-artifacts.rust-lang.org" - url = "rustc-builds/{}".format(llvm_sha) - if llvm_assertions: - url = url.replace('rustc-builds', 'rustc-builds-alt') - # ci-artifacts are only stored as .xz, not .gz - if not support_xz(): - print("error: XZ support is required to download LLVM") - print("help: consider disabling `download-ci-llvm` or using python3") - exit(1) - tarball_suffix = '.tar.xz' - filename = "rust-dev-nightly-" + self.build + tarball_suffix - tarball = os.path.join(rustc_cache, filename) - if not os.path.exists(tarball): - help_on_error = "error: failed to download llvm from ci" - help_on_error += "\nhelp: old builds get deleted after a certain time" - help_on_error += "\nhelp: if trying to compile an old commit of rustc," - help_on_error += " disable `download-ci-llvm` in config.toml:" - help_on_error += "\n" - help_on_error += "\n[llvm]" - help_on_error += "\ndownload-ci-llvm = false" - help_on_error += "\n" - get( - base, - "{}/{}".format(url, filename), - tarball, - self.checksums_sha256, - verbose=self.verbose, - do_verify=False, - help_on_error=help_on_error, - ) - unpack(tarball, tarball_suffix, self.llvm_root(), - match="rust-dev", - verbose=self.verbose) - def fix_bin_or_dylib(self, fname): """Modifies the interpreter section of 'fname' to fix the dynamic linker, or the RPATH section, to fix the dynamic library search path @@ -816,17 +694,6 @@ class RustBuild(object): """ return os.path.join(self.bin_root(True), '.rustfmt-stamp') - def llvm_stamp(self): - """Return the path for .llvm-stamp - - >>> rb = RustBuild() - >>> rb.build_dir = "build" - >>> rb.llvm_stamp() == os.path.join("build", "ci-llvm", ".llvm-stamp") - True - """ - return os.path.join(self.llvm_root(), '.llvm-stamp') - - def program_out_of_date(self, stamp_path, key): """Check if the given program stamp is out of date""" if not os.path.exists(stamp_path) or self.clean: @@ -856,22 +723,6 @@ class RustBuild(object): subdir = "ci-rustc" return os.path.join(self.build_dir, self.build, subdir) - def llvm_root(self): - """Return the CI LLVM root directory - - >>> rb = RustBuild() - >>> rb.build_dir = "build" - >>> rb.llvm_root() == os.path.join("build", "ci-llvm") - True - - When the 'build' property is given should be a nested directory: - - >>> rb.build = "devel" - >>> rb.llvm_root() == os.path.join("build", "devel", "ci-llvm") - True - """ - return os.path.join(self.build_dir, self.build, "ci-llvm") - def get_toml(self, key, section=None): """Returns the value of the given key in config.toml, otherwise returns None diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index d688f798956..dd45bd3a213 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -1,9 +1,9 @@ -use std::any::Any; +use std::any::{type_name, Any}; use std::cell::{Cell, RefCell}; use std::collections::BTreeSet; use std::env; use std::ffi::OsStr; -use std::fmt::Debug; +use std::fmt::{Debug, Write}; use std::fs; use std::hash::Hash; use std::ops::Deref; @@ -12,9 +12,8 @@ use std::process::Command; use std::time::{Duration, Instant}; use crate::cache::{Cache, Interned, INTERNER}; -use crate::check; use crate::compile; -use crate::config::TargetSelection; +use crate::config::{SplitDebuginfo, TargetSelection}; use crate::dist; use crate::doc; use crate::flags::{Color, Subcommand}; @@ -25,6 +24,7 @@ use crate::test; use crate::tool::{self, SourceType}; use crate::util::{self, add_dylib_path, add_link_lib_path, exe, libdir, output, t}; use crate::EXTRA_CHECK_CFGS; +use crate::{check, Config}; use crate::{Build, CLang, DocTests, GitRepo, Mode}; pub use crate::Compiler; @@ -125,7 +125,8 @@ impl TaskPath { if found_kind.is_empty() { panic!("empty kind in task path {}", path.display()); } - kind = Some(Kind::parse(found_kind)); + kind = Kind::parse(found_kind); + assert!(kind.is_some()); path = Path::new(found_prefix).join(components.as_path()); } } @@ -388,11 +389,13 @@ impl<'a> ShouldRun<'a> { paths .iter() .map(|p| { - assert!( - self.builder.src.join(p).exists(), - "`should_run.paths` should correspond to real on-disk paths - use `alias` if there is no relevant path: {}", - p - ); + // FIXME(#96188): make sure this is actually a path. + // This currently breaks for paths within submodules. + //assert!( + // self.builder.src.join(p).exists(), + // "`should_run.paths` should correspond to real on-disk paths - use `alias` if there is no relevant path: {}", + // p + //); TaskPath { path: p.into(), kind: Some(self.kind) } }) .collect(), @@ -429,43 +432,53 @@ pub enum Kind { Check, Clippy, Fix, + Format, Test, Bench, - Dist, Doc, + Clean, + Dist, Install, Run, + Setup, } impl Kind { - fn parse(string: &str) -> Kind { - match string { - "build" => Kind::Build, - "check" => Kind::Check, + pub fn parse(string: &str) -> Option<Kind> { + // these strings, including the one-letter aliases, must match the x.py help text + Some(match string { + "build" | "b" => Kind::Build, + "check" | "c" => Kind::Check, "clippy" => Kind::Clippy, "fix" => Kind::Fix, - "test" => Kind::Test, + "fmt" => Kind::Format, + "test" | "t" => Kind::Test, "bench" => Kind::Bench, + "doc" | "d" => Kind::Doc, + "clean" => Kind::Clean, "dist" => Kind::Dist, - "doc" => Kind::Doc, "install" => Kind::Install, - "run" => Kind::Run, - other => panic!("unknown kind: {}", other), - } + "run" | "r" => Kind::Run, + "setup" => Kind::Setup, + _ => return None, + }) } - fn as_str(&self) -> &'static str { + pub fn as_str(&self) -> &'static str { match self { Kind::Build => "build", Kind::Check => "check", Kind::Clippy => "clippy", Kind::Fix => "fix", + Kind::Format => "fmt", Kind::Test => "test", Kind::Bench => "bench", - Kind::Dist => "dist", Kind::Doc => "doc", + Kind::Clean => "clean", + Kind::Dist => "dist", Kind::Install => "install", Kind::Run => "run", + Kind::Setup => "setup", } } } @@ -509,7 +522,7 @@ impl<'a> Builder<'a> { native::Lld, native::CrtBeginEnd ), - Kind::Check | Kind::Clippy { .. } | Kind::Fix => describe!( + Kind::Check => describe!( check::Std, check::Rustc, check::Rustdoc, @@ -639,32 +652,29 @@ impl<'a> Builder<'a> { install::Rustc ), Kind::Run => describe!(run::ExpandYamlAnchors, run::BuildManifest, run::BumpStage0), + // These commands either don't use paths, or they're special-cased in Build::build() + Kind::Clean | Kind::Clippy | Kind::Fix | Kind::Format | Kind::Setup => vec![], } } - pub fn get_help(build: &Build, subcommand: &str) -> Option<String> { - let kind = match subcommand { - "build" | "b" => Kind::Build, - "doc" | "d" => Kind::Doc, - "test" | "t" => Kind::Test, - "bench" => Kind::Bench, - "dist" => Kind::Dist, - "install" => Kind::Install, - _ => return None, - }; + pub fn get_help(build: &Build, kind: Kind) -> Option<String> { + let step_descriptions = Builder::get_step_descriptions(kind); + if step_descriptions.is_empty() { + return None; + } let builder = Self::new_internal(build, kind, vec![]); let builder = &builder; // The "build" kind here is just a placeholder, it will be replaced with something else in // the following statement. let mut should_run = ShouldRun::new(builder, Kind::Build); - for desc in Builder::get_step_descriptions(builder.kind) { + for desc in step_descriptions { should_run.kind = desc.kind; should_run = (desc.should_run)(should_run); } let mut help = String::from("Available paths:\n"); let mut add_path = |path: &Path| { - help.push_str(&format!(" ./x.py {} {}\n", subcommand, path.display())); + t!(write!(help, " ./x.py {} {}\n", kind.as_str(), path.display())); }; for pathset in should_run.paths { match pathset { @@ -950,6 +960,11 @@ impl<'a> Builder<'a> { None } + /// Convenience wrapper to allow `builder.llvm_link_shared()` instead of `builder.config.llvm_link_shared(&builder)`. + pub(crate) fn llvm_link_shared(&self) -> bool { + Config::llvm_link_shared(self) + } + /// Prepares an invocation of `cargo` to be run. /// /// This will create a `Command` that represents a pending execution of @@ -1388,17 +1403,17 @@ impl<'a> Builder<'a> { }, ); - // `dsymutil` adds time to builds on Apple platforms for no clear benefit, and also makes - // it more difficult for debuggers to find debug info. The compiler currently defaults to - // running `dsymutil` to preserve its historical default, but when compiling the compiler - // itself, we skip it by default since we know it's safe to do so in that case. - // See https://github.com/rust-lang/rust/issues/79361 for more info on this flag. - if target.contains("apple") { - if self.config.rust_run_dsymutil { - rustflags.arg("-Csplit-debuginfo=packed"); - } else { - rustflags.arg("-Csplit-debuginfo=unpacked"); + // FIXME(davidtwco): #[cfg(not(bootstrap))] - #95612 needs to be in the bootstrap compiler + // for this conditional to be removed. + if !target.contains("windows") || compiler.stage >= 1 { + if target.contains("linux") || target.contains("windows") { + rustflags.arg("-Zunstable-options"); } + match self.config.rust_split_debuginfo { + SplitDebuginfo::Packed => rustflags.arg("-Csplit-debuginfo=packed"), + SplitDebuginfo::Unpacked => rustflags.arg("-Csplit-debuginfo=unpacked"), + SplitDebuginfo::Off => rustflags.arg("-Csplit-debuginfo=off"), + }; } if self.config.cmd.bless() { @@ -1753,7 +1768,16 @@ impl<'a> Builder<'a> { }; if self.config.print_step_timings && !self.config.dry_run { - println!("[TIMING] {:?} -- {}.{:03}", step, dur.as_secs(), dur.subsec_millis()); + let step_string = format!("{:?}", step); + let brace_index = step_string.find("{").unwrap_or(0); + let type_string = type_name::<S>(); + println!( + "[TIMING] {} {} -- {}.{:03}", + &type_string.strip_prefix("bootstrap::").unwrap_or(type_string), + &step_string[brace_index..], + dur.as_secs(), + dur.subsec_millis() + ); } { diff --git a/src/bootstrap/builder/tests.rs b/src/bootstrap/builder/tests.rs index a59f72ed968..3b6cd7564f0 100644 --- a/src/bootstrap/builder/tests.rs +++ b/src/bootstrap/builder/tests.rs @@ -7,6 +7,7 @@ fn configure(cmd: &str, host: &[&str], target: &[&str]) -> Config { // don't save toolstates config.save_toolstates = None; config.dry_run = true; + config.submodules = Some(false); config.ninja_in_file = false; // try to avoid spurious failures in dist where we create/delete each others file // HACK: rather than pull in `tempdir`, use the one that cargo has conveniently created for us @@ -25,36 +26,74 @@ fn first<A, B>(v: Vec<(A, B)>) -> Vec<A> { v.into_iter().map(|(a, _)| a).collect::<Vec<_>>() } +fn run_build(paths: &[PathBuf], config: Config) -> Cache { + let kind = config.cmd.kind(); + let build = Build::new(config); + let builder = Builder::new(&build); + builder.run_step_descriptions(&Builder::get_step_descriptions(kind), paths); + builder.cache +} + +#[test] +fn test_exclude() { + let mut config = configure("test", &["A"], &["A"]); + config.exclude = vec![TaskPath::parse("src/tools/tidy")]; + let cache = run_build(&[], config); + + // Ensure we have really excluded tidy + assert!(!cache.contains::<test::Tidy>()); + + // Ensure other tests are not affected. + assert!(cache.contains::<test::RustdocUi>()); +} + +#[test] +fn test_exclude_kind() { + let path = PathBuf::from("src/tools/cargotest"); + let exclude = TaskPath::parse("test::src/tools/cargotest"); + assert_eq!(exclude, TaskPath { kind: Some(Kind::Test), path: path.clone() }); + + let mut config = configure("test", &["A"], &["A"]); + // Ensure our test is valid, and `test::Cargotest` would be run without the exclude. + assert!(run_build(&[path.clone()], config.clone()).contains::<test::Cargotest>()); + // Ensure tests for cargotest are skipped. + config.exclude = vec![exclude.clone()]; + assert!(!run_build(&[path.clone()], config).contains::<test::Cargotest>()); + + // Ensure builds for cargotest are not skipped. + let mut config = configure("build", &["A"], &["A"]); + config.exclude = vec![exclude]; + assert!(run_build(&[path], config).contains::<tool::CargoTest>()); +} + mod defaults { - use super::{configure, first}; + use super::{configure, first, run_build}; use crate::builder::*; use crate::Config; use pretty_assertions::assert_eq; #[test] fn build_default() { - let build = Build::new(configure("build", &["A"], &["A"])); - let mut builder = Builder::new(&build); - builder.run_step_descriptions(&Builder::get_step_descriptions(Kind::Build), &[]); + let mut cache = run_build(&[], configure("build", &["A"], &["A"])); let a = TargetSelection::from_user("A"); assert_eq!( - first(builder.cache.all::<compile::Std>()), + first(cache.all::<compile::Std>()), &[ compile::Std { compiler: Compiler { host: a, stage: 0 }, target: a }, compile::Std { compiler: Compiler { host: a, stage: 1 }, target: a }, ] ); - assert!(!builder.cache.all::<compile::Assemble>().is_empty()); + assert!(!cache.all::<compile::Assemble>().is_empty()); // Make sure rustdoc is only built once. assert_eq!( - first(builder.cache.all::<tool::Rustdoc>()), + first(cache.all::<tool::Rustdoc>()), // Recall that rustdoc stages are off-by-one // - this is the compiler it's _linked_ to, not built with. &[tool::Rustdoc { compiler: Compiler { host: a, stage: 1 } }], ); assert_eq!( - first(builder.cache.all::<compile::Rustc>()), + first(cache.all::<compile::Rustc>()), &[compile::Rustc { compiler: Compiler { host: a, stage: 0 }, target: a },] ); } @@ -62,31 +101,27 @@ mod defaults { #[test] fn build_stage_0() { let config = Config { stage: 0, ..configure("build", &["A"], &["A"]) }; - let build = Build::new(config); - let mut builder = Builder::new(&build); - builder.run_step_descriptions(&Builder::get_step_descriptions(Kind::Build), &[]); + let mut cache = run_build(&[], config); let a = TargetSelection::from_user("A"); assert_eq!( - first(builder.cache.all::<compile::Std>()), + first(cache.all::<compile::Std>()), &[compile::Std { compiler: Compiler { host: a, stage: 0 }, target: a },] ); - assert!(!builder.cache.all::<compile::Assemble>().is_empty()); + assert!(!cache.all::<compile::Assemble>().is_empty()); assert_eq!( - first(builder.cache.all::<tool::Rustdoc>()), + first(cache.all::<tool::Rustdoc>()), // This is the beta rustdoc. // Add an assert here to make sure this is the only rustdoc built. &[tool::Rustdoc { compiler: Compiler { host: a, stage: 0 } }], ); - assert!(builder.cache.all::<compile::Rustc>().is_empty()); + assert!(cache.all::<compile::Rustc>().is_empty()); } #[test] fn build_cross_compile() { let config = Config { stage: 1, ..configure("build", &["A", "B"], &["A", "B"]) }; - let build = Build::new(config); - let mut builder = Builder::new(&build); - builder.run_step_descriptions(&Builder::get_step_descriptions(Kind::Build), &[]); + let mut cache = run_build(&[], config); let a = TargetSelection::from_user("A"); let b = TargetSelection::from_user("B"); @@ -97,7 +132,7 @@ mod defaults { // (since we're producing stage 1 libraries/binaries). But currently // rustbuild is just a bit buggy here; this should be fixed though. assert_eq!( - first(builder.cache.all::<compile::Std>()), + first(cache.all::<compile::Std>()), &[ compile::Std { compiler: Compiler { host: a, stage: 0 }, target: a }, compile::Std { compiler: Compiler { host: a, stage: 1 }, target: a }, @@ -106,7 +141,7 @@ mod defaults { ] ); assert_eq!( - first(builder.cache.all::<compile::Assemble>()), + first(cache.all::<compile::Assemble>()), &[ compile::Assemble { target_compiler: Compiler { host: a, stage: 0 } }, compile::Assemble { target_compiler: Compiler { host: a, stage: 1 } }, @@ -114,14 +149,14 @@ mod defaults { ] ); assert_eq!( - first(builder.cache.all::<tool::Rustdoc>()), + first(cache.all::<tool::Rustdoc>()), &[ tool::Rustdoc { compiler: Compiler { host: a, stage: 1 } }, tool::Rustdoc { compiler: Compiler { host: b, stage: 1 } }, ], ); assert_eq!( - first(builder.cache.all::<compile::Rustc>()), + first(cache.all::<compile::Rustc>()), &[ compile::Rustc { compiler: Compiler { host: a, stage: 0 }, target: a }, compile::Rustc { compiler: Compiler { host: a, stage: 0 }, target: b }, @@ -134,33 +169,28 @@ mod defaults { let mut config = configure("doc", &["A"], &["A"]); config.compiler_docs = true; config.cmd = Subcommand::Doc { paths: Vec::new(), open: false }; - let build = Build::new(config); - let mut builder = Builder::new(&build); - builder.run_step_descriptions(&Builder::get_step_descriptions(Kind::Doc), &[]); + let mut cache = run_build(&[], config); let a = TargetSelection::from_user("A"); // error_index_generator uses stage 0 to share rustdoc artifacts with the // rustdoc tool. + assert_eq!(first(cache.all::<doc::ErrorIndex>()), &[doc::ErrorIndex { target: a },]); assert_eq!( - first(builder.cache.all::<doc::ErrorIndex>()), - &[doc::ErrorIndex { target: a },] - ); - assert_eq!( - first(builder.cache.all::<tool::ErrorIndex>()), + first(cache.all::<tool::ErrorIndex>()), &[tool::ErrorIndex { compiler: Compiler { host: a, stage: 0 } }] ); // docs should be built with the beta compiler, not with the stage0 artifacts. // recall that rustdoc is off-by-one: `stage` is the compiler rustdoc is _linked_ to, // not the one it was built by. assert_eq!( - first(builder.cache.all::<tool::Rustdoc>()), + first(cache.all::<tool::Rustdoc>()), &[tool::Rustdoc { compiler: Compiler { host: a, stage: 0 } },] ); } } mod dist { - use super::{first, Config}; + use super::{first, run_build, Config}; use crate::builder::*; use pretty_assertions::assert_eq; @@ -170,94 +200,88 @@ mod dist { #[test] fn dist_baseline() { - let build = Build::new(configure(&["A"], &["A"])); - let mut builder = Builder::new(&build); - builder.run_step_descriptions(&Builder::get_step_descriptions(Kind::Dist), &[]); + let mut cache = run_build(&[], configure(&["A"], &["A"])); let a = TargetSelection::from_user("A"); - assert_eq!(first(builder.cache.all::<dist::Docs>()), &[dist::Docs { host: a },]); - assert_eq!(first(builder.cache.all::<dist::Mingw>()), &[dist::Mingw { host: a },]); + assert_eq!(first(cache.all::<dist::Docs>()), &[dist::Docs { host: a },]); + assert_eq!(first(cache.all::<dist::Mingw>()), &[dist::Mingw { host: a },]); assert_eq!( - first(builder.cache.all::<dist::Rustc>()), + first(cache.all::<dist::Rustc>()), &[dist::Rustc { compiler: Compiler { host: a, stage: 2 } },] ); assert_eq!( - first(builder.cache.all::<dist::Std>()), + first(cache.all::<dist::Std>()), &[dist::Std { compiler: Compiler { host: a, stage: 1 }, target: a },] ); - assert_eq!(first(builder.cache.all::<dist::Src>()), &[dist::Src]); + assert_eq!(first(cache.all::<dist::Src>()), &[dist::Src]); // Make sure rustdoc is only built once. assert_eq!( - first(builder.cache.all::<tool::Rustdoc>()), + first(cache.all::<tool::Rustdoc>()), &[tool::Rustdoc { compiler: Compiler { host: a, stage: 2 } },] ); } #[test] fn dist_with_targets() { - let build = Build::new(configure(&["A"], &["A", "B"])); - let mut builder = Builder::new(&build); - builder.run_step_descriptions(&Builder::get_step_descriptions(Kind::Dist), &[]); + let mut cache = run_build(&[], configure(&["A"], &["A", "B"])); let a = TargetSelection::from_user("A"); let b = TargetSelection::from_user("B"); assert_eq!( - first(builder.cache.all::<dist::Docs>()), + first(cache.all::<dist::Docs>()), &[dist::Docs { host: a }, dist::Docs { host: b },] ); assert_eq!( - first(builder.cache.all::<dist::Mingw>()), + first(cache.all::<dist::Mingw>()), &[dist::Mingw { host: a }, dist::Mingw { host: b },] ); assert_eq!( - first(builder.cache.all::<dist::Rustc>()), + first(cache.all::<dist::Rustc>()), &[dist::Rustc { compiler: Compiler { host: a, stage: 2 } },] ); assert_eq!( - first(builder.cache.all::<dist::Std>()), + first(cache.all::<dist::Std>()), &[ dist::Std { compiler: Compiler { host: a, stage: 1 }, target: a }, dist::Std { compiler: Compiler { host: a, stage: 2 }, target: b }, ] ); - assert_eq!(first(builder.cache.all::<dist::Src>()), &[dist::Src]); + assert_eq!(first(cache.all::<dist::Src>()), &[dist::Src]); } #[test] fn dist_with_hosts() { - let build = Build::new(configure(&["A", "B"], &["A", "B"])); - let mut builder = Builder::new(&build); - builder.run_step_descriptions(&Builder::get_step_descriptions(Kind::Dist), &[]); + let mut cache = run_build(&[], configure(&["A", "B"], &["A", "B"])); let a = TargetSelection::from_user("A"); let b = TargetSelection::from_user("B"); assert_eq!( - first(builder.cache.all::<dist::Docs>()), + first(cache.all::<dist::Docs>()), &[dist::Docs { host: a }, dist::Docs { host: b },] ); assert_eq!( - first(builder.cache.all::<dist::Mingw>()), + first(cache.all::<dist::Mingw>()), &[dist::Mingw { host: a }, dist::Mingw { host: b },] ); assert_eq!( - first(builder.cache.all::<dist::Rustc>()), + first(cache.all::<dist::Rustc>()), &[ dist::Rustc { compiler: Compiler { host: a, stage: 2 } }, dist::Rustc { compiler: Compiler { host: b, stage: 2 } }, ] ); assert_eq!( - first(builder.cache.all::<dist::Std>()), + first(cache.all::<dist::Std>()), &[ dist::Std { compiler: Compiler { host: a, stage: 1 }, target: a }, dist::Std { compiler: Compiler { host: a, stage: 1 }, target: b }, ] ); assert_eq!( - first(builder.cache.all::<compile::Std>()), + first(cache.all::<compile::Std>()), &[ compile::Std { compiler: Compiler { host: a, stage: 0 }, target: a }, compile::Std { compiler: Compiler { host: a, stage: 1 }, target: a }, @@ -266,26 +290,25 @@ mod dist { compile::Std { compiler: Compiler { host: a, stage: 2 }, target: b }, ], ); - assert_eq!(first(builder.cache.all::<dist::Src>()), &[dist::Src]); + assert_eq!(first(cache.all::<dist::Src>()), &[dist::Src]); } #[test] fn dist_only_cross_host() { let a = TargetSelection::from_user("A"); let b = TargetSelection::from_user("B"); - let mut build = Build::new(configure(&["A", "B"], &["A", "B"])); - build.config.docs = false; - build.config.extended = true; - build.hosts = vec![b]; - let mut builder = Builder::new(&build); - builder.run_step_descriptions(&Builder::get_step_descriptions(Kind::Dist), &[]); + let mut config = configure(&["A", "B"], &["A", "B"]); + config.docs = false; + config.extended = true; + config.hosts = vec![b]; + let mut cache = run_build(&[], config); assert_eq!( - first(builder.cache.all::<dist::Rustc>()), + first(cache.all::<dist::Rustc>()), &[dist::Rustc { compiler: Compiler { host: b, stage: 2 } },] ); assert_eq!( - first(builder.cache.all::<compile::Rustc>()), + first(cache.all::<compile::Rustc>()), &[ compile::Rustc { compiler: Compiler { host: a, stage: 0 }, target: a }, compile::Rustc { compiler: Compiler { host: a, stage: 1 }, target: b }, @@ -295,92 +318,86 @@ mod dist { #[test] fn dist_with_targets_and_hosts() { - let build = Build::new(configure(&["A", "B"], &["A", "B", "C"])); - let mut builder = Builder::new(&build); - builder.run_step_descriptions(&Builder::get_step_descriptions(Kind::Dist), &[]); + let mut cache = run_build(&[], configure(&["A", "B"], &["A", "B", "C"])); let a = TargetSelection::from_user("A"); let b = TargetSelection::from_user("B"); let c = TargetSelection::from_user("C"); assert_eq!( - first(builder.cache.all::<dist::Docs>()), + first(cache.all::<dist::Docs>()), &[dist::Docs { host: a }, dist::Docs { host: b }, dist::Docs { host: c },] ); assert_eq!( - first(builder.cache.all::<dist::Mingw>()), + first(cache.all::<dist::Mingw>()), &[dist::Mingw { host: a }, dist::Mingw { host: b }, dist::Mingw { host: c },] ); assert_eq!( - first(builder.cache.all::<dist::Rustc>()), + first(cache.all::<dist::Rustc>()), &[ dist::Rustc { compiler: Compiler { host: a, stage: 2 } }, dist::Rustc { compiler: Compiler { host: b, stage: 2 } }, ] ); assert_eq!( - first(builder.cache.all::<dist::Std>()), + first(cache.all::<dist::Std>()), &[ dist::Std { compiler: Compiler { host: a, stage: 1 }, target: a }, dist::Std { compiler: Compiler { host: a, stage: 1 }, target: b }, dist::Std { compiler: Compiler { host: a, stage: 2 }, target: c }, ] ); - assert_eq!(first(builder.cache.all::<dist::Src>()), &[dist::Src]); + assert_eq!(first(cache.all::<dist::Src>()), &[dist::Src]); } #[test] fn dist_with_empty_host() { let config = configure(&[], &["C"]); - let build = Build::new(config); - let mut builder = Builder::new(&build); - builder.run_step_descriptions(&Builder::get_step_descriptions(Kind::Dist), &[]); + let mut cache = run_build(&[], config); let a = TargetSelection::from_user("A"); let c = TargetSelection::from_user("C"); - assert_eq!(first(builder.cache.all::<dist::Docs>()), &[dist::Docs { host: c },]); - assert_eq!(first(builder.cache.all::<dist::Mingw>()), &[dist::Mingw { host: c },]); + assert_eq!(first(cache.all::<dist::Docs>()), &[dist::Docs { host: c },]); + assert_eq!(first(cache.all::<dist::Mingw>()), &[dist::Mingw { host: c },]); assert_eq!( - first(builder.cache.all::<dist::Std>()), + first(cache.all::<dist::Std>()), &[dist::Std { compiler: Compiler { host: a, stage: 2 }, target: c },] ); } #[test] fn dist_with_same_targets_and_hosts() { - let build = Build::new(configure(&["A", "B"], &["A", "B"])); - let mut builder = Builder::new(&build); - builder.run_step_descriptions(&Builder::get_step_descriptions(Kind::Dist), &[]); + let mut cache = run_build(&[], configure(&["A", "B"], &["A", "B"])); let a = TargetSelection::from_user("A"); let b = TargetSelection::from_user("B"); assert_eq!( - first(builder.cache.all::<dist::Docs>()), + first(cache.all::<dist::Docs>()), &[dist::Docs { host: a }, dist::Docs { host: b },] ); assert_eq!( - first(builder.cache.all::<dist::Mingw>()), + first(cache.all::<dist::Mingw>()), &[dist::Mingw { host: a }, dist::Mingw { host: b },] ); assert_eq!( - first(builder.cache.all::<dist::Rustc>()), + first(cache.all::<dist::Rustc>()), &[ dist::Rustc { compiler: Compiler { host: a, stage: 2 } }, dist::Rustc { compiler: Compiler { host: b, stage: 2 } }, ] ); assert_eq!( - first(builder.cache.all::<dist::Std>()), + first(cache.all::<dist::Std>()), &[ dist::Std { compiler: Compiler { host: a, stage: 1 }, target: a }, dist::Std { compiler: Compiler { host: a, stage: 1 }, target: b }, ] ); - assert_eq!(first(builder.cache.all::<dist::Src>()), &[dist::Src]); + assert_eq!(first(cache.all::<dist::Src>()), &[dist::Src]); assert_eq!( - first(builder.cache.all::<compile::Std>()), + first(cache.all::<compile::Std>()), &[ compile::Std { compiler: Compiler { host: a, stage: 0 }, target: a }, compile::Std { compiler: Compiler { host: a, stage: 1 }, target: a }, @@ -390,7 +407,7 @@ mod dist { ] ); assert_eq!( - first(builder.cache.all::<compile::Assemble>()), + first(cache.all::<compile::Assemble>()), &[ compile::Assemble { target_compiler: Compiler { host: a, stage: 0 } }, compile::Assemble { target_compiler: Compiler { host: a, stage: 1 } }, @@ -515,35 +532,6 @@ mod dist { } #[test] - fn test_exclude() { - let mut config = configure(&["A"], &["A"]); - config.exclude = vec![TaskPath::parse("src/tools/tidy")]; - config.cmd = Subcommand::Test { - paths: Vec::new(), - test_args: Vec::new(), - rustc_args: Vec::new(), - fail_fast: true, - doc_tests: DocTests::No, - bless: false, - force_rerun: false, - compare_mode: None, - rustfix_coverage: false, - pass: None, - run: None, - }; - - let build = Build::new(config); - let builder = Builder::new(&build); - builder.run_step_descriptions(&Builder::get_step_descriptions(Kind::Test), &[]); - - // Ensure we have really excluded tidy - assert!(!builder.cache.contains::<test::Tidy>()); - - // Ensure other tests are not affected. - assert!(builder.cache.contains::<test::RustdocUi>()); - } - - #[test] fn doc_ci() { let mut config = configure(&["A"], &["A"]); config.compiler_docs = true; diff --git a/src/bootstrap/check.rs b/src/bootstrap/check.rs index 432a6c34ed5..731ebc41bb9 100644 --- a/src/bootstrap/check.rs +++ b/src/bootstrap/check.rs @@ -64,7 +64,7 @@ impl Step for Std { const DEFAULT: bool = true; fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { - run.all_krates("test") + run.all_krates("test").path("library") } fn make_run(run: RunConfig<'_>) { @@ -162,7 +162,7 @@ impl Step for Rustc { const DEFAULT: bool = true; fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { - run.all_krates("rustc-main") + run.all_krates("rustc-main").path("compiler") } fn make_run(run: RunConfig<'_>) { diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs index 45991381dc0..53933e4cd7d 100644 --- a/src/bootstrap/compile.rs +++ b/src/bootstrap/compile.rs @@ -43,7 +43,7 @@ impl Step for Std { // When downloading stage1, the standard library has already been copied to the sysroot, so // there's no need to rebuild it. let download_rustc = run.builder.config.download_rustc; - run.all_krates("test").default_condition(!download_rustc) + run.all_krates("test").path("library").default_condition(!download_rustc) } fn make_run(run: RunConfig<'_>) { @@ -737,7 +737,7 @@ pub fn rustc_cargo_env(builder: &Builder<'_>, cargo: &mut Cargo, target: TargetS ); cargo.env("LLVM_STATIC_STDCPP", file); } - if builder.config.llvm_link_shared { + if builder.llvm_link_shared() { cargo.env("LLVM_LINK_SHARED", "1"); } if builder.config.llvm_use_libcxx { @@ -1047,7 +1047,7 @@ impl Step for Assemble { const ONLY_HOSTS: bool = true; fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { - run.path("compiler/rustc") + run.path("compiler/rustc").path("compiler") } fn make_run(run: RunConfig<'_>) { diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs index d7c29f6900a..e39c9fa1c5a 100644 --- a/src/bootstrap/config.rs +++ b/src/bootstrap/config.rs @@ -3,6 +3,7 @@ //! This module implements parsing `config.toml` configuration files to tweak //! how the build runs. +use std::cell::Cell; use std::cmp; use std::collections::{HashMap, HashSet}; use std::env; @@ -11,7 +12,7 @@ use std::fs; use std::path::{Path, PathBuf}; use std::str::FromStr; -use crate::builder::TaskPath; +use crate::builder::{Builder, TaskPath}; use crate::cache::{Interned, INTERNER}; use crate::channel::GitInfo; pub use crate::flags::Subcommand; @@ -41,6 +42,7 @@ macro_rules! check_ci_llvm { /// each field, see the corresponding fields in /// `config.toml.example`. #[derive(Default)] +#[cfg_attr(test, derive(Clone))] pub struct Config { pub changelog_seen: Option<usize>, pub ccache: Option<String>, @@ -68,13 +70,14 @@ pub struct Config { pub test_compare_mode: bool, pub llvm_libunwind: LlvmLibunwind, pub color: Color, + pub patch_binaries_for_nix: bool, pub on_fail: Option<String>, pub stage: u32, pub keep_stage: Vec<u32>, pub keep_stage_std: Vec<u32>, pub src: PathBuf, - // defaults to `config.toml` + /// defaults to `config.toml` pub config: PathBuf, pub jobs: Option<u32>, pub cmd: Subcommand, @@ -95,7 +98,11 @@ pub struct Config { pub llvm_release_debuginfo: bool, pub llvm_version_check: bool, pub llvm_static_stdcpp: bool, - pub llvm_link_shared: bool, + /// `None` if `llvm_from_ci` is true and we haven't yet downloaded llvm. + #[cfg(not(test))] + llvm_link_shared: Cell<Option<bool>>, + #[cfg(test)] + pub llvm_link_shared: Cell<Option<bool>>, pub llvm_clang_cl: Option<String>, pub llvm_targets: Option<String>, pub llvm_experimental_targets: Option<String>, @@ -130,7 +137,7 @@ pub struct Config { pub rust_debuginfo_level_std: u32, pub rust_debuginfo_level_tools: u32, pub rust_debuginfo_level_tests: u32, - pub rust_run_dsymutil: bool, + pub rust_split_debuginfo: SplitDebuginfo, pub rust_rpath: bool, pub rustc_parallel: bool, pub rustc_default_linker: Option<String>, @@ -221,6 +228,46 @@ impl FromStr for LlvmLibunwind { } } +#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] +pub enum SplitDebuginfo { + Packed, + Unpacked, + Off, +} + +impl Default for SplitDebuginfo { + fn default() -> Self { + SplitDebuginfo::Off + } +} + +impl std::str::FromStr for SplitDebuginfo { + type Err = (); + + fn from_str(s: &str) -> Result<Self, Self::Err> { + match s { + "packed" => Ok(SplitDebuginfo::Packed), + "unpacked" => Ok(SplitDebuginfo::Unpacked), + "off" => Ok(SplitDebuginfo::Off), + _ => Err(()), + } + } +} + +impl SplitDebuginfo { + /// Returns the default `-Csplit-debuginfo` value for the current target. See the comment for + /// `rust.split-debuginfo` in `config.toml.example`. + fn default_for_platform(target: &str) -> Self { + if target.contains("apple") { + SplitDebuginfo::Unpacked + } else if target.contains("windows") { + SplitDebuginfo::Packed + } else { + SplitDebuginfo::Off + } + } +} + #[derive(Copy, Clone, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct TargetSelection { pub triple: Interned<String>, @@ -290,6 +337,7 @@ impl PartialEq<&str> for TargetSelection { /// Per-target configuration stored in the global configuration structure. #[derive(Default)] +#[cfg_attr(test, derive(Clone))] pub struct Target { /// Some(path to llvm-config) if using an external LLVM. pub llvm_config: Option<PathBuf>, @@ -586,6 +634,7 @@ define_config! { debuginfo_level_std: Option<u32> = "debuginfo-level-std", debuginfo_level_tools: Option<u32> = "debuginfo-level-tools", debuginfo_level_tests: Option<u32> = "debuginfo-level-tests", + split_debuginfo: Option<String> = "split-debuginfo", run_dsymutil: Option<bool> = "run-dsymutil", backtrace: Option<bool> = "backtrace", incremental: Option<bool> = "incremental", @@ -815,6 +864,7 @@ impl Config { set(&mut config.local_rebuild, build.local_rebuild); set(&mut config.print_step_timings, build.print_step_timings); set(&mut config.print_step_rusage, build.print_step_rusage); + set(&mut config.patch_binaries_for_nix, build.patch_binaries_for_nix); config.verbose = cmp::max(config.verbose, flags.verbose); @@ -870,7 +920,9 @@ impl Config { set(&mut config.llvm_release_debuginfo, llvm.release_debuginfo); set(&mut config.llvm_version_check, llvm.version_check); set(&mut config.llvm_static_stdcpp, llvm.static_libstdcpp); - set(&mut config.llvm_link_shared, llvm.link_shared); + if let Some(v) = llvm.link_shared { + config.llvm_link_shared.set(Some(v)); + } config.llvm_targets = llvm.targets.clone(); config.llvm_experimental_targets = llvm.experimental_targets.clone(); config.llvm_link_jobs = llvm.link_jobs; @@ -940,6 +992,7 @@ impl Config { check_ci_llvm!(llvm.optimize); check_ci_llvm!(llvm.thin_lto); check_ci_llvm!(llvm.release_debuginfo); + // CI-built LLVM can be either dynamic or static. We won't know until we download it. check_ci_llvm!(llvm.link_shared); check_ci_llvm!(llvm.static_libstdcpp); check_ci_llvm!(llvm.targets); @@ -957,26 +1010,14 @@ impl Config { check_ci_llvm!(llvm.clang); check_ci_llvm!(llvm.build_config); check_ci_llvm!(llvm.plugins); - - // CI-built LLVM can be either dynamic or static. - let ci_llvm = config.out.join(&*config.build.triple).join("ci-llvm"); - config.llvm_link_shared = if config.dry_run { - // just assume dynamic for now - true - } else { - let link_type = t!( - std::fs::read_to_string(ci_llvm.join("link-type.txt")), - format!("CI llvm missing: {}", ci_llvm.display()) - ); - link_type == "dynamic" - }; } + // NOTE: can never be hit when downloading from CI, since we call `check_ci_llvm!(thin_lto)` above. if config.llvm_thin_lto && llvm.link_shared.is_none() { // If we're building with ThinLTO on, by default we want to link // to LLVM shared, to avoid re-doing ThinLTO (which happens in // the link step) with each stage. - config.llvm_link_shared = true; + config.llvm_link_shared.set(Some(true)); } } @@ -992,7 +1033,12 @@ impl Config { debuginfo_level_std = rust.debuginfo_level_std; debuginfo_level_tools = rust.debuginfo_level_tools; debuginfo_level_tests = rust.debuginfo_level_tests; - config.rust_run_dsymutil = rust.run_dsymutil.unwrap_or(false); + config.rust_split_debuginfo = rust + .split_debuginfo + .as_deref() + .map(SplitDebuginfo::from_str) + .map(|v| v.expect("invalid value for rust.split_debuginfo")) + .unwrap_or(SplitDebuginfo::default_for_platform(&config.build.triple)); optimize = rust.optimize; ignore_git = rust.ignore_git; config.rust_new_symbol_mangling = rust.new_symbol_mangling; @@ -1226,6 +1272,42 @@ impl Config { } } + /// The absolute path to the downloaded LLVM artifacts. + pub(crate) fn ci_llvm_root(&self) -> PathBuf { + assert!(self.llvm_from_ci); + self.out.join(&*self.build.triple).join("ci-llvm") + } + + /// Determine whether llvm should be linked dynamically. + /// + /// If `false`, llvm should be linked statically. + /// This is computed on demand since LLVM might have to first be downloaded from CI. + pub(crate) fn llvm_link_shared(builder: &Builder<'_>) -> bool { + let mut opt = builder.config.llvm_link_shared.get(); + if opt.is_none() && builder.config.dry_run { + // just assume static for now - dynamic linking isn't supported on all platforms + return false; + } + + let llvm_link_shared = *opt.get_or_insert_with(|| { + if builder.config.llvm_from_ci { + crate::native::maybe_download_ci_llvm(builder); + let ci_llvm = builder.config.ci_llvm_root(); + let link_type = t!( + std::fs::read_to_string(ci_llvm.join("link-type.txt")), + format!("CI llvm missing: {}", ci_llvm.display()) + ); + link_type == "dynamic" + } else { + // unclear how thought-through this default is, but it maintains compatibility with + // previous behavior + false + } + }); + builder.config.llvm_link_shared.set(opt); + llvm_link_shared + } + pub fn verbose(&self) -> bool { self.verbose > 0 } diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index e3287e35227..5d812e8b332 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -1904,7 +1904,7 @@ fn maybe_install_llvm(builder: &Builder<'_>, target: TargetSelection, dst_libdir // clear why this is the case, though. llvm-config will emit the versioned // paths and we don't want those in the sysroot (as we're expecting // unversioned paths). - if target.contains("apple-darwin") && builder.config.llvm_link_shared { + if target.contains("apple-darwin") && builder.llvm_link_shared() { let src_libdir = builder.llvm_out(target).join("lib"); let llvm_dylib_path = src_libdir.join("libLLVM.dylib"); if llvm_dylib_path.exists() { @@ -1939,7 +1939,7 @@ pub fn maybe_install_llvm_target(builder: &Builder<'_>, target: TargetSelection, // We do not need to copy LLVM files into the sysroot if it is not // dynamically linked; it is already included into librustc_llvm // statically. - if builder.config.llvm_link_shared { + if builder.llvm_link_shared() { maybe_install_llvm(builder, target, &dst_libdir); } } @@ -1951,7 +1951,7 @@ pub fn maybe_install_llvm_runtime(builder: &Builder<'_>, target: TargetSelection // We do not need to copy LLVM files into the sysroot if it is not // dynamically linked; it is already included into librustc_llvm // statically. - if builder.config.llvm_link_shared { + if builder.llvm_link_shared() { maybe_install_llvm(builder, target, &dst_libdir); } } @@ -2077,7 +2077,7 @@ impl Step for RustDev { // compiler libraries. let dst_libdir = tarball.image_dir().join("lib"); maybe_install_llvm(builder, target, &dst_libdir); - let link_type = if builder.config.llvm_link_shared { "dynamic" } else { "static" }; + let link_type = if builder.llvm_link_shared() { "dynamic" } else { "static" }; t!(std::fs::write(tarball.image_dir().join("link-type.txt"), link_type), dst_libdir); Some(tarball.generate()) diff --git a/src/bootstrap/doc.rs b/src/bootstrap/doc.rs index a2802f76008..fcef784d2d1 100644 --- a/src/bootstrap/doc.rs +++ b/src/bootstrap/doc.rs @@ -416,7 +416,7 @@ impl Step for Std { fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { let builder = run.builder; - run.all_krates("test").default_condition(builder.config.docs) + run.all_krates("test").path("library").default_condition(builder.config.docs) } fn make_run(run: RunConfig<'_>) { @@ -477,11 +477,14 @@ impl Step for Std { .iter() .map(components_simplified) .filter_map(|path| { - if path.get(0) == Some(&"library") { + if path.len() >= 2 && path.get(0) == Some(&"library") { + // single crate Some(path[1].to_owned()) } else if !path.is_empty() { + // ?? Some(path[0].to_owned()) } else { + // all library crates None } }) diff --git a/src/bootstrap/flags.rs b/src/bootstrap/flags.rs index 1a4e6a96888..58571ea129c 100644 --- a/src/bootstrap/flags.rs +++ b/src/bootstrap/flags.rs @@ -8,12 +8,13 @@ use std::process; use getopts::Options; -use crate::builder::Builder; +use crate::builder::{Builder, Kind}; use crate::config::{Config, TargetSelection}; use crate::setup::Profile; use crate::util::t; use crate::{Build, DocTests}; +#[derive(Copy, Clone)] pub enum Color { Always, Never, @@ -79,6 +80,7 @@ pub struct Flags { pub llvm_profile_generate: bool, } +#[cfg_attr(test, derive(Clone))] pub enum Subcommand { Build { paths: Vec<PathBuf>, @@ -243,27 +245,7 @@ To learn more about a subcommand, run `./x.py <subcommand> -h`", // the subcommand. Therefore we must manually identify the subcommand first, so that we can // complete the definition of the options. Then we can use the getopt::Matches object from // there on out. - let subcommand = args.iter().find(|&s| { - (s == "build") - || (s == "b") - || (s == "check") - || (s == "c") - || (s == "clippy") - || (s == "fix") - || (s == "fmt") - || (s == "test") - || (s == "t") - || (s == "bench") - || (s == "doc") - || (s == "d") - || (s == "clean") - || (s == "dist") - || (s == "install") - || (s == "run") - || (s == "r") - || (s == "setup") - }); - let subcommand = match subcommand { + let subcommand = match args.iter().find_map(|s| Kind::parse(&s)) { Some(s) => s, None => { // No or an invalid subcommand -- show the general usage and subcommand help @@ -276,8 +258,8 @@ To learn more about a subcommand, run `./x.py <subcommand> -h`", }; // Some subcommands get extra options - match subcommand.as_str() { - "test" | "t" => { + match subcommand { + Kind::Test => { opts.optflag("", "no-fail-fast", "Run all tests regardless of failure"); opts.optmulti( "", @@ -316,22 +298,22 @@ To learn more about a subcommand, run `./x.py <subcommand> -h`", `/<build_base>/rustfix_missing_coverage.txt`", ); } - "check" | "c" => { + Kind::Check => { opts.optflag("", "all-targets", "Check all targets"); } - "bench" => { + Kind::Bench => { opts.optmulti("", "test-args", "extra arguments", "ARGS"); } - "clippy" => { + Kind::Clippy => { opts.optflag("", "fix", "automatically apply lint suggestions"); } - "doc" | "d" => { + Kind::Doc => { opts.optflag("", "open", "open the docs in a browser"); } - "clean" => { + Kind::Clean => { opts.optflag("", "all", "clean all build artifacts"); } - "fmt" => { + Kind::Format => { opts.optflag("", "check", "check formatting instead of applying."); } _ => {} @@ -339,25 +321,22 @@ To learn more about a subcommand, run `./x.py <subcommand> -h`", // fn usage() let usage = |exit_code: i32, opts: &Options, verbose: bool, subcommand_help: &str| -> ! { - let mut extra_help = String::new(); - - // All subcommands except `clean` can have an optional "Available paths" section - if verbose { - let config = Config::parse(&["build".to_string()]); - let build = Build::new(config); - - let maybe_rules_help = Builder::get_help(&build, subcommand.as_str()); - extra_help.push_str(maybe_rules_help.unwrap_or_default().as_str()); - } else if !(subcommand.as_str() == "clean" || subcommand.as_str() == "fmt") { - extra_help.push_str( - format!("Run `./x.py {} -h -v` to see a list of available paths.", subcommand) - .as_str(), - ); - } + let config = Config::parse(&["build".to_string()]); + let build = Build::new(config); + let paths = Builder::get_help(&build, subcommand); println!("{}", opts.usage(subcommand_help)); - if !extra_help.is_empty() { - println!("{}", extra_help); + if let Some(s) = paths { + if verbose { + println!("{}", s); + } else { + println!( + "Run `./x.py {} -h -v` to see a list of available paths.", + subcommand.as_str() + ); + } + } else if verbose { + panic!("No paths available for subcommand `{}`", subcommand.as_str()); } process::exit(exit_code); }; @@ -375,7 +354,7 @@ To learn more about a subcommand, run `./x.py <subcommand> -h`", // ^-- option ^ ^- actual subcommand // \_ arg to option could be mistaken as subcommand let mut pass_sanity_check = true; - match matches.free.get(0) { + match matches.free.get(0).and_then(|s| Kind::parse(&s)) { Some(check_subcommand) => { if check_subcommand != subcommand { pass_sanity_check = false; @@ -394,8 +373,8 @@ To learn more about a subcommand, run `./x.py <subcommand> -h`", process::exit(1); } // Extra help text for some commands - match subcommand.as_str() { - "build" | "b" => { + match subcommand { + Kind::Build => { subcommand_help.push_str( "\n Arguments: @@ -415,7 +394,7 @@ Arguments: ./x.py build ", ); } - "check" | "c" => { + Kind::Check => { subcommand_help.push_str( "\n Arguments: @@ -427,7 +406,7 @@ Arguments: If no arguments are passed then many artifacts are checked.", ); } - "clippy" => { + Kind::Clippy => { subcommand_help.push_str( "\n Arguments: @@ -438,7 +417,7 @@ Arguments: ./x.py clippy library/core library/proc_macro", ); } - "fix" => { + Kind::Fix => { subcommand_help.push_str( "\n Arguments: @@ -449,7 +428,7 @@ Arguments: ./x.py fix library/core library/proc_macro", ); } - "fmt" => { + Kind::Format => { subcommand_help.push_str( "\n Arguments: @@ -460,7 +439,7 @@ Arguments: ./x.py fmt --check", ); } - "test" | "t" => { + Kind::Test => { subcommand_help.push_str( "\n Arguments: @@ -488,7 +467,7 @@ Arguments: ./x.py test --stage 1", ); } - "doc" | "d" => { + Kind::Doc => { subcommand_help.push_str( "\n Arguments: @@ -506,7 +485,7 @@ Arguments: ./x.py doc --stage 1", ); } - "run" | "r" => { + Kind::Run => { subcommand_help.push_str( "\n Arguments: @@ -518,7 +497,7 @@ Arguments: At least a tool needs to be called.", ); } - "setup" => { + Kind::Setup => { subcommand_help.push_str(&format!( "\n x.py setup creates a `config.toml` which changes the defaults for x.py itself. @@ -535,7 +514,7 @@ Arguments: Profile::all_for_help(" ").trim_end() )); } - _ => {} + Kind::Bench | Kind::Clean | Kind::Dist | Kind::Install => {} }; // Get any optional paths which occur after the subcommand let mut paths = matches.free[1..].iter().map(|p| p.into()).collect::<Vec<PathBuf>>(); @@ -547,9 +526,9 @@ Arguments: usage(0, &opts, verbose, &subcommand_help); } - let cmd = match subcommand.as_str() { - "build" | "b" => Subcommand::Build { paths }, - "check" | "c" => { + let cmd = match subcommand { + Kind::Build => Subcommand::Build { paths }, + Kind::Check => { if matches.opt_present("all-targets") { eprintln!( "Warning: --all-targets is now on by default and does not need to be passed explicitly." @@ -557,9 +536,9 @@ Arguments: } Subcommand::Check { paths } } - "clippy" => Subcommand::Clippy { paths, fix: matches.opt_present("fix") }, - "fix" => Subcommand::Fix { paths }, - "test" | "t" => Subcommand::Test { + Kind::Clippy => Subcommand::Clippy { paths, fix: matches.opt_present("fix") }, + Kind::Fix => Subcommand::Fix { paths }, + Kind::Test => Subcommand::Test { paths, bless: matches.opt_present("bless"), force_rerun: matches.opt_present("force-rerun"), @@ -578,9 +557,9 @@ Arguments: DocTests::Yes }, }, - "bench" => Subcommand::Bench { paths, test_args: matches.opt_strs("test-args") }, - "doc" | "d" => Subcommand::Doc { paths, open: matches.opt_present("open") }, - "clean" => { + Kind::Bench => Subcommand::Bench { paths, test_args: matches.opt_strs("test-args") }, + Kind::Doc => Subcommand::Doc { paths, open: matches.opt_present("open") }, + Kind::Clean => { if !paths.is_empty() { println!("\nclean does not take a path argument\n"); usage(1, &opts, verbose, &subcommand_help); @@ -588,17 +567,17 @@ Arguments: Subcommand::Clean { all: matches.opt_present("all") } } - "fmt" => Subcommand::Format { check: matches.opt_present("check"), paths }, - "dist" => Subcommand::Dist { paths }, - "install" => Subcommand::Install { paths }, - "run" | "r" => { + Kind::Format => Subcommand::Format { check: matches.opt_present("check"), paths }, + Kind::Dist => Subcommand::Dist { paths }, + Kind::Install => Subcommand::Install { paths }, + Kind::Run => { if paths.is_empty() { println!("\nrun requires at least a path!\n"); usage(1, &opts, verbose, &subcommand_help); } Subcommand::Run { paths } } - "setup" => { + Kind::Setup => { let profile = if paths.len() > 1 { println!("\nat most one profile can be passed to setup\n"); usage(1, &opts, verbose, &subcommand_help) @@ -618,9 +597,6 @@ Arguments: }; Subcommand::Setup { profile } } - _ => { - usage(1, &opts, verbose, &subcommand_help); - } }; if let Subcommand::Check { .. } = &cmd { @@ -694,6 +670,24 @@ Arguments: } impl Subcommand { + pub fn kind(&self) -> Kind { + match self { + Subcommand::Bench { .. } => Kind::Bench, + Subcommand::Build { .. } => Kind::Build, + Subcommand::Check { .. } => Kind::Check, + Subcommand::Clippy { .. } => Kind::Clippy, + Subcommand::Doc { .. } => Kind::Doc, + Subcommand::Fix { .. } => Kind::Fix, + Subcommand::Format { .. } => Kind::Format, + Subcommand::Test { .. } => Kind::Test, + Subcommand::Clean { .. } => Kind::Clean, + Subcommand::Dist { .. } => Kind::Dist, + Subcommand::Install { .. } => Kind::Install, + Subcommand::Run { .. } => Kind::Run, + Subcommand::Setup { .. } => Kind::Setup, + } + } + pub fn test_args(&self) -> Vec<&str> { match *self { Subcommand::Test { ref test_args, .. } | Subcommand::Bench { ref test_args, .. } => { diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index 59102ad9f50..b4b973b4247 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -1391,6 +1391,16 @@ impl Build { paths } + /// Create a temporary directory in `out` and return its path. + /// + /// NOTE: this temporary directory is shared between all steps; + /// if you need an empty directory, create a new subdirectory inside it. + fn tempdir(&self) -> PathBuf { + let tmp = self.out.join("tmp"); + t!(fs::create_dir_all(&tmp)); + tmp + } + /// Copies a file from `src` to `dst` pub fn copy(&self, src: &Path, dst: &Path) { if self.config.dry_run { diff --git a/src/bootstrap/native.rs b/src/bootstrap/native.rs index 73fb2dad1e3..64e25f803b2 100644 --- a/src/bootstrap/native.rs +++ b/src/bootstrap/native.rs @@ -12,9 +12,12 @@ use std::env; use std::env::consts::EXE_EXTENSION; use std::ffi::{OsStr, OsString}; use std::fs::{self, File}; -use std::io; +use std::io::{self, BufRead, BufReader, ErrorKind}; use std::path::{Path, PathBuf}; -use std::process::Command; +use std::process::{Command, Stdio}; + +use once_cell::sync::OnceCell; +use xz2::bufread::XzDecoder; use crate::builder::{Builder, RunConfig, ShouldRun, Step}; use crate::config::TargetSelection; @@ -62,6 +65,8 @@ pub fn prebuilt_llvm_config( builder: &Builder<'_>, target: TargetSelection, ) -> Result<PathBuf, Meta> { + maybe_download_ci_llvm(builder); + // If we're using a custom LLVM bail out here, but we can only use a // custom LLVM for the build triple. if let Some(config) = builder.config.target_config.get(&target) { @@ -111,6 +116,285 @@ pub fn prebuilt_llvm_config( Err(Meta { stamp, build_llvm_config, out_dir, root: root.into() }) } +pub(crate) fn maybe_download_ci_llvm(builder: &Builder<'_>) { + let config = &builder.config; + if !config.llvm_from_ci { + return; + } + let mut rev_list = Command::new("git"); + rev_list.args(&[ + PathBuf::from("rev-list"), + "--author=bors@rust-lang.org".into(), + "-n1".into(), + "--first-parent".into(), + "HEAD".into(), + "--".into(), + builder.src.join("src/llvm-project"), + builder.src.join("src/bootstrap/download-ci-llvm-stamp"), + // the LLVM shared object file is named `LLVM-12-rust-{version}-nightly` + builder.src.join("src/version"), + ]); + let llvm_sha = output(&mut rev_list); + let llvm_sha = llvm_sha.trim(); + + if llvm_sha == "" { + println!("error: could not find commit hash for downloading LLVM"); + println!("help: maybe your repository history is too shallow?"); + println!("help: consider disabling `download-ci-llvm`"); + println!("help: or fetch enough history to include one upstream commit"); + panic!(); + } + + let llvm_root = config.ci_llvm_root(); + let llvm_stamp = llvm_root.join(".llvm-stamp"); + let key = format!("{}{}", llvm_sha, config.llvm_assertions); + if program_out_of_date(&llvm_stamp, &key) && !config.dry_run { + download_ci_llvm(builder, &llvm_sha); + for binary in ["llvm-config", "FileCheck"] { + fix_bin_or_dylib(builder, &llvm_root.join("bin").join(binary)); + } + let llvm_lib = llvm_root.join("lib"); + for entry in t!(fs::read_dir(&llvm_lib)) { + let lib = t!(entry).path(); + if lib.ends_with(".so") { + fix_bin_or_dylib(builder, &lib); + } + } + t!(fs::write(llvm_stamp, key)); + } +} + +fn download_ci_llvm(builder: &Builder<'_>, llvm_sha: &str) { + let llvm_assertions = builder.config.llvm_assertions; + + let cache_prefix = format!("llvm-{}-{}", llvm_sha, llvm_assertions); + let cache_dst = builder.out.join("cache"); + let rustc_cache = cache_dst.join(cache_prefix); + if !rustc_cache.exists() { + t!(fs::create_dir_all(&rustc_cache)); + } + let base = "https://ci-artifacts.rust-lang.org"; + let url = if llvm_assertions { + format!("rustc-builds-alt/{}", llvm_sha) + } else { + format!("rustc-builds/{}", llvm_sha) + }; + let filename = format!("rust-dev-nightly-{}.tar.xz", builder.build.build.triple); + let tarball = rustc_cache.join(&filename); + if !tarball.exists() { + download_component(builder, base, &format!("{}/{}", url, filename), &tarball); + } + let llvm_root = builder.config.ci_llvm_root(); + unpack(builder, &tarball, &llvm_root); +} + +/// Modifies the interpreter section of 'fname' to fix the dynamic linker, +/// or the RPATH section, to fix the dynamic library search path +/// +/// This is only required on NixOS and uses the PatchELF utility to +/// change the interpreter/RPATH of ELF executables. +/// +/// Please see https://nixos.org/patchelf.html for more information +fn fix_bin_or_dylib(builder: &Builder<'_>, fname: &Path) { + // FIXME: cache NixOS detection? + match Command::new("uname").arg("-s").stderr(Stdio::inherit()).output() { + Err(_) => return, + Ok(output) if !output.status.success() => return, + Ok(output) => { + let mut s = output.stdout; + if s.last() == Some(&b'\n') { + s.pop(); + } + if s != b"Linux" { + return; + } + } + } + + // If the user has asked binaries to be patched for Nix, then + // don't check for NixOS or `/lib`, just continue to the patching. + // FIXME: shouldn't this take precedence over the `uname` check above? + if !builder.config.patch_binaries_for_nix { + // Use `/etc/os-release` instead of `/etc/NIXOS`. + // The latter one does not exist on NixOS when using tmpfs as root. + const NIX_IDS: &[&str] = &["ID=nixos", "ID='nixos'", "ID=\"nixos\""]; + let os_release = match File::open("/etc/os-release") { + Err(e) if e.kind() == ErrorKind::NotFound => return, + Err(e) => panic!("failed to access /etc/os-release: {}", e), + Ok(f) => f, + }; + if !BufReader::new(os_release).lines().any(|l| NIX_IDS.contains(&t!(l).trim())) { + return; + } + if Path::new("/lib").exists() { + return; + } + } + + // At this point we're pretty sure the user is running NixOS or using Nix + println!("info: you seem to be using Nix. Attempting to patch {}", fname.display()); + + // Only build `.nix-deps` once. + static NIX_DEPS_DIR: OnceCell<PathBuf> = OnceCell::new(); + let mut nix_build_succeeded = true; + let nix_deps_dir = NIX_DEPS_DIR.get_or_init(|| { + // Run `nix-build` to "build" each dependency (which will likely reuse + // the existing `/nix/store` copy, or at most download a pre-built copy). + // + // Importantly, we create a gc-root called `.nix-deps` in the `build/` + // directory, but still reference the actual `/nix/store` path in the rpath + // as it makes it significantly more robust against changes to the location of + // the `.nix-deps` location. + // + // bintools: Needed for the path of `ld-linux.so` (via `nix-support/dynamic-linker`). + // zlib: Needed as a system dependency of `libLLVM-*.so`. + // patchelf: Needed for patching ELF binaries (see doc comment above). + let nix_deps_dir = builder.out.join(".nix-deps"); + const NIX_EXPR: &str = " + with (import <nixpkgs> {}); + symlinkJoin { + name = \"rust-stage0-dependencies\"; + paths = [ + zlib + patchelf + stdenv.cc.bintools + ]; + } + "; + nix_build_succeeded = builder.try_run(Command::new("nix-build").args(&[ + Path::new("-E"), + Path::new(NIX_EXPR), + Path::new("-o"), + &nix_deps_dir, + ])); + nix_deps_dir + }); + if !nix_build_succeeded { + return; + } + + let mut patchelf = Command::new(nix_deps_dir.join("bin/patchelf")); + let rpath_entries = { + // ORIGIN is a relative default, all binary and dynamic libraries we ship + // appear to have this (even when `../lib` is redundant). + // NOTE: there are only two paths here, delimited by a `:` + let mut entries = OsString::from("$ORIGIN/../lib:"); + entries.push(t!(fs::canonicalize(nix_deps_dir))); + entries.push("/lib"); + entries + }; + patchelf.args(&[OsString::from("--set-rpath"), rpath_entries]); + if !fname.ends_with(".so") { + // Finally, set the corret .interp for binaries + let dynamic_linker_path = nix_deps_dir.join("nix-support/dynamic-linker"); + // FIXME: can we support utf8 here? `args` doesn't accept Vec<u8>, only OsString ... + let dynamic_linker = t!(String::from_utf8(t!(fs::read(dynamic_linker_path)))); + patchelf.args(&["--set-interpreter", dynamic_linker.trim_end()]); + } + + builder.try_run(patchelf.arg(fname)); +} + +fn download_component(builder: &Builder<'_>, base: &str, url: &str, dest_path: &Path) { + // Use a temporary file in case we crash while downloading, to avoid a corrupt download in cache/. + let tempfile = builder.tempdir().join(dest_path.file_name().unwrap()); + // FIXME: support `do_verify` (only really needed for nightly rustfmt) + // FIXME: support non-utf8 paths? + download_with_retries(builder, tempfile.to_str().unwrap(), &format!("{}/{}", base, url)); + t!(std::fs::rename(&tempfile, dest_path)); +} + +fn download_with_retries(builder: &Builder<'_>, tempfile: &str, url: &str) { + println!("downloading {}", url); + + // FIXME: check if curl is installed instead of skipping straight to powershell + if builder.build.build.contains("windows-msvc") { + for _ in 0..3 { + if builder.try_run(Command::new("PowerShell.exe").args(&[ + "/nologo", + "-Command", + "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12;", + &format!( + "(New-Object System.Net.WebClient).DownloadFile('{}', '{}')", + url, tempfile + ), + ])) { + return; + } + println!("\nspurious failure, trying again"); + } + } else { + builder.run(Command::new("curl").args(&[ + "-#", + "-y", + "30", + "-Y", + "10", // timeout if speed is < 10 bytes/sec for > 30 seconds + "--connect-timeout", + "30", // timeout if cannot connect within 30 seconds + "--retry", + "3", + "-Sf", + "-o", + tempfile, + url, + ])); + } +} + +fn unpack(builder: &Builder<'_>, tarball: &Path, dst: &Path) { + println!("extracting {} to {}", tarball.display(), dst.display()); + if !dst.exists() { + t!(fs::create_dir_all(dst)); + } + + // FIXME: will need to be a parameter once `download-rustc` is moved to rustbuild + const MATCH: &str = "rust-dev"; + + // `tarball` ends with `.tar.xz`; strip that suffix + // example: `rust-dev-nightly-x86_64-unknown-linux-gnu` + let uncompressed_filename = + Path::new(tarball.file_name().expect("missing tarball filename")).file_stem().unwrap(); + let directory_prefix = Path::new(Path::new(uncompressed_filename).file_stem().unwrap()); + + // decompress the file + let data = t!(File::open(tarball)); + let decompressor = XzDecoder::new(BufReader::new(data)); + + let mut tar = tar::Archive::new(decompressor); + for member in t!(tar.entries()) { + let mut member = t!(member); + let original_path = t!(member.path()).into_owned(); + // skip the top-level directory + if original_path == directory_prefix { + continue; + } + let mut short_path = t!(original_path.strip_prefix(directory_prefix)); + if !short_path.starts_with(MATCH) { + continue; + } + short_path = t!(short_path.strip_prefix(MATCH)); + let dst_path = dst.join(short_path); + builder.verbose(&format!("extracting {} to {}", original_path.display(), dst.display())); + if !t!(member.unpack_in(dst)) { + panic!("path traversal attack ??"); + } + let src_path = dst.join(original_path); + if src_path.is_dir() && dst_path.exists() { + continue; + } + t!(fs::rename(src_path, dst_path)); + } + t!(fs::remove_dir_all(dst.join(directory_prefix))); +} + +fn program_out_of_date(stamp: &Path, key: &str) -> bool { + if !stamp.exists() { + return true; + } + t!(fs::read_to_string(stamp)) != key +} + #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] pub struct Llvm { pub target: TargetSelection, @@ -153,7 +437,7 @@ impl Step for Llvm { }; builder.update_submodule(&Path::new("src").join("llvm-project")); - if builder.config.llvm_link_shared + if builder.llvm_link_shared() && (target.contains("windows") || target.contains("apple-darwin")) { panic!("shared linking to LLVM is not currently supported on {}", target.triple); @@ -255,7 +539,7 @@ impl Step for Llvm { // // If we're not linking rustc to a dynamic LLVM, though, then don't link // tools to it. - if builder.llvm_link_tools_dynamically(target) && builder.config.llvm_link_shared { + if builder.llvm_link_tools_dynamically(target) && builder.llvm_link_shared() { cfg.define("LLVM_LINK_LLVM_DYLIB", "ON"); } diff --git a/src/bootstrap/tarball.rs b/src/bootstrap/tarball.rs index c743c5188e7..689b4819cdd 100644 --- a/src/bootstrap/tarball.rs +++ b/src/bootstrap/tarball.rs @@ -262,11 +262,13 @@ impl<'a> Tarball<'a> { t!(std::fs::rename(&self.image_dir, &dest)); self.run(|this, cmd| { + let distdir = crate::dist::distdir(this.builder); + t!(std::fs::create_dir_all(&distdir)); cmd.arg("tarball") .arg("--input") .arg(&dest) .arg("--output") - .arg(crate::dist::distdir(this.builder).join(this.package_name())); + .arg(distdir.join(this.package_name())); }) } diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs index da468909811..1193546992c 100644 --- a/src/bootstrap/test.rs +++ b/src/bootstrap/test.rs @@ -1400,9 +1400,7 @@ note: if you're sure you want to do this, please open an issue as to why. In the targetflags.extend(builder.lld_flags(target)); cmd.arg("--target-rustcflags").arg(targetflags.join(" ")); - cmd.arg("--docck-python").arg(builder.python()); - - cmd.arg("--lldb-python").arg(builder.python()); + cmd.arg("--python").arg(builder.python()); if let Some(ref gdb) = builder.config.gdb { cmd.arg("--gdb").arg(gdb); @@ -1577,9 +1575,7 @@ note: if you're sure you want to do this, please open an issue as to why. In the cmd.env("RUSTC_PROFILER_SUPPORT", "1"); } - let tmp = builder.out.join("tmp"); - std::fs::create_dir_all(&tmp).unwrap(); - cmd.env("RUST_TEST_TMPDIR", tmp); + cmd.env("RUST_TEST_TMPDIR", builder.tempdir()); cmd.arg("--adb-path").arg("adb"); cmd.arg("--adb-test-dir").arg(ADB_TEST_DIR); @@ -2259,14 +2255,13 @@ impl Step for RemoteCopyLibs { builder.ensure(compile::Std { compiler, target }); builder.info(&format!("REMOTE copy libs to emulator ({})", target)); - t!(fs::create_dir_all(builder.out.join("tmp"))); let server = builder.ensure(tool::RemoteTestServer { compiler, target }); // Spawn the emulator and wait for it to come online let tool = builder.tool_exe(Tool::RemoteTestClient); let mut cmd = Command::new(&tool); - cmd.arg("spawn-emulator").arg(target.triple).arg(&server).arg(builder.out.join("tmp")); + cmd.arg("spawn-emulator").arg(target.triple).arg(&server).arg(builder.tempdir()); if let Some(rootfs) = builder.qemu_rootfs(target) { cmd.arg(rootfs); } @@ -2300,7 +2295,7 @@ impl Step for Distcheck { /// Runs "distcheck", a 'make check' from a tarball fn run(self, builder: &Builder<'_>) { builder.info("Distcheck"); - let dir = builder.out.join("tmp").join("distcheck"); + let dir = builder.tempdir().join("distcheck"); let _ = fs::remove_dir_all(&dir); t!(fs::create_dir_all(&dir)); @@ -2326,7 +2321,7 @@ impl Step for Distcheck { // Now make sure that rust-src has all of libstd's dependencies builder.info("Distcheck rust-src"); - let dir = builder.out.join("tmp").join("distcheck-src"); + let dir = builder.tempdir().join("distcheck-src"); let _ = fs::remove_dir_all(&dir); t!(fs::create_dir_all(&dir)); diff --git a/src/ci/docker/host-x86_64/dist-x86_64-linux/build-clang.sh b/src/ci/docker/host-x86_64/dist-x86_64-linux/build-clang.sh index 562be752f84..495c539d069 100755 --- a/src/ci/docker/host-x86_64/dist-x86_64-linux/build-clang.sh +++ b/src/ci/docker/host-x86_64/dist-x86_64-linux/build-clang.sh @@ -4,7 +4,7 @@ set -ex source shared.sh -LLVM=llvmorg-13.0.0 +LLVM=llvmorg-14.0.2 mkdir llvm-project cd llvm-project @@ -30,7 +30,12 @@ hide_output \ -DCMAKE_BUILD_TYPE=Release \ -DCMAKE_INSTALL_PREFIX=/rustroot \ -DCOMPILER_RT_BUILD_SANITIZERS=OFF \ + -DCOMPILER_RT_BUILD_XRAY=OFF \ + -DCOMPILER_RT_BUILD_MEMPROF=OFF \ -DLLVM_TARGETS_TO_BUILD=X86 \ + -DLLVM_INCLUDE_BENCHMARKS=OFF \ + -DLLVM_INCLUDE_TESTS=OFF \ + -DLLVM_INCLUDE_EXAMPLES=OFF \ -DLLVM_ENABLE_PROJECTS="clang;lld;compiler-rt" \ -DC_INCLUDE_DIRS="$INC" diff --git a/src/ci/docker/host-x86_64/dist-x86_64-linux/build-gcc.sh b/src/ci/docker/host-x86_64/dist-x86_64-linux/build-gcc.sh index 3a03eb2bdc8..7992ec3b991 100755 --- a/src/ci/docker/host-x86_64/dist-x86_64-linux/build-gcc.sh +++ b/src/ci/docker/host-x86_64/dist-x86_64-linux/build-gcc.sh @@ -3,7 +3,7 @@ set -ex source shared.sh -GCC=5.5.0 +GCC=7.5.0 curl https://ftp.gnu.org/gnu/gcc/gcc-$GCC/gcc-$GCC.tar.xz | xzcat | tar xf - cd gcc-$GCC diff --git a/src/doc/book b/src/doc/book -Subproject 765318b844569a642ceef7bf1adab9639cbf6af +Subproject de0dbffc5812fd885700874e8d258dd334733ac diff --git a/src/doc/embedded-book b/src/doc/embedded-book -Subproject a6de8b6e3ea5d4f0de8b7b9a7e5c1405dc2c2dd +Subproject f7cefbb995eec8c6148f213235e9e2e03268e77 diff --git a/src/doc/rust-by-example b/src/doc/rust-by-example -Subproject c2a98d9fc5d29c481d42052fbeccfde15ed0311 +Subproject 44a80e8d8bfc5881c9bd69a2cb3a570776ee418 diff --git a/src/doc/rustc-dev-guide b/src/doc/rustc-dev-guide -Subproject eeb5a83c15b6ae60df3e4f19207376b22c6fbc4 +Subproject 043e60f4f191651e9f8bf52fa32df14defbb23d diff --git a/src/doc/unstable-book/src/compiler-flags/cf-protection.md b/src/doc/unstable-book/src/compiler-flags/cf-protection.md index cc580ca9b42..ab698c82ba9 100644 --- a/src/doc/unstable-book/src/compiler-flags/cf-protection.md +++ b/src/doc/unstable-book/src/compiler-flags/cf-protection.md @@ -17,7 +17,7 @@ standard library does not ship with CET enabled by default, so you may need to r modules with a `cargo` command like: ```sh -$ RUSTFLAGS="-Z cf-protection=full" RUSTC="rustc-custom" cargo +nightly build -Z build-std --target x86_64-unknown-linux-gnu +$ RUSTFLAGS="-Z cf-protection=full" cargo +nightly build -Z build-std --target x86_64-unknown-linux-gnu ``` ### Detection diff --git a/src/doc/unstable-book/src/language-features/yeet-expr.md b/src/doc/unstable-book/src/language-features/yeet-expr.md new file mode 100644 index 00000000000..bc1ba4c916b --- /dev/null +++ b/src/doc/unstable-book/src/language-features/yeet-expr.md @@ -0,0 +1,26 @@ +# `yeet_expr` + +The tracking issue for this feature is: [#96373] + +[#96373]: https://github.com/rust-lang/rust/issues/96373 + +------------------------ + +The `yeet_expr` feature adds support for `do yeet` expressions, +which can be used to early-exit from a function or `try` block. + +These are highly experimental, thus the placeholder syntax. + +```rust,edition2021 +#![feature(yeet_expr)] + +fn foo() -> Result<String, i32> { + do yeet 4; +} +assert_eq!(foo(), Err(4)); + +fn bar() -> Option<String> { + do yeet; +} +assert_eq!(bar(), None); +``` diff --git a/src/etc/check_missing_items.py b/src/etc/check_missing_items.py index 89696f39262..343dd0387f4 100644 --- a/src/etc/check_missing_items.py +++ b/src/etc/check_missing_items.py @@ -49,8 +49,6 @@ def check_generic_param(param): ty = param["kind"]["type"] if ty["default"]: check_type(ty["default"]) - for bound in ty["bounds"]: - check_generic_bound(bound) elif "const" in param["kind"]: check_type(param["kind"]["const"]) diff --git a/src/librustdoc/Cargo.toml b/src/librustdoc/Cargo.toml index cc5c583bea8..21efd040663 100644 --- a/src/librustdoc/Cargo.toml +++ b/src/librustdoc/Cargo.toml @@ -22,6 +22,7 @@ regex = "1" rustdoc-json-types = { path = "../rustdoc-json-types" } tracing = "0.1" tracing-tree = "0.2.0" +once_cell = "1.10.0" [dependencies.tracing-subscriber] version = "0.3.3" diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index a070cef2272..d458deddae3 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -238,9 +238,12 @@ impl Clean<Option<Lifetime>> for ty::Region<'_> { } } -impl Clean<WherePredicate> for hir::WherePredicate<'_> { - fn clean(&self, cx: &mut DocContext<'_>) -> WherePredicate { - match *self { +impl Clean<Option<WherePredicate>> for hir::WherePredicate<'_> { + fn clean(&self, cx: &mut DocContext<'_>) -> Option<WherePredicate> { + if !self.in_where_clause() { + return None; + } + Some(match *self { hir::WherePredicate::BoundPredicate(ref wbp) => { let bound_params = wbp .bound_generic_params @@ -250,11 +253,7 @@ impl Clean<WherePredicate> for hir::WherePredicate<'_> { // Higher-ranked lifetimes can't have bounds. assert_matches!( param, - hir::GenericParam { - kind: hir::GenericParamKind::Lifetime { .. }, - bounds: [], - .. - } + hir::GenericParam { kind: hir::GenericParamKind::Lifetime { .. }, .. } ); Lifetime(param.name.ident().name) }) @@ -275,7 +274,7 @@ impl Clean<WherePredicate> for hir::WherePredicate<'_> { lhs: wrp.lhs_ty.clean(cx), rhs: wrp.rhs_ty.clean(cx).into(), }, - } + }) } } @@ -456,44 +455,75 @@ impl Clean<GenericParamDef> for ty::GenericParamDef { } } -impl Clean<GenericParamDef> for hir::GenericParam<'_> { - fn clean(&self, cx: &mut DocContext<'_>) -> GenericParamDef { - let (name, kind) = match self.kind { - hir::GenericParamKind::Lifetime { .. } => { - let outlives = self - .bounds +fn clean_generic_param( + cx: &mut DocContext<'_>, + generics: Option<&hir::Generics<'_>>, + param: &hir::GenericParam<'_>, +) -> GenericParamDef { + let (name, kind) = match param.kind { + hir::GenericParamKind::Lifetime { .. } => { + let outlives = if let Some(generics) = generics { + generics + .predicates .iter() + .flat_map(|pred| { + match pred { + hir::WherePredicate::RegionPredicate(rp) + if rp.lifetime.name == hir::LifetimeName::Param(param.name) + && !rp.in_where_clause => + { + rp.bounds + } + _ => &[], + } + .iter() + }) .map(|bound| match bound { hir::GenericBound::Outlives(lt) => lt.clean(cx), _ => panic!(), }) - .collect(); - (self.name.ident().name, GenericParamDefKind::Lifetime { outlives }) - } - hir::GenericParamKind::Type { ref default, synthetic } => ( - self.name.ident().name, + .collect() + } else { + Vec::new() + }; + (param.name.ident().name, GenericParamDefKind::Lifetime { outlives }) + } + hir::GenericParamKind::Type { ref default, synthetic } => { + let did = cx.tcx.hir().local_def_id(param.hir_id); + let bounds = if let Some(generics) = generics { + generics + .bounds_for_param(did) + .filter(|bp| !bp.in_where_clause) + .flat_map(|bp| bp.bounds) + .filter_map(|x| x.clean(cx)) + .collect() + } else { + Vec::new() + }; + ( + param.name.ident().name, GenericParamDefKind::Type { - did: cx.tcx.hir().local_def_id(self.hir_id).to_def_id(), - bounds: self.bounds.iter().filter_map(|x| x.clean(cx)).collect(), + did: did.to_def_id(), + bounds, default: default.map(|t| t.clean(cx)).map(Box::new), synthetic, }, - ), - hir::GenericParamKind::Const { ref ty, default } => ( - self.name.ident().name, - GenericParamDefKind::Const { - did: cx.tcx.hir().local_def_id(self.hir_id).to_def_id(), - ty: Box::new(ty.clean(cx)), - default: default.map(|ct| { - let def_id = cx.tcx.hir().local_def_id(ct.hir_id); - Box::new(ty::Const::from_anon_const(cx.tcx, def_id).to_string()) - }), - }, - ), - }; + ) + } + hir::GenericParamKind::Const { ref ty, default } => ( + param.name.ident().name, + GenericParamDefKind::Const { + did: cx.tcx.hir().local_def_id(param.hir_id).to_def_id(), + ty: Box::new(ty.clean(cx)), + default: default.map(|ct| { + let def_id = cx.tcx.hir().local_def_id(ct.hir_id); + Box::new(ty::Const::from_anon_const(cx.tcx, def_id).to_string()) + }), + }, + ), + }; - GenericParamDef { name, kind } - } + GenericParamDef { name, kind } } impl Clean<Generics> for hir::Generics<'_> { @@ -524,7 +554,7 @@ impl Clean<Generics> for hir::Generics<'_> { .iter() .filter(|param| is_impl_trait(param)) .map(|param| { - let param: GenericParamDef = param.clean(cx); + let param = clean_generic_param(cx, Some(self), param); match param.kind { GenericParamDefKind::Lifetime { .. } => unreachable!(), GenericParamDefKind::Type { did, ref bounds, .. } => { @@ -538,14 +568,14 @@ impl Clean<Generics> for hir::Generics<'_> { let mut params = Vec::with_capacity(self.params.len()); for p in self.params.iter().filter(|p| !is_impl_trait(p) && !is_elided_lifetime(p)) { - let p = p.clean(cx); + let p = clean_generic_param(cx, Some(self), p); params.push(p); } params.extend(impl_trait_params); let mut generics = Generics { params, - where_predicates: self.where_clause.predicates.iter().map(|x| x.clean(cx)).collect(), + where_predicates: self.predicates.iter().filter_map(|x| x.clean(cx)).collect(), }; // Some duplicates are generated for ?Sized bounds between type params and where @@ -954,7 +984,11 @@ impl Clean<PolyTrait> for hir::PolyTraitRef<'_> { fn clean(&self, cx: &mut DocContext<'_>) -> PolyTrait { PolyTrait { trait_: self.trait_ref.clean(cx), - generic_params: self.bound_generic_params.iter().map(|x| x.clean(cx)).collect(), + generic_params: self + .bound_generic_params + .iter() + .map(|x| clean_generic_param(cx, None, x)) + .collect(), } } } @@ -1305,7 +1339,7 @@ fn clean_qpath(hir_ty: &hir::Ty<'_>, cx: &mut DocContext<'_>) -> Type { fn maybe_expand_private_type_alias(cx: &mut DocContext<'_>, path: &hir::Path<'_>) -> Option<Type> { let Res::Def(DefKind::TyAlias, def_id) = path.res else { return None }; // Substitute private type aliases - let Some(def_id) = def_id.as_local() else { return None }; + let def_id = def_id.as_local()?; let alias = if !cx.cache.access_levels.is_exported(def_id.to_def_id()) { &cx.tcx.hir().expect_item(def_id).kind } else { @@ -1823,7 +1857,8 @@ impl Clean<BareFunctionDecl> for hir::BareFnTy<'_> { fn clean(&self, cx: &mut DocContext<'_>) -> BareFunctionDecl { let (generic_params, decl) = enter_impl_trait(cx, |cx| { // NOTE: generics must be cleaned before args - let generic_params = self.generic_params.iter().map(|x| x.clean(cx)).collect(); + let generic_params = + self.generic_params.iter().map(|x| clean_generic_param(cx, None, x)).collect(); let args = clean_args_from_types_and_names(cx, self.decl.inputs, self.param_names); let decl = clean_fn_decl_with_args(cx, self.decl, args); (generic_params, decl) diff --git a/src/librustdoc/clean/render_macro_matchers.rs b/src/librustdoc/clean/render_macro_matchers.rs index 58ca8869ea9..a9c0fe6f079 100644 --- a/src/librustdoc/clean/render_macro_matchers.rs +++ b/src/librustdoc/clean/render_macro_matchers.rs @@ -1,4 +1,4 @@ -use rustc_ast::token::{self, BinOpToken, DelimToken}; +use rustc_ast::token::{self, BinOpToken, Delimiter}; use rustc_ast::tokenstream::{TokenStream, TokenTree}; use rustc_ast_pretty::pprust::state::State as Printer; use rustc_ast_pretty::pprust::PrintState; @@ -104,11 +104,11 @@ fn print_tt(printer: &mut Printer<'_>, tt: &TokenTree) { let open_delim = printer.token_kind_to_string(&token::OpenDelim(*delim)); printer.word(open_delim); if !tts.is_empty() { - if *delim == DelimToken::Brace { + if *delim == Delimiter::Brace { printer.space(); } print_tts(printer, tts); - if *delim == DelimToken::Brace { + if *delim == Delimiter::Brace { printer.space(); } } @@ -162,9 +162,9 @@ fn print_tts(printer: &mut Printer<'_>, tts: &TokenStream) { (_, _) => (true, Other), }, TokenTree::Delimited(_, delim, _) => match (state, delim) { - (Dollar, DelimToken::Paren) => (false, DollarParen), - (Pound | PoundBang, DelimToken::Bracket) => (false, Other), - (Ident, DelimToken::Paren | DelimToken::Bracket) => (false, Other), + (Dollar, Delimiter::Parenthesis) => (false, DollarParen), + (Pound | PoundBang, Delimiter::Bracket) => (false, Other), + (Ident, Delimiter::Parenthesis | Delimiter::Bracket) => (false, Other), (_, _) => (true, Other), }, }; diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index e30bc6e0a97..2b65b8f910c 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -1,13 +1,11 @@ use std::cell::RefCell; use std::default::Default; -use std::fmt; use std::hash::Hash; -use std::iter; use std::lazy::SyncOnceCell as OnceCell; use std::path::PathBuf; use std::rc::Rc; use std::sync::Arc; -use std::vec; +use std::{cmp, fmt, iter}; use arrayvec::ArrayVec; @@ -55,6 +53,9 @@ crate use self::Type::{ }; crate use self::Visibility::{Inherited, Public}; +#[cfg(test)] +mod tests; + crate type ItemIdSet = FxHashSet<ItemId>; #[derive(Debug, Clone, PartialEq, Eq, Hash, Copy)] @@ -1028,6 +1029,86 @@ crate fn collapse_doc_fragments(doc_strings: &[DocFragment]) -> String { acc } +/// Removes excess indentation on comments in order for the Markdown +/// to be parsed correctly. This is necessary because the convention for +/// writing documentation is to provide a space between the /// or //! marker +/// and the doc text, but Markdown is whitespace-sensitive. For example, +/// a block of text with four-space indentation is parsed as a code block, +/// so if we didn't unindent comments, these list items +/// +/// /// A list: +/// /// +/// /// - Foo +/// /// - Bar +/// +/// would be parsed as if they were in a code block, which is likely not what the user intended. +fn unindent_doc_fragments(docs: &mut Vec<DocFragment>) { + // `add` is used in case the most common sugared doc syntax is used ("/// "). The other + // fragments kind's lines are never starting with a whitespace unless they are using some + // markdown formatting requiring it. Therefore, if the doc block have a mix between the two, + // we need to take into account the fact that the minimum indent minus one (to take this + // whitespace into account). + // + // For example: + // + // /// hello! + // #[doc = "another"] + // + // In this case, you want "hello! another" and not "hello! another". + let add = if docs.windows(2).any(|arr| arr[0].kind != arr[1].kind) + && docs.iter().any(|d| d.kind == DocFragmentKind::SugaredDoc) + { + // In case we have a mix of sugared doc comments and "raw" ones, we want the sugared one to + // "decide" how much the minimum indent will be. + 1 + } else { + 0 + }; + + // `min_indent` is used to know how much whitespaces from the start of each lines must be + // removed. Example: + // + // /// hello! + // #[doc = "another"] + // + // In here, the `min_indent` is 1 (because non-sugared fragment are always counted with minimum + // 1 whitespace), meaning that "hello!" will be considered a codeblock because it starts with 4 + // (5 - 1) whitespaces. + let Some(min_indent) = docs + .iter() + .map(|fragment| { + fragment.doc.as_str().lines().fold(usize::MAX, |min_indent, line| { + if line.chars().all(|c| c.is_whitespace()) { + min_indent + } else { + // Compare against either space or tab, ignoring whether they are + // mixed or not. + let whitespace = line.chars().take_while(|c| *c == ' ' || *c == '\t').count(); + cmp::min(min_indent, whitespace) + + if fragment.kind == DocFragmentKind::SugaredDoc { 0 } else { add } + } + }) + }) + .min() + else { + return; + }; + + for fragment in docs { + if fragment.doc == kw::Empty { + continue; + } + + let min_indent = if fragment.kind != DocFragmentKind::SugaredDoc && min_indent > 0 { + min_indent - add + } else { + min_indent + }; + + fragment.indent = min_indent; + } +} + /// A link that has not yet been rendered. /// /// This link will be turned into a rendered link by [`Item::links`]. @@ -1089,35 +1170,37 @@ impl Attributes { attrs: &[ast::Attribute], additional_attrs: Option<(&[ast::Attribute], DefId)>, ) -> Attributes { - let mut doc_strings: Vec<DocFragment> = vec![]; - let clean_attr = |(attr, parent_module): (&ast::Attribute, Option<DefId>)| { - if let Some((value, kind)) = attr.doc_str_and_comment_kind() { - trace!("got doc_str={:?}", value); - let value = beautify_doc_string(value, kind); + // Additional documentation should be shown before the original documentation. + let attrs1 = additional_attrs + .into_iter() + .flat_map(|(attrs, def_id)| attrs.iter().map(move |attr| (attr, Some(def_id)))); + let attrs2 = attrs.iter().map(|attr| (attr, None)); + Attributes::from_ast_iter(attrs1.chain(attrs2), false) + } + + crate fn from_ast_iter<'a>( + attrs: impl Iterator<Item = (&'a ast::Attribute, Option<DefId>)>, + doc_only: bool, + ) -> Attributes { + let mut doc_strings = Vec::new(); + let mut other_attrs = Vec::new(); + for (attr, parent_module) in attrs { + if let Some((doc_str, comment_kind)) = attr.doc_str_and_comment_kind() { + trace!("got doc_str={doc_str:?}"); + let doc = beautify_doc_string(doc_str, comment_kind); let kind = if attr.is_doc_comment() { DocFragmentKind::SugaredDoc } else { DocFragmentKind::RawDoc }; - - let frag = - DocFragment { span: attr.span, doc: value, kind, parent_module, indent: 0 }; - - doc_strings.push(frag); - - None - } else { - Some(attr.clone()) + let fragment = DocFragment { span: attr.span, doc, kind, parent_module, indent: 0 }; + doc_strings.push(fragment); + } else if !doc_only { + other_attrs.push(attr.clone()); } - }; + } - // Additional documentation should be shown before the original documentation - let other_attrs = additional_attrs - .into_iter() - .flat_map(|(attrs, id)| attrs.iter().map(move |attr| (attr, Some(id)))) - .chain(attrs.iter().map(|attr| (attr, None))) - .filter_map(clean_attr) - .collect(); + unindent_doc_fragments(&mut doc_strings); Attributes { doc_strings, other_attrs } } @@ -1138,23 +1221,17 @@ impl Attributes { } /// Return the doc-comments on this item, grouped by the module they came from. - /// /// The module can be different if this is a re-export with added documentation. - crate fn collapsed_doc_value_by_module_level(&self) -> FxHashMap<Option<DefId>, String> { - let mut ret = FxHashMap::default(); - if self.doc_strings.len() == 0 { - return ret; - } - let last_index = self.doc_strings.len() - 1; - - for (i, new_frag) in self.doc_strings.iter().enumerate() { - let out = ret.entry(new_frag.parent_module).or_default(); - add_doc_fragment(out, new_frag); - if i == last_index { - out.pop(); - } + /// + /// The last newline is not trimmed so the produced strings are reusable between + /// early and late doc link resolution regardless of their position. + crate fn prepare_to_doc_link_resolution(&self) -> FxHashMap<Option<DefId>, String> { + let mut res = FxHashMap::default(); + for fragment in &self.doc_strings { + let out_str = res.entry(fragment.parent_module).or_default(); + add_doc_fragment(out_str, fragment); } - ret + res } /// Finds all `doc` attributes as NameValues and returns their corresponding values, joined diff --git a/src/librustdoc/passes/unindent_comments/tests.rs b/src/librustdoc/clean/types/tests.rs index baff839cdc8..71eddf4348f 100644 --- a/src/librustdoc/passes/unindent_comments/tests.rs +++ b/src/librustdoc/clean/types/tests.rs @@ -20,7 +20,7 @@ fn create_doc_fragment(s: &str) -> Vec<DocFragment> { fn run_test(input: &str, expected: &str) { create_default_session_globals_then(|| { let mut s = create_doc_fragment(input); - unindent_fragments(&mut s); + unindent_doc_fragments(&mut s); assert_eq!(collapse_doc_fragments(&s), expected); }); } diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs index cee3dcb416f..1ff2c8191e5 100644 --- a/src/librustdoc/config.rs +++ b/src/librustdoc/config.rs @@ -10,7 +10,9 @@ use rustc_session::config::{ self, parse_crate_types_from_list, parse_externs, parse_target_triple, CrateType, }; use rustc_session::config::{get_cmd_lint_options, nightly_options}; -use rustc_session::config::{CodegenOptions, DebuggingOptions, ErrorOutputType, Externs}; +use rustc_session::config::{ + CodegenOptions, DebuggingOptions, ErrorOutputType, Externs, JsonUnusedExterns, +}; use rustc_session::getopts; use rustc_session::lint::Level; use rustc_session::search_paths::SearchPath; @@ -147,7 +149,7 @@ crate struct Options { /// documentation. crate run_check: bool, /// Whether doctests should emit unused externs - crate json_unused_externs: bool, + crate json_unused_externs: JsonUnusedExterns, /// Whether to skip capturing stdout and stderr of tests. crate nocapture: bool, diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index b9e20c41b68..1db6064551c 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -4,7 +4,7 @@ use rustc_data_structures::sync::{self, Lrc}; use rustc_errors::emitter::{Emitter, EmitterWriter}; use rustc_errors::json::JsonEmitter; use rustc_feature::UnstableFeatures; -use rustc_hir::def::Res; +use rustc_hir::def::{Namespace, Res}; use rustc_hir::def_id::{DefId, DefIdMap, LocalDefId}; use rustc_hir::intravisit::{self, Visitor}; use rustc_hir::{HirId, Path, TraitCandidate}; @@ -29,11 +29,14 @@ use crate::clean::inline::build_external_trait; use crate::clean::{self, ItemId, TraitWithExtraInfo}; use crate::config::{Options as RustdocOptions, OutputFormat, RenderOptions}; use crate::formats::cache::Cache; +use crate::passes::collect_intra_doc_links::PreprocessedMarkdownLink; use crate::passes::{self, Condition::*}; crate use rustc_session::config::{DebuggingOptions, Input, Options}; crate struct ResolverCaches { + crate markdown_links: Option<FxHashMap<String, Vec<PreprocessedMarkdownLink>>>, + crate doc_link_resolutions: FxHashMap<(Symbol, Namespace, DefId), Option<Res<NodeId>>>, /// Traits in scope for a given module. /// See `collect_intra_doc_links::traits_implemented_by` for more details. crate traits_in_scope: DefIdMap<Vec<TraitCandidate>>, diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs index 61826844574..82e367427ef 100644 --- a/src/librustdoc/doctest.rs +++ b/src/librustdoc/doctest.rs @@ -168,7 +168,7 @@ crate fn run(options: RustdocOptions) -> Result<(), ErrorGuaranteed> { // Collect and warn about unused externs, but only if we've gotten // reports for each doctest - if json_unused_externs { + if json_unused_externs.is_enabled() { let unused_extern_reports: Vec<_> = std::mem::take(&mut unused_extern_reports.lock().unwrap()); if unused_extern_reports.len() == compiling_test_count { @@ -337,7 +337,7 @@ fn run_test( if lang_string.test_harness { compiler.arg("--test"); } - if rustdoc_options.json_unused_externs && !lang_string.compile_fail { + if rustdoc_options.json_unused_externs.is_enabled() && !lang_string.compile_fail { compiler.arg("--error-format=json"); compiler.arg("--json").arg("unused-externs"); compiler.arg("-Z").arg("unstable-options"); @@ -1174,8 +1174,6 @@ impl<'a, 'hir, 'tcx> HirCollector<'a, 'hir, 'tcx> { nested: F, ) { let ast_attrs = self.tcx.hir().attrs(hir_id); - let mut attrs = Attributes::from_ast(ast_attrs, None); - if let Some(ref cfg) = ast_attrs.cfg(self.tcx, &FxHashSet::default()) { if !cfg.matches(&self.sess.parse_sess, Some(self.sess.features_untracked())) { return; @@ -1187,9 +1185,9 @@ impl<'a, 'hir, 'tcx> HirCollector<'a, 'hir, 'tcx> { self.collector.names.push(name); } - attrs.unindent_doc_comments(); // The collapse-docs pass won't combine sugared/raw doc attributes, or included files with // anything else, this will combine them for us. + let attrs = Attributes::from_ast(ast_attrs, None); if let Some(doc) = attrs.collapsed_doc_value() { // Use the outermost invocation, so that doctest names come from where the docs were written. let span = ast_attrs diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index 6954e2363f5..118807a8286 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -18,6 +18,7 @@ use rustc_hir::def_id::DefId; use rustc_middle::ty; use rustc_middle::ty::DefIdTree; use rustc_middle::ty::TyCtxt; +use rustc_span::symbol::kw; use rustc_span::{sym, Symbol}; use rustc_target::spec::abi::Abi; @@ -267,6 +268,8 @@ crate fn print_where_clause<'a, 'tcx: 'a>( indent: usize, end_newline: bool, ) -> impl fmt::Display + 'a + Captures<'tcx> { + use fmt::Write; + display_fn(move |f| { let mut where_predicates = gens.where_predicates.iter().filter(|pred| { !matches!(pred, clean::WherePredicate::BoundPredicate { bounds, .. } if bounds.is_empty()) @@ -280,56 +283,44 @@ crate fn print_where_clause<'a, 'tcx: 'a>( match pred { clean::WherePredicate::BoundPredicate { ty, bounds, bound_params } => { - let bounds = bounds; - let for_prefix = if bound_params.is_empty() { - String::new() - } else if f.alternate() { - format!( - "for<{:#}> ", - comma_sep(bound_params.iter().map(|lt| lt.print()), true) - ) - } else { - format!( - "for<{}> ", - comma_sep(bound_params.iter().map(|lt| lt.print()), true) - ) - }; + let ty_cx = ty.print(cx); + let generic_bounds = print_generic_bounds(bounds, cx); - if f.alternate() { - write!( - f, - "{}{:#}: {:#}", - for_prefix, - ty.print(cx), - print_generic_bounds(bounds, cx) - ) + if bound_params.is_empty() { + if f.alternate() { + write!(f, "{ty_cx:#}: {generic_bounds:#}") + } else { + write!(f, "{ty_cx}: {generic_bounds}") + } } else { - write!( - f, - "{}{}: {}", - for_prefix, - ty.print(cx), - print_generic_bounds(bounds, cx) - ) + if f.alternate() { + write!( + f, + "for<{:#}> {ty_cx:#}: {generic_bounds:#}", + comma_sep(bound_params.iter().map(|lt| lt.print()), true) + ) + } else { + write!( + f, + "for<{}> {ty_cx}: {generic_bounds}", + comma_sep(bound_params.iter().map(|lt| lt.print()), true) + ) + } } } clean::WherePredicate::RegionPredicate { lifetime, bounds } => { - write!( - f, - "{}: {}", - lifetime.print(), - bounds - .iter() - .map(|b| b.print(cx).to_string()) - .collect::<Vec<_>>() - .join(" + ") - ) + let mut bounds_display = String::new(); + for bound in bounds.iter().map(|b| b.print(cx)) { + write!(bounds_display, "{bound} + ")?; + } + bounds_display.truncate(bounds_display.len() - " + ".len()); + write!(f, "{}: {bounds_display}", lifetime.print()) } clean::WherePredicate::EqPredicate { lhs, rhs } => { if f.alternate() { - write!(f, "{:#} == {:#}", lhs.print(cx), rhs.print(cx),) + write!(f, "{:#} == {:#}", lhs.print(cx), rhs.print(cx)) } else { - write!(f, "{} == {}", lhs.print(cx), rhs.print(cx),) + write!(f, "{} == {}", lhs.print(cx), rhs.print(cx)) } } } @@ -340,40 +331,43 @@ crate fn print_where_clause<'a, 'tcx: 'a>( return Ok(()); } - let mut clause = String::new(); - - if f.alternate() { - clause.push_str(" where"); - } else { + let where_preds = comma_sep(where_predicates, false); + let clause = if f.alternate() { if end_newline { - clause.push_str(" <span class=\"where fmt-newline\">where"); + // add a space so stripping <br> tags and breaking spaces still renders properly + format!(" where{where_preds}, ") } else { - clause.push_str(" <span class=\"where\">where"); + format!(" where{where_preds}") } - } - - clause.push_str(&comma_sep(where_predicates, false).to_string()); - - if end_newline { - clause.push(','); - // add a space so stripping <br> tags and breaking spaces still renders properly - if f.alternate() { - clause.push(' '); - } else { - clause.push_str(" "); + } else { + let mut br_with_padding = String::with_capacity(6 * indent + 28); + br_with_padding.push_str("<br>"); + for _ in 0..indent + 4 { + br_with_padding.push_str(" "); } - } + let where_preds = where_preds.to_string().replace("<br>", &br_with_padding); - if !f.alternate() { - clause.push_str("</span>"); - let padding = " ".repeat(indent + 4); - clause = clause.replace("<br>", &format!("<br>{}", padding)); - clause.insert_str(0, &" ".repeat(indent.saturating_sub(1))); - if !end_newline { - clause.insert_str(0, "<br>"); + if end_newline { + let mut clause = " ".repeat(indent.saturating_sub(1)); + // add a space so stripping <br> tags and breaking spaces still renders properly + write!( + clause, + " <span class=\"where fmt-newline\">where{where_preds}, </span>" + )?; + clause + } else { + // insert a <br> tag after a single space but before multiple spaces at the start + if indent == 0 { + format!(" <br><span class=\"where\">where{where_preds}</span>") + } else { + let mut clause = br_with_padding; + clause.truncate(clause.len() - 5 * " ".len()); + write!(clause, " <span class=\"where\">where{where_preds}</span>")?; + clause + } } - } - write!(f, "{}", clause) + }; + write!(f, "{clause}") }) } @@ -686,7 +680,7 @@ fn resolved_path<'cx>( if print_all { for seg in &path.segments[..path.segments.len() - 1] { - write!(w, "{}::", seg.name)?; + write!(w, "{}::", if seg.name == kw::PathRoot { "" } else { seg.name.as_str() })?; } } if w.alternate() { diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs index 1ebb41b5933..9e76af98298 100644 --- a/src/librustdoc/html/markdown.rs +++ b/src/librustdoc/html/markdown.rs @@ -32,6 +32,7 @@ use rustc_middle::ty::TyCtxt; use rustc_span::edition::Edition; use rustc_span::Span; +use once_cell::sync::Lazy; use std::borrow::Cow; use std::cell::RefCell; use std::collections::VecDeque; @@ -1255,7 +1256,7 @@ crate struct MarkdownLink { pub range: Range<usize>, } -crate fn markdown_links(md: &str) -> Vec<MarkdownLink> { +crate fn markdown_links<R>(md: &str, filter_map: impl Fn(MarkdownLink) -> Option<R>) -> Vec<R> { if md.is_empty() { return vec![]; } @@ -1295,11 +1296,12 @@ crate fn markdown_links(md: &str) -> Vec<MarkdownLink> { let mut push = |link: BrokenLink<'_>| { let span = span_for_link(&link.reference, link.span); - links.borrow_mut().push(MarkdownLink { + filter_map(MarkdownLink { kind: LinkType::ShortcutUnknown, link: link.reference.to_string(), range: span, - }); + }) + .map(|link| links.borrow_mut().push(link)); None }; let p = Parser::new_with_broken_link_callback(md, main_body_opts(), Some(&mut push)) @@ -1311,10 +1313,23 @@ crate fn markdown_links(md: &str) -> Vec<MarkdownLink> { let iter = Footnotes::new(HeadingLinks::new(p, None, &mut ids, HeadingOffset::H1)); for ev in iter { - if let Event::Start(Tag::Link(kind, dest, _)) = ev.0 { + if let Event::Start(Tag::Link( + // `<>` links cannot be intra-doc links so we skip them. + kind @ (LinkType::Inline + | LinkType::Reference + | LinkType::ReferenceUnknown + | LinkType::Collapsed + | LinkType::CollapsedUnknown + | LinkType::Shortcut + | LinkType::ShortcutUnknown), + dest, + _, + )) = ev.0 + { debug!("found link: {dest}"); let span = span_for_link(&dest, ev.1); - links.borrow_mut().push(MarkdownLink { kind, link: dest.into_string(), range: span }); + filter_map(MarkdownLink { kind, link: dest.into_string(), range: span }) + .map(|link| links.borrow_mut().push(link)); } } @@ -1415,62 +1430,65 @@ crate fn rust_code_blocks(md: &str, extra_info: &ExtraInfo<'_>) -> Vec<RustCodeB #[derive(Clone, Default, Debug)] pub struct IdMap { - map: FxHashMap<String, usize>, + map: FxHashMap<Cow<'static, str>, usize>, } -fn init_id_map() -> FxHashMap<String, usize> { +// The map is pre-initialized and cloned each time to avoid reinitializing it repeatedly. +static DEFAULT_ID_MAP: Lazy<FxHashMap<Cow<'static, str>, usize>> = Lazy::new(|| init_id_map()); + +fn init_id_map() -> FxHashMap<Cow<'static, str>, usize> { let mut map = FxHashMap::default(); // This is the list of IDs used in Javascript. - map.insert("help".to_owned(), 1); + map.insert("help".into(), 1); // This is the list of IDs used in HTML generated in Rust (including the ones // used in tera template files). - map.insert("mainThemeStyle".to_owned(), 1); - map.insert("themeStyle".to_owned(), 1); - map.insert("theme-picker".to_owned(), 1); - map.insert("theme-choices".to_owned(), 1); - map.insert("settings-menu".to_owned(), 1); - map.insert("help-button".to_owned(), 1); - map.insert("main-content".to_owned(), 1); - map.insert("search".to_owned(), 1); - map.insert("crate-search".to_owned(), 1); - map.insert("render-detail".to_owned(), 1); - map.insert("toggle-all-docs".to_owned(), 1); - map.insert("all-types".to_owned(), 1); - map.insert("default-settings".to_owned(), 1); - map.insert("rustdoc-vars".to_owned(), 1); - map.insert("sidebar-vars".to_owned(), 1); - map.insert("copy-path".to_owned(), 1); - map.insert("TOC".to_owned(), 1); + map.insert("mainThemeStyle".into(), 1); + map.insert("themeStyle".into(), 1); + map.insert("theme-picker".into(), 1); + map.insert("theme-choices".into(), 1); + map.insert("settings-menu".into(), 1); + map.insert("help-button".into(), 1); + map.insert("main-content".into(), 1); + map.insert("search".into(), 1); + map.insert("crate-search".into(), 1); + map.insert("render-detail".into(), 1); + map.insert("toggle-all-docs".into(), 1); + map.insert("all-types".into(), 1); + map.insert("default-settings".into(), 1); + map.insert("rustdoc-vars".into(), 1); + map.insert("sidebar-vars".into(), 1); + map.insert("copy-path".into(), 1); + map.insert("TOC".into(), 1); // This is the list of IDs used by rustdoc sections (but still generated by // rustdoc). - map.insert("fields".to_owned(), 1); - map.insert("variants".to_owned(), 1); - map.insert("implementors-list".to_owned(), 1); - map.insert("synthetic-implementors-list".to_owned(), 1); - map.insert("foreign-impls".to_owned(), 1); - map.insert("implementations".to_owned(), 1); - map.insert("trait-implementations".to_owned(), 1); - map.insert("synthetic-implementations".to_owned(), 1); - map.insert("blanket-implementations".to_owned(), 1); - map.insert("required-associated-types".to_owned(), 1); - map.insert("provided-associated-types".to_owned(), 1); - map.insert("provided-associated-consts".to_owned(), 1); - map.insert("required-associated-consts".to_owned(), 1); - map.insert("required-methods".to_owned(), 1); - map.insert("provided-methods".to_owned(), 1); - map.insert("implementors".to_owned(), 1); - map.insert("synthetic-implementors".to_owned(), 1); - map.insert("implementations-list".to_owned(), 1); - map.insert("trait-implementations-list".to_owned(), 1); - map.insert("synthetic-implementations-list".to_owned(), 1); - map.insert("blanket-implementations-list".to_owned(), 1); - map.insert("deref-methods".to_owned(), 1); + map.insert("fields".into(), 1); + map.insert("variants".into(), 1); + map.insert("implementors-list".into(), 1); + map.insert("synthetic-implementors-list".into(), 1); + map.insert("foreign-impls".into(), 1); + map.insert("implementations".into(), 1); + map.insert("trait-implementations".into(), 1); + map.insert("synthetic-implementations".into(), 1); + map.insert("blanket-implementations".into(), 1); + map.insert("required-associated-types".into(), 1); + map.insert("provided-associated-types".into(), 1); + map.insert("provided-associated-consts".into(), 1); + map.insert("required-associated-consts".into(), 1); + map.insert("required-methods".into(), 1); + map.insert("provided-methods".into(), 1); + map.insert("implementors".into(), 1); + map.insert("synthetic-implementors".into(), 1); + map.insert("implementations-list".into(), 1); + map.insert("trait-implementations-list".into(), 1); + map.insert("synthetic-implementations-list".into(), 1); + map.insert("blanket-implementations-list".into(), 1); + map.insert("deref-methods".into(), 1); map } impl IdMap { pub fn new() -> Self { - IdMap { map: init_id_map() } + IdMap { map: DEFAULT_ID_MAP.clone() } } crate fn derive<S: AsRef<str> + ToString>(&mut self, candidate: S) -> String { @@ -1483,7 +1501,7 @@ impl IdMap { } }; - self.map.insert(id.clone(), 1); + self.map.insert(id.clone().into(), 1); id } } diff --git a/src/librustdoc/html/render/span_map.rs b/src/librustdoc/html/render/span_map.rs index 06c63ec97d7..b5502309560 100644 --- a/src/librustdoc/html/render/span_map.rs +++ b/src/librustdoc/html/render/span_map.rs @@ -5,7 +5,7 @@ use rustc_data_structures::fx::FxHashMap; use rustc_hir::def::{DefKind, Res}; use rustc_hir::def_id::DefId; use rustc_hir::intravisit::{self, Visitor}; -use rustc_hir::{ExprKind, GenericParam, GenericParamKind, HirId, Mod, Node}; +use rustc_hir::{ExprKind, GenericParam, HirId, Mod, Node}; use rustc_middle::hir::nested_filter; use rustc_middle::ty::TyCtxt; use rustc_span::Span; @@ -100,16 +100,7 @@ impl<'tcx> Visitor<'tcx> for SpanMapVisitor<'tcx> { self.tcx.hir() } - fn visit_generic_param(&mut self, p: &'tcx GenericParam<'tcx>) { - if !matches!(p.kind, GenericParamKind::Type { .. }) { - return; - } - for bound in p.bounds { - if let Some(trait_ref) = bound.trait_ref() { - self.handle_path(trait_ref.path, None); - } - } - } + fn visit_generic_param(&mut self, _: &'tcx GenericParam<'tcx>) {} fn visit_path(&mut self, path: &'tcx rustc_hir::Path<'tcx>, _id: HirId) { self.handle_path(path, None); diff --git a/src/librustdoc/html/render/write_shared.rs b/src/librustdoc/html/render/write_shared.rs index 371d0e84087..7c202e471ad 100644 --- a/src/librustdoc/html/render/write_shared.rs +++ b/src/librustdoc/html/render/write_shared.rs @@ -21,27 +21,18 @@ use crate::{try_err, try_none}; static FILES_UNVERSIONED: Lazy<FxHashMap<&str, &[u8]>> = Lazy::new(|| { map! { - "FiraSans-Regular.woff2" => static_files::fira_sans::REGULAR2, - "FiraSans-Medium.woff2" => static_files::fira_sans::MEDIUM2, - "FiraSans-Regular.woff" => static_files::fira_sans::REGULAR, - "FiraSans-Medium.woff" => static_files::fira_sans::MEDIUM, + "FiraSans-Regular.woff2" => static_files::fira_sans::REGULAR, + "FiraSans-Medium.woff2" => static_files::fira_sans::MEDIUM, "FiraSans-LICENSE.txt" => static_files::fira_sans::LICENSE, - "SourceSerif4-Regular.ttf.woff2" => static_files::source_serif_4::REGULAR2, - "SourceSerif4-Bold.ttf.woff2" => static_files::source_serif_4::BOLD2, - "SourceSerif4-It.ttf.woff2" => static_files::source_serif_4::ITALIC2, - "SourceSerif4-Regular.ttf.woff" => static_files::source_serif_4::REGULAR, - "SourceSerif4-Bold.ttf.woff" => static_files::source_serif_4::BOLD, - "SourceSerif4-It.ttf.woff" => static_files::source_serif_4::ITALIC, + "SourceSerif4-Regular.ttf.woff2" => static_files::source_serif_4::REGULAR, + "SourceSerif4-Bold.ttf.woff2" => static_files::source_serif_4::BOLD, + "SourceSerif4-It.ttf.woff2" => static_files::source_serif_4::ITALIC, "SourceSerif4-LICENSE.md" => static_files::source_serif_4::LICENSE, - "SourceCodePro-Regular.ttf.woff2" => static_files::source_code_pro::REGULAR2, - "SourceCodePro-Semibold.ttf.woff2" => static_files::source_code_pro::SEMIBOLD2, - "SourceCodePro-It.ttf.woff2" => static_files::source_code_pro::ITALIC2, - "SourceCodePro-Regular.ttf.woff" => static_files::source_code_pro::REGULAR, - "SourceCodePro-Semibold.ttf.woff" => static_files::source_code_pro::SEMIBOLD, - "SourceCodePro-It.ttf.woff" => static_files::source_code_pro::ITALIC, + "SourceCodePro-Regular.ttf.woff2" => static_files::source_code_pro::REGULAR, + "SourceCodePro-Semibold.ttf.woff2" => static_files::source_code_pro::SEMIBOLD, + "SourceCodePro-It.ttf.woff2" => static_files::source_code_pro::ITALIC, "SourceCodePro-LICENSE.txt" => static_files::source_code_pro::LICENSE, - "NanumBarunGothic.ttf.woff2" => static_files::nanum_barun_gothic::REGULAR2, - "NanumBarunGothic.ttf.woff" => static_files::nanum_barun_gothic::REGULAR, + "NanumBarunGothic.ttf.woff2" => static_files::nanum_barun_gothic::REGULAR, "NanumBarunGothic-LICENSE.txt" => static_files::nanum_barun_gothic::LICENSE, "LICENSE-MIT.txt" => static_files::LICENSE_MIT, "LICENSE-APACHE.txt" => static_files::LICENSE_APACHE, diff --git a/src/librustdoc/html/static/COPYRIGHT.txt b/src/librustdoc/html/static/COPYRIGHT.txt index c2629a83f70..34e48134cc3 100644 --- a/src/librustdoc/html/static/COPYRIGHT.txt +++ b/src/librustdoc/html/static/COPYRIGHT.txt @@ -2,8 +2,7 @@ These documentation pages include resources by third parties. This copyright file applies only to those resources. The following third party resources are included, and carry their own copyright notices and license terms: -* Fira Sans (FiraSans-Regular.woff2, FiraSans-Medium.woff2, - FiraSans-Regular.woff, FiraSans-Medium.woff): +* Fira Sans (FiraSans-Regular.woff2, FiraSans-Medium.woff2): Copyright (c) 2014, Mozilla Foundation https://mozilla.org/ with Reserved Font Name Fira Sans. @@ -25,9 +24,7 @@ included, and carry their own copyright notices and license terms: Licensed under the MIT license (see LICENSE-MIT.txt). * Source Code Pro (SourceCodePro-Regular.ttf.woff2, - SourceCodePro-Semibold.ttf.woff2, SourceCodePro-It.ttf.woff2, - SourceCodePro-Regular.ttf.woff, SourceCodePro-Semibold.ttf.woff, - SourceCodePro-It.ttf.woff): + SourceCodePro-Semibold.ttf.woff2, SourceCodePro-It.ttf.woff2): Copyright 2010, 2012 Adobe Systems Incorporated (http://www.adobe.com/), with Reserved Font Name 'Source'. All Rights Reserved. Source is a trademark @@ -37,8 +34,7 @@ included, and carry their own copyright notices and license terms: See SourceCodePro-LICENSE.txt. * Source Serif 4 (SourceSerif4-Regular.ttf.woff2, SourceSerif4-Bold.ttf.woff2, - SourceSerif4-It.ttf.woff2, SourceSerif4-Regular.ttf.woff, - SourceSerif4-Bold.ttf.woff, SourceSerif4-It.ttf.woff): + SourceSerif4-It.ttf.woff2): Copyright 2014-2021 Adobe (http://www.adobe.com/), with Reserved Font Name 'Source'. All Rights Reserved. Source is a trademark of Adobe in the United diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css index 48cb0a46ad6..81c12be8e83 100644 --- a/src/librustdoc/html/static/css/rustdoc.css +++ b/src/librustdoc/html/static/css/rustdoc.css @@ -4,8 +4,7 @@ font-style: normal; font-weight: 400; src: local('Fira Sans'), - url("FiraSans-Regular.woff2") format("woff2"), - url("FiraSans-Regular.woff") format('woff'); + url("FiraSans-Regular.woff2") format("woff2"); font-display: swap; } @font-face { @@ -13,8 +12,7 @@ font-style: normal; font-weight: 500; src: local('Fira Sans Medium'), - url("FiraSans-Medium.woff2") format("woff2"), - url("FiraSans-Medium.woff") format('woff'); + url("FiraSans-Medium.woff2") format("woff2"); font-display: swap; } @@ -24,8 +22,7 @@ font-style: normal; font-weight: 400; src: local('Source Serif 4'), - url("SourceSerif4-Regular.ttf.woff2") format("woff2"), - url("SourceSerif4-Regular.ttf.woff") format("woff"); + url("SourceSerif4-Regular.ttf.woff2") format("woff2"); font-display: swap; } @font-face { @@ -33,8 +30,7 @@ font-style: italic; font-weight: 400; src: local('Source Serif 4 Italic'), - url("SourceSerif4-It.ttf.woff2") format("woff2"), - url("SourceSerif4-It.ttf.woff") format("woff"); + url("SourceSerif4-It.ttf.woff2") format("woff2"); font-display: swap; } @font-face { @@ -42,8 +38,7 @@ font-style: normal; font-weight: 700; src: local('Source Serif 4 Bold'), - url("SourceSerif4-Bold.ttf.woff2") format("woff2"), - url("SourceSerif4-Bold.ttf.woff") format("woff"); + url("SourceSerif4-Bold.ttf.woff2") format("woff2"); font-display: swap; } @@ -54,32 +49,28 @@ font-weight: 400; /* Avoid using locally installed font because bad versions are in circulation: * see https://github.com/rust-lang/rust/issues/24355 */ - src: url("SourceCodePro-Regular.ttf.woff2") format("woff2"), - url("SourceCodePro-Regular.ttf.woff") format("woff"); + src: url("SourceCodePro-Regular.ttf.woff2") format("woff2"); font-display: swap; } @font-face { font-family: 'Source Code Pro'; font-style: italic; font-weight: 400; - src: url("SourceCodePro-It.ttf.woff2") format("woff2"), - url("SourceCodePro-It.ttf.woff") format("woff"); + src: url("SourceCodePro-It.ttf.woff2") format("woff2"); font-display: swap; } @font-face { font-family: 'Source Code Pro'; font-style: normal; font-weight: 600; - src: url("SourceCodePro-Semibold.ttf.woff2") format("woff2"), - url("SourceCodePro-Semibold.ttf.woff") format("woff"); + src: url("SourceCodePro-Semibold.ttf.woff2") format("woff2"); font-display: swap; } /* Avoid using legacy CJK serif fonts in Windows like Batang. */ @font-face { font-family: 'NanumBarunGothic'; - src: url("NanumBarunGothic.ttf.woff2") format("woff2"), - url("NanumBarunGothic.ttf.woff") format("woff"); + src: url("NanumBarunGothic.ttf.woff2") format("woff2"); font-display: swap; unicode-range: U+AC00-D7AF, U+1100-11FF, U+3130-318F, U+A960-A97F, U+D7B0-D7FF; } diff --git a/src/librustdoc/html/static/fonts/FiraSans-Medium.woff b/src/librustdoc/html/static/fonts/FiraSans-Medium.woff deleted file mode 100644 index 7d742c5fb7d..00000000000 --- a/src/librustdoc/html/static/fonts/FiraSans-Medium.woff +++ /dev/null Binary files differdiff --git a/src/librustdoc/html/static/fonts/FiraSans-Regular.woff b/src/librustdoc/html/static/fonts/FiraSans-Regular.woff deleted file mode 100644 index d8e0363f4e1..00000000000 --- a/src/librustdoc/html/static/fonts/FiraSans-Regular.woff +++ /dev/null Binary files differdiff --git a/src/librustdoc/html/static/fonts/NanumBarunGothic.ttf.woff b/src/librustdoc/html/static/fonts/NanumBarunGothic.ttf.woff deleted file mode 100644 index fb063e8fb7d..00000000000 --- a/src/librustdoc/html/static/fonts/NanumBarunGothic.ttf.woff +++ /dev/null Binary files differdiff --git a/src/librustdoc/html/static/fonts/SourceCodePro-It.ttf.woff b/src/librustdoc/html/static/fonts/SourceCodePro-It.ttf.woff deleted file mode 100644 index 8d68f2febdd..00000000000 --- a/src/librustdoc/html/static/fonts/SourceCodePro-It.ttf.woff +++ /dev/null Binary files differdiff --git a/src/librustdoc/html/static/fonts/SourceCodePro-Regular.ttf.woff b/src/librustdoc/html/static/fonts/SourceCodePro-Regular.ttf.woff deleted file mode 100644 index 7be076e1fca..00000000000 --- a/src/librustdoc/html/static/fonts/SourceCodePro-Regular.ttf.woff +++ /dev/null Binary files differdiff --git a/src/librustdoc/html/static/fonts/SourceCodePro-Semibold.ttf.woff b/src/librustdoc/html/static/fonts/SourceCodePro-Semibold.ttf.woff deleted file mode 100644 index 61bc67b8025..00000000000 --- a/src/librustdoc/html/static/fonts/SourceCodePro-Semibold.ttf.woff +++ /dev/null Binary files differdiff --git a/src/librustdoc/html/static/fonts/SourceSerif4-Bold.ttf.woff b/src/librustdoc/html/static/fonts/SourceSerif4-Bold.ttf.woff deleted file mode 100644 index 8ad41888e6e..00000000000 --- a/src/librustdoc/html/static/fonts/SourceSerif4-Bold.ttf.woff +++ /dev/null Binary files differdiff --git a/src/librustdoc/html/static/fonts/SourceSerif4-It.ttf.woff b/src/librustdoc/html/static/fonts/SourceSerif4-It.ttf.woff deleted file mode 100644 index 2a34b5c42a8..00000000000 --- a/src/librustdoc/html/static/fonts/SourceSerif4-It.ttf.woff +++ /dev/null Binary files differdiff --git a/src/librustdoc/html/static/fonts/SourceSerif4-Regular.ttf.woff b/src/librustdoc/html/static/fonts/SourceSerif4-Regular.ttf.woff deleted file mode 100644 index 45a5521ab0c..00000000000 --- a/src/librustdoc/html/static/fonts/SourceSerif4-Regular.ttf.woff +++ /dev/null Binary files differdiff --git a/src/librustdoc/html/static/js/externs.js b/src/librustdoc/html/static/js/externs.js index 629f90728d2..de881dbd081 100644 --- a/src/librustdoc/html/static/js/externs.js +++ b/src/librustdoc/html/static/js/externs.js @@ -1,20 +1,47 @@ // This file contains type definitions that are processed by the Closure Compiler but are // not put into the JavaScript we include as part of the documentation. It is used for // type checking. See README.md in this directory for more info. +/* eslint-env es6 */ +/* eslint no-var: "error" */ +/* eslint prefer-const: "error" */ /* eslint-disable */ -var searchState; +let searchState; function initSearch(searchIndex){} /** * @typedef {{ - * raw: string, - * query: string, - * type: string, - * id: string, + * name: string, + * fullPath: Array<string>, + * pathWithoutLast: Array<string>, + * pathLast: string, + * generics: Array<QueryElement>, * }} */ -var ParsedQuery; +let QueryElement; + +/** + * @typedef {{ + * pos: number, + * totalElems: number, + * typeFilter: (null|string), + * userQuery: string, + * }} + */ +let ParserState; + +/** + * @typedef {{ + * original: string, + * userQuery: string, + * typeFilter: number, + * elems: Array<QueryElement>, + * args: Array<QueryElement>, + * returned: Array<QueryElement>, + * foundElems: number, + * }} + */ +let ParsedQuery; /** * @typedef {{ @@ -29,4 +56,31 @@ var ParsedQuery; * type: (Array<?>|null) * }} */ -var Row; +let Row; + +/** + * @typedef {{ + * in_args: Array<Object>, + * returned: Array<Object>, + * others: Array<Object>, + * query: ParsedQuery, + * }} + */ +let ResultsTable; + +/** + * @typedef {{ + * desc: string, + * displayPath: string, + * fullPath: string, + * href: string, + * id: number, + * lev: number, + * name: string, + * normalizedName: string, + * parent: (Object|undefined), + * path: string, + * ty: number, + * }} + */ +let Results; diff --git a/src/librustdoc/html/static/js/main.js b/src/librustdoc/html/static/js/main.js index 90592335d5d..9e5de9a843a 100644 --- a/src/librustdoc/html/static/js/main.js +++ b/src/librustdoc/html/static/js/main.js @@ -1,3 +1,6 @@ +/* eslint-env es6 */ +/* eslint no-var: "error" */ +/* eslint prefer-const: "error" */ // Local js definitions: /* global addClass, getSettingValue, hasClass, searchState */ /* global onEach, onEachLazy, removeClass */ @@ -11,7 +14,7 @@ if (!String.prototype.startsWith) { } if (!String.prototype.endsWith) { String.prototype.endsWith = function(suffix, length) { - var l = length || this.length; + const l = length || this.length; return this.indexOf(suffix, l - suffix.length) !== -1; }; } @@ -40,7 +43,7 @@ if (!DOMTokenList.prototype.remove) { // Get a value from the rustdoc-vars div, which is used to convey data from // Rust to the JS. If there is no such element, return null. function getVar(name) { - var el = document.getElementById("rustdoc-vars"); + const el = document.getElementById("rustdoc-vars"); if (el) { return el.attributes["data-" + name].value; } else { @@ -59,7 +62,7 @@ function resourcePath(basename, extension) { window.currentCrate = getVar("current-crate"); window.searchJS = resourcePath("search", ".js"); window.searchIndexJS = resourcePath("search-index", ".js"); - var sidebarVars = document.getElementById("sidebar-vars"); + const sidebarVars = document.getElementById("sidebar-vars"); if (sidebarVars) { window.sidebarCurrent = { name: sidebarVars.attributes["data-name"].value, @@ -68,8 +71,8 @@ function resourcePath(basename, extension) { }; // FIXME: It would be nicer to generate this text content directly in HTML, // but with the current code it's hard to get the right information in the right place. - var mobileLocationTitle = document.querySelector(".mobile-topbar h2.location"); - var locationTitle = document.querySelector(".sidebar h2.location"); + const mobileLocationTitle = document.querySelector(".mobile-topbar h2.location"); + const locationTitle = document.querySelector(".sidebar h2.location"); if (mobileLocationTitle && locationTitle) { mobileLocationTitle.innerHTML = locationTitle.innerHTML; } @@ -91,16 +94,16 @@ function getVirtualKey(ev) { return ev.key; } - var c = ev.charCode || ev.keyCode; + const c = ev.charCode || ev.keyCode; if (c == 27) { return "Escape"; } return String.fromCharCode(c); } -var THEME_PICKER_ELEMENT_ID = "theme-picker"; -var THEMES_ELEMENT_ID = "theme-choices"; -var MAIN_ID = "main-content"; +const THEME_PICKER_ELEMENT_ID = "theme-picker"; +const THEMES_ELEMENT_ID = "theme-choices"; +const MAIN_ID = "main-content"; function getThemesElement() { return document.getElementById(THEMES_ELEMENT_ID); @@ -116,8 +119,8 @@ function getNakedUrl() { } function showThemeButtonState() { - var themePicker = getThemePickerElement(); - var themeChoices = getThemesElement(); + const themePicker = getThemePickerElement(); + const themeChoices = getThemesElement(); themeChoices.style.display = "block"; themePicker.style.borderBottomRightRadius = "0"; @@ -125,8 +128,8 @@ function showThemeButtonState() { } function hideThemeButtonState() { - var themePicker = getThemePickerElement(); - var themeChoices = getThemesElement(); + const themePicker = getThemePickerElement(); + const themeChoices = getThemesElement(); themeChoices.style.display = "none"; themePicker.style.borderBottomRightRadius = "3px"; @@ -138,9 +141,9 @@ function hideThemeButtonState() { if (!document.location.href.startsWith("file:///")) { return; } - var themeChoices = getThemesElement(); - var themePicker = getThemePickerElement(); - var availableThemes = getVar("themes").split(","); + const themeChoices = getThemesElement(); + const themePicker = getThemePickerElement(); + const availableThemes = getVar("themes").split(","); removeClass(themeChoices.parentElement, "hidden"); @@ -153,8 +156,8 @@ function hideThemeButtonState() { } function handleThemeButtonsBlur(e) { - var active = document.activeElement; - var related = e.relatedTarget; + const active = document.activeElement; + const related = e.relatedTarget; if (active.id !== THEME_PICKER_ELEMENT_ID && (!active.parentNode || active.parentNode.id !== THEMES_ELEMENT_ID) && @@ -168,7 +171,7 @@ function hideThemeButtonState() { themePicker.onclick = switchThemeButtonState; themePicker.onblur = handleThemeButtonsBlur; availableThemes.forEach(function(item) { - var but = document.createElement("button"); + const but = document.createElement("button"); but.textContent = item; but.onclick = function() { switchTheme(window.currentTheme, window.mainTheme, item, true); @@ -236,10 +239,10 @@ function hideThemeButtonState() { } }, getQueryStringParams: function() { - var params = {}; + const params = {}; window.location.search.substring(1).split("&"). map(function(s) { - var pair = s.split("="); + const pair = s.split("="); params[decodeURIComponent(pair[0])] = typeof pair[1] === "undefined" ? null : decodeURIComponent(pair[1]); }); @@ -249,17 +252,17 @@ function hideThemeButtonState() { return window.history && typeof window.history.pushState === "function"; }, setup: function() { - var search_input = searchState.input; + const search_input = searchState.input; if (!searchState.input) { return; } function loadScript(url) { - var script = document.createElement('script'); + const script = document.createElement('script'); script.src = url; document.head.append(script); } - var searchLoaded = false; + let searchLoaded = false; function loadSearch() { if (!searchLoaded) { searchLoaded = true; @@ -278,9 +281,9 @@ function hideThemeButtonState() { loadSearch(); } - var params = searchState.getQueryStringParams(); + const params = searchState.getQueryStringParams(); if (params.search !== undefined) { - var search = searchState.outputElement(); + const search = searchState.outputElement(); search.innerHTML = "<h3 class=\"search-loading\">" + searchState.loadingText + "</h3>"; searchState.showResults(search); @@ -291,7 +294,7 @@ function hideThemeButtonState() { function getPageId() { if (window.location.hash) { - var tmp = window.location.hash.replace(/^#/, ""); + const tmp = window.location.hash.replace(/^#/, ""); if (tmp.length > 0) { return tmp; } @@ -299,18 +302,18 @@ function hideThemeButtonState() { return null; } - var toggleAllDocsId = "toggle-all-docs"; - var main = document.getElementById(MAIN_ID); - var savedHash = ""; + const toggleAllDocsId = "toggle-all-docs"; + const main = document.getElementById(MAIN_ID); + let savedHash = ""; function handleHashes(ev) { - var elem; - var search = searchState.outputElement(); + let elem; + const search = searchState.outputElement(); if (ev !== null && search && !hasClass(search, "hidden") && ev.newURL) { // This block occurs when clicking on an element in the navbar while // in a search. searchState.hideResults(search); - var hash = ev.newURL.slice(ev.newURL.indexOf("#") + 1); + const hash = ev.newURL.slice(ev.newURL.indexOf("#") + 1); if (searchState.browserSupportsHistoryApi()) { // `window.location.search`` contains all the query parameters, not just `search`. history.replaceState(null, "", @@ -333,7 +336,7 @@ function hideThemeButtonState() { function onHashChange(ev) { // If we're in mobile mode, we should hide the sidebar in any case. - var sidebar = document.getElementsByClassName("sidebar")[0]; + const sidebar = document.getElementsByClassName("sidebar")[0]; removeClass(sidebar, "shown"); handleHashes(ev); } @@ -386,8 +389,8 @@ function hideThemeButtonState() { } function handleEscape(ev) { - var help = getHelpElement(false); - var search = searchState.outputElement(); + const help = getHelpElement(false); + const search = searchState.outputElement(); if (help && !hasClass(help, "hidden")) { displayHelp(false, ev, help); } else if (search && !hasClass(search, "hidden")) { @@ -399,13 +402,15 @@ function hideThemeButtonState() { hideThemeButtonState(); } - var disableShortcuts = getSettingValue("disable-shortcuts") === "true"; + const disableShortcuts = getSettingValue("disable-shortcuts") === "true"; function handleShortcut(ev) { // Don't interfere with browser shortcuts if (ev.ctrlKey || ev.altKey || ev.metaKey || disableShortcuts) { return; } + let themePicker; + if (document.activeElement.tagName === "INPUT") { switch (getVirtualKey(ev)) { case "Escape": @@ -439,7 +444,7 @@ function hideThemeButtonState() { case "T": displayHelp(false, ev); ev.preventDefault(); - var themePicker = getThemePickerElement(); + themePicker = getThemePickerElement(); themePicker.click(); themePicker.focus(); break; @@ -453,8 +458,8 @@ function hideThemeButtonState() { } function handleThemeKeyDown(ev) { - var active = document.activeElement; - var themes = getThemesElement(); + const active = document.activeElement; + const themes = getThemesElement(); switch (getVirtualKey(ev)) { case "ArrowUp": ev.preventDefault(); @@ -499,36 +504,11 @@ function hideThemeButtonState() { document.addEventListener("keypress", handleShortcut); document.addEventListener("keydown", handleShortcut); - (function() { - var x = document.getElementsByClassName("version-selector"); - if (x.length > 0) { - x[0].onchange = function() { - var i, match, - url = document.location.href, - stripped = "", - len = window.rootPath.match(/\.\.\//g).length + 1; - - for (i = 0; i < len; ++i) { - match = url.match(/\/[^/]*$/); - if (i < len - 1) { - stripped = match[0] + stripped; - } - url = url.substring(0, url.length - match[0].length); - } - - var selectedVersion = document.getElementsByClassName("version-selector")[0].value; - url += "/" + selectedVersion + stripped; - - document.location.href = url; - }; - } - }()); - // delayed sidebar rendering. window.initSidebarItems = function(items) { - var sidebar = document.getElementsByClassName("sidebar-elems")[0]; - var others; - var current = window.sidebarCurrent; + const sidebar = document.getElementsByClassName("sidebar-elems")[0]; + let others; + const current = window.sidebarCurrent; function addSidebarCrates(crates) { if (!hasClass(document.body, "crate")) { @@ -536,23 +516,23 @@ function hideThemeButtonState() { return; } // Draw a convenient sidebar of known crates if we have a listing - var div = document.createElement("div"); + const div = document.createElement("div"); div.className = "block crate"; div.innerHTML = "<h3>Crates</h3>"; - var ul = document.createElement("ul"); + const ul = document.createElement("ul"); div.appendChild(ul); - for (var i = 0; i < crates.length; ++i) { - var klass = "crate"; - if (window.rootPath !== "./" && crates[i] === window.currentCrate) { + for (const crate of crates) { + let klass = "crate"; + if (window.rootPath !== "./" && crate === window.currentCrate) { klass += " current"; } - var link = document.createElement("a"); - link.href = window.rootPath + crates[i] + "/index.html"; + const link = document.createElement("a"); + link.href = window.rootPath + crate + "/index.html"; link.className = klass; - link.textContent = crates[i]; + link.textContent = crate; - var li = document.createElement("li"); + const li = document.createElement("li"); li.appendChild(link); ul.appendChild(li); } @@ -568,39 +548,38 @@ function hideThemeButtonState() { * "Modules", or "Macros". */ function block(shortty, id, longty) { - var filtered = items[shortty]; + const filtered = items[shortty]; if (!filtered) { return; } - var div = document.createElement("div"); + const div = document.createElement("div"); div.className = "block " + shortty; - var h3 = document.createElement("h3"); + const h3 = document.createElement("h3"); h3.innerHTML = `<a href="index.html#${id}">${longty}</a>`; div.appendChild(h3); - var ul = document.createElement("ul"); + const ul = document.createElement("ul"); - for (var i = 0, len = filtered.length; i < len; ++i) { - var item = filtered[i]; - var name = item[0]; - var desc = item[1]; // can be null + for (const item of filtered) { + const name = item[0]; + const desc = item[1]; // can be null - var klass = shortty; + let klass = shortty; if (name === current.name && shortty === current.ty) { klass += " current"; } - var path; + let path; if (shortty === "mod") { path = name + "/index.html"; } else { path = shortty + "." + name + ".html"; } - var link = document.createElement("a"); + const link = document.createElement("a"); link.href = current.relpath + path; link.title = desc; link.className = klass; link.textContent = name; - var li = document.createElement("li"); + const li = document.createElement("li"); li.appendChild(link); ul.appendChild(li); } @@ -613,7 +592,7 @@ function hideThemeButtonState() { others.className = "others"; sidebar.appendChild(others); - var isModule = hasClass(document.body, "mod"); + const isModule = hasClass(document.body, "mod"); if (!isModule) { block("primitive", "primitives", "Primitive Types"); block("mod", "modules", "Modules"); @@ -638,8 +617,9 @@ function hideThemeButtonState() { }; window.register_implementors = function(imp) { - var implementors = document.getElementById("implementors-list"); - var synthetic_implementors = document.getElementById("synthetic-implementors-list"); + const implementors = document.getElementById("implementors-list"); + const synthetic_implementors = document.getElementById("synthetic-implementors-list"); + const inlined_types = new Set(); if (synthetic_implementors) { // This `inlined_types` variable is used to avoid having the same implementation @@ -647,9 +627,8 @@ function hideThemeButtonState() { // // By the way, this is only used by and useful for traits implemented automatically // (like "Send" and "Sync"). - var inlined_types = new Set(); onEachLazy(synthetic_implementors.getElementsByClassName("impl"), function(el) { - var aliases = el.getAttribute("data-aliases"); + const aliases = el.getAttribute("data-aliases"); if (!aliases) { return; } @@ -659,48 +638,48 @@ function hideThemeButtonState() { }); } - var currentNbImpls = implementors.getElementsByClassName("impl").length; - var traitName = document.querySelector("h1.fqn > .in-band > .trait").textContent; - var baseIdName = "impl-" + traitName + "-"; - var libs = Object.getOwnPropertyNames(imp); - for (var i = 0, llength = libs.length; i < llength; ++i) { - if (libs[i] === window.currentCrate) { continue; } - var structs = imp[libs[i]]; + let currentNbImpls = implementors.getElementsByClassName("impl").length; + const traitName = document.querySelector("h1.fqn > .in-band > .trait").textContent; + const baseIdName = "impl-" + traitName + "-"; + const libs = Object.getOwnPropertyNames(imp); + for (const lib of libs) { + if (lib === window.currentCrate) { + continue; + } + const structs = imp[lib]; struct_loop: - for (var j = 0, slength = structs.length; j < slength; ++j) { - var struct = structs[j]; - - var list = struct.synthetic ? synthetic_implementors : implementors; + for (const struct of structs) { + const list = struct.synthetic ? synthetic_implementors : implementors; if (struct.synthetic) { - for (var k = 0, stlength = struct.types.length; k < stlength; k++) { - if (inlined_types.has(struct.types[k])) { + for (const struct_type of struct.types) { + if (inlined_types.has(struct_type)) { continue struct_loop; } - inlined_types.add(struct.types[k]); + inlined_types.add(struct_type); } } - var code = document.createElement("h3"); + const code = document.createElement("h3"); code.innerHTML = struct.text; addClass(code, "code-header"); addClass(code, "in-band"); onEachLazy(code.getElementsByTagName("a"), function(elem) { - var href = elem.getAttribute("href"); + const href = elem.getAttribute("href"); if (href && href.indexOf("http") !== 0) { elem.setAttribute("href", window.rootPath + href); } }); - var currentId = baseIdName + currentNbImpls; - var anchor = document.createElement("a"); + const currentId = baseIdName + currentNbImpls; + const anchor = document.createElement("a"); anchor.href = "#" + currentId; addClass(anchor, "anchor"); - var display = document.createElement("div"); + const display = document.createElement("div"); display.id = currentId; addClass(display, "impl"); display.appendChild(anchor); @@ -725,11 +704,11 @@ function hideThemeButtonState() { } function toggleAllDocs() { - var innerToggle = document.getElementById(toggleAllDocsId); + const innerToggle = document.getElementById(toggleAllDocsId); if (!innerToggle) { return; } - var sectionIsCollapsed = false; + let sectionIsCollapsed = false; if (hasClass(innerToggle, "will-expand")) { removeClass(innerToggle, "will-expand"); onEachLazy(document.getElementsByClassName("rustdoc-toggle"), function(e) { @@ -759,17 +738,17 @@ function hideThemeButtonState() { } (function() { - var toggles = document.getElementById(toggleAllDocsId); + const toggles = document.getElementById(toggleAllDocsId); if (toggles) { toggles.onclick = toggleAllDocs; } - var hideMethodDocs = getSettingValue("auto-hide-method-docs") === "true"; - var hideImplementations = getSettingValue("auto-hide-trait-implementations") === "true"; - var hideLargeItemContents = getSettingValue("auto-hide-large-items") !== "false"; + const hideMethodDocs = getSettingValue("auto-hide-method-docs") === "true"; + const hideImplementations = getSettingValue("auto-hide-trait-implementations") === "true"; + const hideLargeItemContents = getSettingValue("auto-hide-large-items") !== "false"; function setImplementorsTogglesOpen(id, open) { - var list = document.getElementById(id); + const list = document.getElementById(id); if (list !== null) { onEachLazy(list.getElementsByClassName("implementors-toggle"), function(e) { e.open = open; @@ -792,7 +771,7 @@ function hideThemeButtonState() { }); - var pageId = getPageId(); + const pageId = getPageId(); if (pageId !== null) { expandSection(pageId); } @@ -800,15 +779,15 @@ function hideThemeButtonState() { (function() { // To avoid checking on "rustdoc-line-numbers" value on every loop... - var lineNumbersFunc = function() {}; + let lineNumbersFunc = function() {}; if (getSettingValue("line-numbers") === "true") { lineNumbersFunc = function(x) { - var count = x.textContent.split("\n").length; - var elems = []; - for (var i = 0; i < count; ++i) { + const count = x.textContent.split("\n").length; + const elems = []; + for (let i = 0; i < count; ++i) { elems.push(i + 1); } - var node = document.createElement("pre"); + const node = document.createElement("pre"); addClass(node, "line-number"); node.innerHTML = elems.join("\n"); x.parentNode.insertBefore(node, x); @@ -835,12 +814,12 @@ function hideThemeButtonState() { }()); function hideSidebar() { - var sidebar = document.getElementsByClassName("sidebar")[0]; + const sidebar = document.getElementsByClassName("sidebar")[0]; removeClass(sidebar, "shown"); } function handleClick(id, f) { - var elem = document.getElementById(id); + const elem = document.getElementById(id); if (elem) { elem.addEventListener("click", f); } @@ -879,10 +858,10 @@ function hideThemeButtonState() { }; }); - var sidebar_menu_toggle = document.getElementsByClassName("sidebar-menu-toggle")[0]; + const sidebar_menu_toggle = document.getElementsByClassName("sidebar-menu-toggle")[0]; if (sidebar_menu_toggle) { sidebar_menu_toggle.addEventListener("click", function() { - var sidebar = document.getElementsByClassName("sidebar")[0]; + const sidebar = document.getElementsByClassName("sidebar")[0]; if (!hasClass(sidebar, "shown")) { addClass(sidebar, "shown"); } else { @@ -891,8 +870,8 @@ function hideThemeButtonState() { }); } - var buildHelperPopup = function() { - var popup = document.createElement("aside"); + let buildHelperPopup = function() { + const popup = document.createElement("aside"); addClass(popup, "hidden"); popup.id = "help"; @@ -903,13 +882,13 @@ function hideThemeButtonState() { } }); - var book_info = document.createElement("span"); + const book_info = document.createElement("span"); book_info.className = "top"; book_info.innerHTML = "You can find more information in \ <a href=\"https://doc.rust-lang.org/rustdoc/\">the rustdoc book</a>."; - var container = document.createElement("div"); - var shortcuts = [ + const container = document.createElement("div"); + const shortcuts = [ ["?", "Show this help dialog"], ["S", "Focus the search field"], ["T", "Focus the theme picker menu"], @@ -927,11 +906,11 @@ function hideThemeButtonState() { }) .join("") + "</dt><dd>" + x[1] + "</dd>"; }).join(""); - var div_shortcuts = document.createElement("div"); + const div_shortcuts = document.createElement("div"); addClass(div_shortcuts, "shortcuts"); div_shortcuts.innerHTML = "<h2>Keyboard Shortcuts</h2><dl>" + shortcuts + "</dl></div>"; - var infos = [ + const infos = [ "Prefix searches with a type followed by a colon (e.g., <code>fn:</code>) to \ restrict the search to a given item kind.", "Accepted kinds are: <code>fn</code>, <code>mod</code>, <code>struct</code>, \ @@ -947,7 +926,7 @@ function hideThemeButtonState() { ].map(function(x) { return "<p>" + x + "</p>"; }).join(""); - var div_infos = document.createElement("div"); + const div_infos = document.createElement("div"); addClass(div_infos, "infos"); div_infos.innerHTML = "<h2>Search Tricks</h2>" + infos; @@ -955,9 +934,9 @@ function hideThemeButtonState() { container.appendChild(div_shortcuts); container.appendChild(div_infos); - var rustdoc_version = document.createElement("span"); + const rustdoc_version = document.createElement("span"); rustdoc_version.className = "bottom"; - var rustdoc_version_code = document.createElement("code"); + const rustdoc_version_code = document.createElement("code"); rustdoc_version_code.innerText = "rustdoc " + getVar("rustdoc-version"); rustdoc_version.appendChild(rustdoc_version_code); @@ -975,11 +954,11 @@ function hideThemeButtonState() { }()); (function () { - var reset_button_timeout = null; + let reset_button_timeout = null; window.copy_path = function(but) { - var parent = but.parentElement; - var path = []; + const parent = but.parentElement; + const path = []; onEach(parent.childNodes, function(child) { if (child.tagName === 'A') { @@ -987,7 +966,7 @@ function hideThemeButtonState() { } }); - var el = document.createElement('textarea'); + const el = document.createElement('textarea'); el.value = path.join('::'); el.setAttribute('readonly', ''); // To not make it appear on the screen. @@ -1002,7 +981,7 @@ function hideThemeButtonState() { // There is always one children, but multiple childNodes. but.children[0].style.display = 'none'; - var tmp; + let tmp; if (but.childNodes.length < 2) { tmp = document.createTextNode('✓'); but.appendChild(tmp); diff --git a/src/librustdoc/html/static/js/scrape-examples.js b/src/librustdoc/html/static/js/scrape-examples.js index a28fb461729..865ed7190f3 100644 --- a/src/librustdoc/html/static/js/scrape-examples.js +++ b/src/librustdoc/html/static/js/scrape-examples.js @@ -1,4 +1,7 @@ -/* global addClass, hasClass, removeClass, onEach */ +/* eslint-env es6 */ +/* eslint no-var: "error" */ +/* eslint prefer-const: "error" */ +/* global addClass, hasClass, removeClass, onEachLazy */ (function () { // Number of lines shown when code viewer is not expanded @@ -6,19 +9,19 @@ // Scroll code block to the given code location function scrollToLoc(elt, loc) { - var lines = elt.querySelector('.line-numbers'); - var scrollOffset; + const lines = elt.querySelector('.line-numbers'); + let scrollOffset; // If the block is greater than the size of the viewer, // then scroll to the top of the block. Otherwise scroll // to the middle of the block. if (loc[1] - loc[0] > MAX_LINES) { - var line = Math.max(0, loc[0] - 1); + const line = Math.max(0, loc[0] - 1); scrollOffset = lines.children[line].offsetTop; } else { - var wrapper = elt.querySelector(".code-wrapper"); - var halfHeight = wrapper.offsetHeight / 2; - var offsetMid = (lines.children[loc[0]].offsetTop + const wrapper = elt.querySelector(".code-wrapper"); + const halfHeight = wrapper.offsetHeight / 2; + const offsetMid = (lines.children[loc[0]].offsetTop + lines.children[loc[1]].offsetTop) / 2; scrollOffset = offsetMid - halfHeight; } @@ -28,21 +31,21 @@ } function updateScrapedExample(example) { - var locs = JSON.parse(example.attributes.getNamedItem("data-locs").textContent); - var locIndex = 0; - var highlights = example.querySelectorAll('.highlight'); - var link = example.querySelector('.scraped-example-title a'); + const locs = JSON.parse(example.attributes.getNamedItem("data-locs").textContent); + let locIndex = 0; + const highlights = Array.prototype.slice.call(example.querySelectorAll('.highlight')); + const link = example.querySelector('.scraped-example-title a'); if (locs.length > 1) { // Toggle through list of examples in a given file - var onChangeLoc = function(changeIndex) { + const onChangeLoc = function(changeIndex) { removeClass(highlights[locIndex], 'focus'); changeIndex(); scrollToLoc(example, locs[locIndex][0]); addClass(highlights[locIndex], 'focus'); - var url = locs[locIndex][1]; - var title = locs[locIndex][2]; + const url = locs[locIndex][1]; + const title = locs[locIndex][2]; link.href = url; link.innerHTML = title; @@ -63,7 +66,7 @@ }); } - var expandButton = example.querySelector('.expand'); + const expandButton = example.querySelector('.expand'); if (expandButton) { expandButton.addEventListener('click', function () { if (hasClass(example, "expanded")) { @@ -79,24 +82,24 @@ scrollToLoc(example, locs[0][0]); } - var firstExamples = document.querySelectorAll('.scraped-example-list > .scraped-example'); - onEach(firstExamples, updateScrapedExample); - onEach(document.querySelectorAll('.more-examples-toggle'), function(toggle) { + const firstExamples = document.querySelectorAll('.scraped-example-list > .scraped-example'); + onEachLazy(firstExamples, updateScrapedExample); + onEachLazy(document.querySelectorAll('.more-examples-toggle'), function(toggle) { // Allow users to click the left border of the <details> section to close it, // since the section can be large and finding the [+] button is annoying. - toggle.querySelectorAll('.toggle-line, .hide-more').forEach(button => { + onEachLazy(toggle.querySelectorAll('.toggle-line, .hide-more'), button => { button.addEventListener('click', function() { toggle.open = false; }); }); - var moreExamples = toggle.querySelectorAll('.scraped-example'); + const moreExamples = toggle.querySelectorAll('.scraped-example'); toggle.querySelector('summary').addEventListener('click', function() { // Wrapping in setTimeout ensures the update happens after the elements are actually // visible. This is necessary since updateScrapedExample calls scrollToLoc which // depends on offsetHeight, a property that requires an element to be visible to // compute correctly. - setTimeout(function() { onEach(moreExamples, updateScrapedExample); }); + setTimeout(function() { onEachLazy(moreExamples, updateScrapedExample); }); }, {once: true}); }); })(); diff --git a/src/librustdoc/html/static/js/search.js b/src/librustdoc/html/static/js/search.js index ab52304491a..a6f7dd74af6 100644 --- a/src/librustdoc/html/static/js/search.js +++ b/src/librustdoc/html/static/js/search.js @@ -1,10 +1,13 @@ +/* eslint-env es6 */ +/* eslint no-var: "error" */ +/* eslint prefer-const: "error" */ /* global addClass, getNakedUrl, getSettingValue, hasOwnPropertyRustdoc, initSearch, onEach */ /* global onEachLazy, removeClass, searchState, hasClass */ (function() { // This mapping table should match the discriminants of // `rustdoc::formats::item_type::ItemType` type in Rust. -var itemTypes = [ +const itemTypes = [ "mod", "externcrate", "import", @@ -34,15 +37,15 @@ var itemTypes = [ ]; // used for special search precedence -var TY_PRIMITIVE = itemTypes.indexOf("primitive"); -var TY_KEYWORD = itemTypes.indexOf("keyword"); +const TY_PRIMITIVE = itemTypes.indexOf("primitive"); +const TY_KEYWORD = itemTypes.indexOf("keyword"); // In the search display, allows to switch between tabs. function printTab(nb) { if (nb === 0 || nb === 1 || nb === 2) { searchState.currentTab = nb; } - var nb_copy = nb; + let nb_copy = nb; onEachLazy(document.getElementById("titles").childNodes, function(elem) { if (nb_copy === 0) { addClass(elem, "selected"); @@ -61,15 +64,6 @@ function printTab(nb) { }); } -function removeEmptyStringsFromArray(x) { - for (var i = 0, len = x.length; i < len; ++i) { - if (x[i] === "") { - x.splice(i, 1); - i -= 1; - } - } -} - /** * A function to compute the Levenshtein distance between two strings * Licensed under the Creative Commons Attribution-ShareAlike 3.0 Unported @@ -77,14 +71,15 @@ function removeEmptyStringsFromArray(x) { * This code is an unmodified version of the code written by Marco de Wit * and was found at https://stackoverflow.com/a/18514751/745719 */ -var levenshtein_row2 = []; +const levenshtein_row2 = []; function levenshtein(s1, s2) { if (s1 === s2) { return 0; } - var s1_len = s1.length, s2_len = s2.length; + const s1_len = s1.length, s2_len = s2.length; if (s1_len && s2_len) { - var i1 = 0, i2 = 0, a, b, c, c2, row = levenshtein_row2; + let i1 = 0, i2 = 0, a, b, c, c2; + const row = levenshtein_row2; while (i1 < s1_len) { row[i1] = ++i1; } @@ -106,24 +101,20 @@ function levenshtein(s1, s2) { } window.initSearch = function(rawSearchIndex) { - var MAX_LEV_DISTANCE = 3; - var MAX_RESULTS = 200; - var GENERICS_DATA = 2; - var NAME = 0; - var INPUTS_DATA = 0; - var OUTPUT_DATA = 1; - var NO_TYPE_FILTER = -1; + const MAX_LEV_DISTANCE = 3; + const MAX_RESULTS = 200; + const GENERICS_DATA = 2; + const NAME = 0; + const INPUTS_DATA = 0; + const OUTPUT_DATA = 1; + const NO_TYPE_FILTER = -1; /** * @type {Array<Row>} */ - var searchIndex; - /** - * @type {Array<string>} - */ - var searchWords; - var currentResults; - var ALIASES = {}; - var params = searchState.getQueryStringParams(); + let searchIndex; + let currentResults; + const ALIASES = {}; + const params = searchState.getQueryStringParams(); // Populate search bar with query string search term when provided, // but only if the input bar is empty. This avoid the obnoxious issue @@ -133,15 +124,451 @@ window.initSearch = function(rawSearchIndex) { searchState.input.value = params.search || ""; } + function isWhitespace(c) { + return " \t\n\r".indexOf(c) !== -1; + } + + function isSpecialStartCharacter(c) { + return "<\"".indexOf(c) !== -1; + } + + function isEndCharacter(c) { + return ",>-".indexOf(c) !== -1; + } + + function isStopCharacter(c) { + return isWhitespace(c) || isEndCharacter(c); + } + + function isErrorCharacter(c) { + return "()".indexOf(c) !== -1; + } + + function itemTypeFromName(typename) { + for (let i = 0, len = itemTypes.length; i < len; ++i) { + if (itemTypes[i] === typename) { + return i; + } + } + + throw new Error("Unknown type filter `" + typename + "`"); + } + + /** + * If we encounter a `"`, then we try to extract the string from it until we find another `"`. + * + * This function will throw an error in the following cases: + * * There is already another string element. + * * We are parsing a generic argument. + * * There is more than one element. + * * There is no closing `"`. + * + * @param {ParsedQuery} query + * @param {ParserState} parserState + * @param {boolean} isInGenerics + */ + function getStringElem(query, parserState, isInGenerics) { + if (isInGenerics) { + throw new Error("`\"` cannot be used in generics"); + } else if (query.literalSearch) { + throw new Error("Cannot have more than one literal search element"); + } else if (parserState.totalElems - parserState.genericsElems > 0) { + throw new Error("Cannot use literal search when there is more than one element"); + } + parserState.pos += 1; + const start = parserState.pos; + const end = getIdentEndPosition(parserState); + if (parserState.pos >= parserState.length) { + throw new Error("Unclosed `\"`"); + } else if (parserState.userQuery[end] !== "\"") { + throw new Error(`Unexpected \`${parserState.userQuery[end]}\` in a string element`); + } else if (start === end) { + throw new Error("Cannot have empty string element"); + } + // To skip the quote at the end. + parserState.pos += 1; + query.literalSearch = true; + } + + /** + * Returns `true` if the current parser position is starting with "::". + * + * @param {ParserState} parserState + * + * @return {boolean} + */ + function isPathStart(parserState) { + return parserState.userQuery.slice(parserState.pos, parserState.pos + 2) == '::'; + } + + /** + * Returns `true` if the current parser position is starting with "->". + * + * @param {ParserState} parserState + * + * @return {boolean} + */ + function isReturnArrow(parserState) { + return parserState.userQuery.slice(parserState.pos, parserState.pos + 2) == '->'; + } + + /** + * Returns `true` if the given `c` character is valid for an ident. + * + * @param {string} c + * + * @return {boolean} + */ + function isIdentCharacter(c) { + return ( + c === '_' || + (c >= '0' && c <= '9') || + (c >= 'a' && c <= 'z') || + (c >= 'A' && c <= 'Z')); + } + + /** + * Returns `true` if the given `c` character is a separator. + * + * @param {string} c + * + * @return {boolean} + */ + function isSeparatorCharacter(c) { + return c === "," || isWhitespaceCharacter(c); + } + + /** + * Returns `true` if the given `c` character is a whitespace. + * + * @param {string} c + * + * @return {boolean} + */ + function isWhitespaceCharacter(c) { + return c === " " || c === "\t"; + } + + /** + * @param {ParsedQuery} query + * @param {ParserState} parserState + * @param {string} name - Name of the query element. + * @param {Array<QueryElement>} generics - List of generics of this query element. + * + * @return {QueryElement} - The newly created `QueryElement`. + */ + function createQueryElement(query, parserState, name, generics, isInGenerics) { + if (name === '*' || (name.length === 0 && generics.length === 0)) { + return; + } + if (query.literalSearch && parserState.totalElems - parserState.genericsElems > 0) { + throw new Error("You cannot have more than one element if you use quotes"); + } + const pathSegments = name.split("::"); + if (pathSegments.length > 1) { + for (let i = 0, len = pathSegments.length; i < len; ++i) { + const pathSegment = pathSegments[i]; + + if (pathSegment.length === 0) { + if (i === 0) { + throw new Error("Paths cannot start with `::`"); + } else if (i + 1 === len) { + throw new Error("Paths cannot end with `::`"); + } + throw new Error("Unexpected `::::`"); + } + } + } + // In case we only have something like `<p>`, there is no name. + if (pathSegments.length === 0 || (pathSegments.length === 1 && pathSegments[0] === "")) { + throw new Error("Found generics without a path"); + } + parserState.totalElems += 1; + if (isInGenerics) { + parserState.genericsElems += 1; + } + return { + name: name, + fullPath: pathSegments, + pathWithoutLast: pathSegments.slice(0, pathSegments.length - 1), + pathLast: pathSegments[pathSegments.length - 1], + generics: generics, + }; + } + + /** + * This function goes through all characters until it reaches an invalid ident character or the + * end of the query. It returns the position of the last character of the ident. + * + * @param {ParserState} parserState + * + * @return {integer} + */ + function getIdentEndPosition(parserState) { + let end = parserState.pos; + let foundExclamation = false; + while (parserState.pos < parserState.length) { + const c = parserState.userQuery[parserState.pos]; + if (!isIdentCharacter(c)) { + if (c === "!") { + if (foundExclamation) { + throw new Error("Cannot have more than one `!` in an ident"); + } else if (parserState.pos + 1 < parserState.length && + isIdentCharacter(parserState.userQuery[parserState.pos + 1])) + { + throw new Error("`!` can only be at the end of an ident"); + } + foundExclamation = true; + } else if (isErrorCharacter(c)) { + throw new Error(`Unexpected \`${c}\``); + } else if ( + isStopCharacter(c) || + isSpecialStartCharacter(c) || + isSeparatorCharacter(c)) + { + break; + } + // If we allow paths ("str::string" for example). + else if (c === ":") { + if (!isPathStart(parserState)) { + break; + } + // Skip current ":". + parserState.pos += 1; + foundExclamation = false; + } else { + throw new Error(`Unexpected \`${c}\``); + } + } + parserState.pos += 1; + end = parserState.pos; + } + return end; + } + + /** + * @param {ParsedQuery} query + * @param {ParserState} parserState + * @param {Array<QueryElement>} elems - This is where the new {QueryElement} will be added. + * @param {boolean} isInGenerics + */ + function getNextElem(query, parserState, elems, isInGenerics) { + const generics = []; + + let start = parserState.pos; + let end; + // We handle the strings on their own mostly to make code easier to follow. + if (parserState.userQuery[parserState.pos] === "\"") { + start += 1; + getStringElem(query, parserState, isInGenerics); + end = parserState.pos - 1; + } else { + end = getIdentEndPosition(parserState); + } + if (parserState.pos < parserState.length && + parserState.userQuery[parserState.pos] === "<") + { + if (isInGenerics) { + throw new Error("Unexpected `<` after `<`"); + } else if (start >= end) { + throw new Error("Found generics without a path"); + } + parserState.pos += 1; + getItemsBefore(query, parserState, generics, ">"); + } + if (start >= end && generics.length === 0) { + return; + } + elems.push( + createQueryElement( + query, + parserState, + parserState.userQuery.slice(start, end), + generics, + isInGenerics + ) + ); + } + + /** + * This function parses the next query element until it finds `endChar`, calling `getNextElem` + * to collect each element. + * + * If there is no `endChar`, this function will implicitly stop at the end without raising an + * error. + * + * @param {ParsedQuery} query + * @param {ParserState} parserState + * @param {Array<QueryElement>} elems - This is where the new {QueryElement} will be added. + * @param {string} endChar - This function will stop when it'll encounter this + * character. + */ + function getItemsBefore(query, parserState, elems, endChar) { + let foundStopChar = true; + + while (parserState.pos < parserState.length) { + const c = parserState.userQuery[parserState.pos]; + if (c === endChar) { + break; + } else if (isSeparatorCharacter(c)) { + parserState.pos += 1; + foundStopChar = true; + continue; + } else if (c === ":" && isPathStart(parserState)) { + throw new Error("Unexpected `::`: paths cannot start with `::`"); + } else if (c === ":" || isEndCharacter(c)) { + let extra = ""; + if (endChar === ">") { + extra = "`<`"; + } else if (endChar === "") { + extra = "`->`"; + } + throw new Error("Unexpected `" + c + "` after " + extra); + } + if (!foundStopChar) { + if (endChar !== "") { + throw new Error(`Expected \`,\`, \` \` or \`${endChar}\`, found \`${c}\``); + } + throw new Error(`Expected \`,\` or \` \`, found \`${c}\``); + } + const posBefore = parserState.pos; + getNextElem(query, parserState, elems, endChar === ">"); + // This case can be encountered if `getNextElem` encounted a "stop character" right from + // the start. For example if you have `,,` or `<>`. In this case, we simply move up the + // current position to continue the parsing. + if (posBefore === parserState.pos) { + parserState.pos += 1; + } + foundStopChar = false; + } + // We are either at the end of the string or on the `endChar`` character, let's move forward + // in any case. + parserState.pos += 1; + } + + /** + * Checks that the type filter doesn't have unwanted characters like `<>` (which are ignored + * if empty). + * + * @param {ParserState} parserState + */ + function checkExtraTypeFilterCharacters(parserState) { + const query = parserState.userQuery; + + for (let pos = 0; pos < parserState.pos; ++pos) { + if (!isIdentCharacter(query[pos]) && !isWhitespaceCharacter(query[pos])) { + throw new Error(`Unexpected \`${query[pos]}\` in type filter`); + } + } + } + + /** + * Parses the provided `query` input to fill `parserState`. If it encounters an error while + * parsing `query`, it'll throw an error. + * + * @param {ParsedQuery} query + * @param {ParserState} parserState + */ + function parseInput(query, parserState) { + let c, before; + let foundStopChar = true; + + while (parserState.pos < parserState.length) { + c = parserState.userQuery[parserState.pos]; + if (isStopCharacter(c)) { + foundStopChar = true; + if (isSeparatorCharacter(c)) { + parserState.pos += 1; + continue; + } else if (c === "-" || c === ">") { + if (isReturnArrow(parserState)) { + break; + } + throw new Error(`Unexpected \`${c}\` (did you mean \`->\`?)`); + } + throw new Error(`Unexpected \`${c}\``); + } else if (c === ":" && !isPathStart(parserState)) { + if (parserState.typeFilter !== null) { + throw new Error("Unexpected `:`"); + } + if (query.elems.length === 0) { + throw new Error("Expected type filter before `:`"); + } else if (query.elems.length !== 1 || parserState.totalElems !== 1) { + throw new Error("Unexpected `:`"); + } else if (query.literalSearch) { + throw new Error("You cannot use quotes on type filter"); + } + checkExtraTypeFilterCharacters(parserState); + // The type filter doesn't count as an element since it's a modifier. + parserState.typeFilter = query.elems.pop().name; + parserState.pos += 1; + parserState.totalElems = 0; + query.literalSearch = false; + foundStopChar = true; + continue; + } + if (!foundStopChar) { + if (parserState.typeFilter !== null) { + throw new Error(`Expected \`,\`, \` \` or \`->\`, found \`${c}\``); + } + throw new Error(`Expected \`,\`, \` \`, \`:\` or \`->\`, found \`${c}\``); + } + before = query.elems.length; + getNextElem(query, parserState, query.elems, false); + if (query.elems.length === before) { + // Nothing was added, weird... Let's increase the position to not remain stuck. + parserState.pos += 1; + } + foundStopChar = false; + } + while (parserState.pos < parserState.length) { + c = parserState.userQuery[parserState.pos]; + if (isReturnArrow(parserState)) { + parserState.pos += 2; + // Get returned elements. + getItemsBefore(query, parserState, query.returned, ""); + // Nothing can come afterward! + if (query.returned.length === 0) { + throw new Error("Expected at least one item after `->`"); + } + break; + } else { + parserState.pos += 1; + } + } + } + + /** + * Takes the user search input and returns an empty `ParsedQuery`. + * + * @param {string} userQuery + * + * @return {ParsedQuery} + */ + function newParsedQuery(userQuery) { + return { + original: userQuery, + userQuery: userQuery.toLowerCase(), + typeFilter: NO_TYPE_FILTER, + elems: [], + returned: [], + // Total number of "top" elements (does not include generics). + foundElems: 0, + literalSearch: false, + error: null, + }; + } + /** * Build an URL with search parameters. * * @param {string} search - The current search being performed. * @param {string|null} filterCrates - The current filtering crate (if any). + * * @return {string} */ function buildUrl(search, filterCrates) { - var extra = "?search=" + encodeURIComponent(search); + let extra = "?search=" + encodeURIComponent(search); if (filterCrates !== null) { extra += "&filter-crate=" + encodeURIComponent(filterCrates); @@ -155,7 +582,7 @@ window.initSearch = function(rawSearchIndex) { * @return {string|null} */ function getFilterCrates() { - var elem = document.getElementById("crate-search"); + const elem = document.getElementById("crate-search"); if (elem && elem.value !== "All crates" && @@ -167,45 +594,149 @@ window.initSearch = function(rawSearchIndex) { } /** - * Executes the query and returns a list of results for each results tab. - * @param {Object} query - The user query - * @param {Array<string>} searchWords - The list of search words to query against - * @param {string} [filterCrates] - Crate to search in - * @return {{ - * in_args: Array<?>, - * returned: Array<?>, - * others: Array<?> - * }} + * Parses the query. + * + * The supported syntax by this parser is as follow: + * + * ident = *(ALPHA / DIGIT / "_") [!] + * path = ident *(DOUBLE-COLON ident) + * arg = path [generics] + * arg-without-generic = path + * type-sep = COMMA/WS *(COMMA/WS) + * nonempty-arg-list = *(type-sep) arg *(type-sep arg) *(type-sep) + * nonempty-arg-list-without-generics = *(type-sep) arg-without-generic + * *(type-sep arg-without-generic) *(type-sep) + * generics = OPEN-ANGLE-BRACKET [ nonempty-arg-list-without-generics ] *(type-sep) + * CLOSE-ANGLE-BRACKET/EOF + * return-args = RETURN-ARROW *(type-sep) nonempty-arg-list + * + * exact-search = [type-filter *WS COLON] [ RETURN-ARROW ] *WS QUOTE ident QUOTE [ generics ] + * type-search = [type-filter *WS COLON] [ nonempty-arg-list ] [ return-args ] + * + * query = *WS (exact-search / type-search) *WS + * + * type-filter = ( + * "mod" / + * "externcrate" / + * "import" / + * "struct" / + * "enum" / + * "fn" / + * "type" / + * "static" / + * "trait" / + * "impl" / + * "tymethod" / + * "method" / + * "structfield" / + * "variant" / + * "macro" / + * "primitive" / + * "associatedtype" / + * "constant" / + * "associatedconstant" / + * "union" / + * "foreigntype" / + * "keyword" / + * "existential" / + * "attr" / + * "derive" / + * "traitalias") + * + * OPEN-ANGLE-BRACKET = "<" + * CLOSE-ANGLE-BRACKET = ">" + * COLON = ":" + * DOUBLE-COLON = "::" + * QUOTE = %x22 + * COMMA = "," + * RETURN-ARROW = "->" + * + * ALPHA = %x41-5A / %x61-7A ; A-Z / a-z + * DIGIT = %x30-39 + * WS = %x09 / " " + * + * @param {string} val - The user query + * + * @return {ParsedQuery} - The parsed query */ - function execQuery(query, searchWords, filterCrates) { - function itemTypeFromName(typename) { - for (var i = 0, len = itemTypes.length; i < len; ++i) { - if (itemTypes[i] === typename) { - return i; + function parseQuery(userQuery) { + userQuery = userQuery.trim(); + const parserState = { + length: userQuery.length, + pos: 0, + // Total number of elements (includes generics). + totalElems: 0, + genericsElems: 0, + typeFilter: null, + userQuery: userQuery.toLowerCase(), + }; + let query = newParsedQuery(userQuery); + + try { + parseInput(query, parserState); + if (parserState.typeFilter !== null) { + let typeFilter = parserState.typeFilter; + if (typeFilter === "const") { + typeFilter = "constant"; } + query.typeFilter = itemTypeFromName(typeFilter); } - return NO_TYPE_FILTER; + } catch (err) { + query = newParsedQuery(userQuery); + query.error = err.message; + query.typeFilter = -1; + return query; } - var valLower = query.query.toLowerCase(), - val = valLower, - typeFilter = itemTypeFromName(query.type), - results = {}, results_in_args = {}, results_returned = {}, - split = valLower.split("::"); + if (!query.literalSearch) { + // If there is more than one element in the query, we switch to literalSearch in any + // case. + query.literalSearch = parserState.totalElems > 1; + } + query.foundElems = query.elems.length + query.returned.length; + return query; + } + + /** + * Creates the query results. + * + * @param {Array<Result>} results_in_args + * @param {Array<Result>} results_returned + * @param {Array<Result>} results_in_args + * @param {ParsedQuery} parsedQuery + * + * @return {ResultsTable} + */ + function createQueryResults(results_in_args, results_returned, results_others, parsedQuery) { + return { + "in_args": results_in_args, + "returned": results_returned, + "others": results_others, + "query": parsedQuery, + }; + } - removeEmptyStringsFromArray(split); + /** + * Executes the parsed query and builds a {ResultsTable}. + * + * @param {ParsedQuery} parsedQuery - The parsed user query + * @param {Object} searchWords - The list of search words to query against + * @param {Object} [filterCrates] - Crate to search in if defined + * + * @return {ResultsTable} + */ + function execQuery(parsedQuery, searchWords, filterCrates) { + const results_others = {}, results_in_args = {}, results_returned = {}; function transformResults(results) { - var duplicates = {}; - var out = []; - - for (var i = 0, len = results.length; i < len; ++i) { - var result = results[i]; + const duplicates = {}; + const out = []; + for (const result of results) { if (result.id > -1) { - var obj = searchIndex[result.id]; + const obj = searchIndex[result.id]; obj.lev = result.lev; - var res = buildHrefAndPath(obj); + const res = buildHrefAndPath(obj); obj.displayPath = pathSplitter(res[0]); obj.fullPath = obj.displayPath + obj.name; // To be sure than it some items aren't considered as duplicate. @@ -227,10 +758,11 @@ window.initSearch = function(rawSearchIndex) { } function sortResults(results, isType) { - var ar = []; - for (var entry in results) { + const userQuery = parsedQuery.userQuery; + const ar = []; + for (const entry in results) { if (hasOwnPropertyRustdoc(results, entry)) { - var result = results[entry]; + const result = results[entry]; result.word = searchWords[result.id]; result.item = searchIndex[result.id] || {}; ar.push(result); @@ -243,11 +775,11 @@ window.initSearch = function(rawSearchIndex) { } results.sort(function(aaa, bbb) { - var a, b; + let a, b; // sort by exact match with regard to the last word (mismatch goes later) - a = (aaa.word !== val); - b = (bbb.word !== val); + a = (aaa.word !== userQuery); + b = (bbb.word !== userQuery); if (a !== b) { return a - b; } // Sort by non levenshtein results and then levenshtein results by the distance @@ -309,270 +841,273 @@ window.initSearch = function(rawSearchIndex) { return 0; }); - for (var i = 0, len = results.length; i < len; ++i) { - result = results[i]; + let nameSplit = null; + if (parsedQuery.elems.length === 1) { + const hasPath = typeof parsedQuery.elems[0].path === "undefined"; + nameSplit = hasPath ? null : parsedQuery.elems[0].path; + } + for (const result of results) { // this validation does not make sense when searching by types if (result.dontValidate) { continue; } - var name = result.item.name.toLowerCase(), + const name = result.item.name.toLowerCase(), path = result.item.path.toLowerCase(), parent = result.item.parent; - if (!isType && !validateResult(name, path, split, parent)) { + if (!isType && !validateResult(name, path, nameSplit, parent)) { result.id = -1; } } return transformResults(results); } - function extractGenerics(val) { - val = val.toLowerCase(); - if (val.indexOf("<") !== -1) { - var values = val.substring(val.indexOf("<") + 1, val.lastIndexOf(">")); - return { - name: val.substring(0, val.indexOf("<")), - generics: values.split(/\s*,\s*/), - }; + /** + * This function checks if the object (`row`) generics match the given type (`elem`) + * generics. If there are no generics on `row`, `defaultLev` is returned. + * + * @param {Row} row - The object to check. + * @param {QueryElement} elem - The element from the parsed query. + * @param {integer} defaultLev - This is the value to return in case there are no generics. + * + * @return {integer} - Returns the best match (if any) or `MAX_LEV_DISTANCE + 1`. + */ + function checkGenerics(row, elem, defaultLev) { + if (row.length <= GENERICS_DATA || row[GENERICS_DATA].length === 0) { + return elem.generics.length === 0 ? defaultLev : MAX_LEV_DISTANCE + 1; + } else if (row[GENERICS_DATA].length > 0 && row[GENERICS_DATA][0][NAME] === "") { + if (row.length > GENERICS_DATA) { + return checkGenerics(row[GENERICS_DATA][0], elem, defaultLev); + } + return elem.generics.length === 0 ? defaultLev : MAX_LEV_DISTANCE + 1; } - return { - name: val, - generics: [], - }; - } - - function checkGenerics(obj, val) { // The names match, but we need to be sure that all generics kinda // match as well. - var tmp_lev, elem_name; - if (val.generics.length > 0) { - if (obj.length > GENERICS_DATA && - obj[GENERICS_DATA].length >= val.generics.length) { - var elems = Object.create(null); - var elength = obj[GENERICS_DATA].length; - for (var x = 0; x < elength; ++x) { - if (!elems[obj[GENERICS_DATA][x][NAME]]) { - elems[obj[GENERICS_DATA][x][NAME]] = 0; + let elem_name; + if (elem.generics.length > 0 && row[GENERICS_DATA].length >= elem.generics.length) { + const elems = Object.create(null); + for (const entry of row[GENERICS_DATA]) { + elem_name = entry[NAME]; + if (elem_name === "") { + // Pure generic, needs to check into it. + if (checkGenerics(entry, elem, MAX_LEV_DISTANCE + 1) !== 0) { + return MAX_LEV_DISTANCE + 1; } - elems[obj[GENERICS_DATA][x][NAME]] += 1; + continue; + } + if (elems[elem_name] === undefined) { + elems[elem_name] = 0; } - var total = 0; - var done = 0; - // We need to find the type that matches the most to remove it in order - // to move forward. - var vlength = val.generics.length; - for (x = 0; x < vlength; ++x) { - var lev = MAX_LEV_DISTANCE + 1; - var firstGeneric = val.generics[x]; - var match = null; - if (elems[firstGeneric]) { - match = firstGeneric; - lev = 0; - } else { - for (elem_name in elems) { - tmp_lev = levenshtein(elem_name, firstGeneric); - if (tmp_lev < lev) { - lev = tmp_lev; - match = elem_name; - } + elems[elem_name] += 1; + } + // We need to find the type that matches the most to remove it in order + // to move forward. + for (const generic of elem.generics) { + let match = null; + if (elems[generic.name]) { + match = generic.name; + } else { + for (elem_name in elems) { + if (!hasOwnPropertyRustdoc(elems, elem_name)) { + continue; } - } - if (match !== null) { - elems[match] -= 1; - if (elems[match] == 0) { - delete elems[match]; + if (elem_name === generic) { + match = elem_name; + break; } - total += lev; - done += 1; - } else { - return MAX_LEV_DISTANCE + 1; } } - return Math.ceil(total / done); + if (match === null) { + return MAX_LEV_DISTANCE + 1; + } + elems[match] -= 1; + if (elems[match] === 0) { + delete elems[match]; + } } + return 0; } return MAX_LEV_DISTANCE + 1; } /** - * This function checks if the object (`obj`) matches the given type (`val`) and its + * This function checks if the object (`row`) matches the given type (`elem`) and its * generics (if any). * - * @param {Object} obj - * @param {string} val + * @param {Row} row + * @param {QueryElement} elem - The element from the parsed query. + * + * @return {integer} - Returns a Levenshtein distance to the best match. + */ + function checkIfInGenerics(row, elem) { + let lev = MAX_LEV_DISTANCE + 1; + for (const entry of row[GENERICS_DATA]) { + lev = Math.min(checkType(entry, elem, true), lev); + if (lev === 0) { + break; + } + } + return lev; + } + + /** + * This function checks if the object (`row`) matches the given type (`elem`) and its + * generics (if any). + * + * @param {Row} row + * @param {QueryElement} elem - The element from the parsed query. * @param {boolean} literalSearch * * @return {integer} - Returns a Levenshtein distance to the best match. If there is * no match, returns `MAX_LEV_DISTANCE + 1`. */ - function checkType(obj, val, literalSearch) { - var lev_distance = MAX_LEV_DISTANCE + 1; - var tmp_lev = MAX_LEV_DISTANCE + 1; - var len, x, firstGeneric; - if (obj[NAME] === val.name) { - if (literalSearch) { - if (val.generics && val.generics.length !== 0) { - if (obj.length > GENERICS_DATA && - obj[GENERICS_DATA].length > 0) { - var elems = Object.create(null); - len = obj[GENERICS_DATA].length; - for (x = 0; x < len; ++x) { - if (!elems[obj[GENERICS_DATA][x][NAME]]) { - elems[obj[GENERICS_DATA][x][NAME]] = 0; - } - elems[obj[GENERICS_DATA][x][NAME]] += 1; - } + function checkType(row, elem, literalSearch) { + if (row[NAME].length === 0) { + // This is a pure "generic" search, no need to run other checks. + if (row.length > GENERICS_DATA) { + return checkIfInGenerics(row, elem); + } + return MAX_LEV_DISTANCE + 1; + } - len = val.generics.length; - for (x = 0; x < len; ++x) { - firstGeneric = val.generics[x]; - if (elems[firstGeneric]) { - elems[firstGeneric] -= 1; - } else { - // Something wasn't found and this is a literal search so - // abort and return a "failing" distance. - return MAX_LEV_DISTANCE + 1; - } - } - // Everything was found, success! + let lev = levenshtein(row[NAME], elem.name); + if (literalSearch) { + if (lev !== 0) { + // The name didn't match, let's try to check if the generics do. + if (elem.generics.length === 0) { + const checkGeneric = (row.length > GENERICS_DATA && + row[GENERICS_DATA].length > 0); + if (checkGeneric && row[GENERICS_DATA].findIndex(function(tmp_elem) { + return tmp_elem[NAME] === elem.name; + }) !== -1) { return 0; } - return MAX_LEV_DISTANCE + 1; } - return 0; - } else { - // If the type has generics but don't match, then it won't return at this point. - // Otherwise, `checkGenerics` will return 0 and it'll return. - if (obj.length > GENERICS_DATA && obj[GENERICS_DATA].length !== 0) { - tmp_lev = checkGenerics(obj, val); - if (tmp_lev <= MAX_LEV_DISTANCE) { - return tmp_lev; - } - } - } - } else if (literalSearch) { - var found = false; - if ((!val.generics || val.generics.length === 0) && - obj.length > GENERICS_DATA && obj[GENERICS_DATA].length > 0) { - found = obj[GENERICS_DATA].some( - function(gen) { - return gen[NAME] === val.name; - }); - } - return found ? 0 : MAX_LEV_DISTANCE + 1; - } - lev_distance = Math.min(levenshtein(obj[NAME], val.name), lev_distance); - if (lev_distance <= MAX_LEV_DISTANCE) { - // The generics didn't match but the name kinda did so we give it - // a levenshtein distance value that isn't *this* good so it goes - // into the search results but not too high. - lev_distance = Math.ceil((checkGenerics(obj, val) + lev_distance) / 2); - } - if (obj.length > GENERICS_DATA && obj[GENERICS_DATA].length > 0) { - // We can check if the type we're looking for is inside the generics! - var olength = obj[GENERICS_DATA].length; - for (x = 0; x < olength; ++x) { - tmp_lev = Math.min(levenshtein(obj[GENERICS_DATA][x][NAME], val.name), tmp_lev); + return MAX_LEV_DISTANCE + 1; + } else if (elem.generics.length > 0) { + return checkGenerics(row, elem, MAX_LEV_DISTANCE + 1); } - if (tmp_lev !== 0) { - // If we didn't find a good enough result, we go check inside the generics of - // the generics. - for (x = 0; x < olength && tmp_lev !== 0; ++x) { - tmp_lev = Math.min( - checkType(obj[GENERICS_DATA][x], val, literalSearch), - tmp_lev - ); + return 0; + } else if (row.length > GENERICS_DATA) { + if (elem.generics.length === 0) { + if (lev === 0) { + return 0; + } + // The name didn't match so we now check if the type we're looking for is inside + // the generics! + lev = checkIfInGenerics(row, elem); + // Now whatever happens, the returned distance is "less good" so we should mark + // it as such, and so we add 0.5 to the distance to make it "less good". + return lev + 0.5; + } else if (lev > MAX_LEV_DISTANCE) { + // So our item's name doesn't match at all and has generics. + // + // Maybe it's present in a sub generic? For example "f<A<B<C>>>()", if we're + // looking for "B<C>", we'll need to go down. + return checkIfInGenerics(row, elem); + } else { + // At this point, the name kinda match and we have generics to check, so + // let's go! + const tmp_lev = checkGenerics(row, elem, lev); + if (tmp_lev > MAX_LEV_DISTANCE) { + return MAX_LEV_DISTANCE + 1; } + // We compute the median value of both checks and return it. + return (tmp_lev + lev) / 2; } + } else if (elem.generics.length > 0) { + // In this case, we were expecting generics but there isn't so we simply reject this + // one. + return MAX_LEV_DISTANCE + 1; } - // Now whatever happens, the returned distance is "less good" so we should mark it - // as such, and so we add 1 to the distance to make it "less good". - return Math.min(lev_distance, tmp_lev) + 1; + // No generics on our query or on the target type so we can return without doing + // anything else. + return lev; } /** - * This function checks if the object (`obj`) has an argument with the given type (`val`). + * This function checks if the object (`row`) has an argument with the given type (`elem`). * - * @param {Object} obj - * @param {string} val - * @param {boolean} literalSearch + * @param {Row} row + * @param {QueryElement} elem - The element from the parsed query. * @param {integer} typeFilter * * @return {integer} - Returns a Levenshtein distance to the best match. If there is no * match, returns `MAX_LEV_DISTANCE + 1`. */ - function findArg(obj, val, literalSearch, typeFilter) { - var lev_distance = MAX_LEV_DISTANCE + 1; - - if (obj && obj.type && obj.type[INPUTS_DATA] && obj.type[INPUTS_DATA].length > 0) { - var length = obj.type[INPUTS_DATA].length; - for (var i = 0; i < length; i++) { - var tmp = obj.type[INPUTS_DATA][i]; - if (!typePassesFilter(typeFilter, tmp[1])) { + function findArg(row, elem, typeFilter) { + let lev = MAX_LEV_DISTANCE + 1; + + if (row && row.type && row.type[INPUTS_DATA] && row.type[INPUTS_DATA].length > 0) { + for (const input of row.type[INPUTS_DATA]) { + if (!typePassesFilter(typeFilter, input[1])) { continue; } - tmp = checkType(tmp, val, literalSearch); - if (tmp === 0) { + lev = Math.min(lev, checkType(input, elem, parsedQuery.literalSearch)); + if (lev === 0) { return 0; - } else if (literalSearch) { - continue; } - lev_distance = Math.min(tmp, lev_distance); } } - return literalSearch ? MAX_LEV_DISTANCE + 1 : lev_distance; + return parsedQuery.literalSearch ? MAX_LEV_DISTANCE + 1 : lev; } - function checkReturned(obj, val, literalSearch, typeFilter) { - var lev_distance = MAX_LEV_DISTANCE + 1; + /** + * This function checks if the object (`row`) returns the given type (`elem`). + * + * @param {Row} row + * @param {QueryElement} elem - The element from the parsed query. + * @param {integer} typeFilter + * + * @return {integer} - Returns a Levenshtein distance to the best match. If there is no + * match, returns `MAX_LEV_DISTANCE + 1`. + */ + function checkReturned(row, elem, typeFilter) { + let lev = MAX_LEV_DISTANCE + 1; - if (obj && obj.type && obj.type.length > OUTPUT_DATA) { - var ret = obj.type[OUTPUT_DATA]; + if (row && row.type && row.type.length > OUTPUT_DATA) { + let ret = row.type[OUTPUT_DATA]; if (typeof ret[0] === "string") { ret = [ret]; } - for (var x = 0, len = ret.length; x < len; ++x) { - var tmp = ret[x]; - if (!typePassesFilter(typeFilter, tmp[1])) { + for (const ret_ty of ret) { + if (!typePassesFilter(typeFilter, ret_ty[1])) { continue; } - tmp = checkType(tmp, val, literalSearch); - if (tmp === 0) { + lev = Math.min(lev, checkType(ret_ty, elem, parsedQuery.literalSearch)); + if (lev === 0) { return 0; - } else if (literalSearch) { - continue; } - lev_distance = Math.min(tmp, lev_distance); } } - return literalSearch ? MAX_LEV_DISTANCE + 1 : lev_distance; + return parsedQuery.literalSearch ? MAX_LEV_DISTANCE + 1 : lev; } function checkPath(contains, lastElem, ty) { if (contains.length === 0) { return 0; } - var ret_lev = MAX_LEV_DISTANCE + 1; - var path = ty.path.split("::"); + let ret_lev = MAX_LEV_DISTANCE + 1; + const path = ty.path.split("::"); if (ty.parent && ty.parent.name) { path.push(ty.parent.name.toLowerCase()); } - var length = path.length; - var clength = contains.length; + const length = path.length; + const clength = contains.length; if (clength > length) { return MAX_LEV_DISTANCE + 1; } - for (var i = 0; i < length; ++i) { + for (let i = 0; i < length; ++i) { if (i + clength > length) { break; } - var lev_total = 0; - var aborted = false; - for (var x = 0; x < clength; ++x) { - var lev = levenshtein(path[i + x], contains[x]); + let lev_total = 0; + let aborted = false; + for (let x = 0; x < clength; ++x) { + const lev = levenshtein(path[i + x], contains[x]); if (lev > MAX_LEV_DISTANCE) { aborted = true; break; @@ -591,7 +1126,7 @@ window.initSearch = function(rawSearchIndex) { if (filter <= NO_TYPE_FILTER || filter === type) return true; // Match related items - var name = itemTypes[type]; + const name = itemTypes[type]; switch (itemTypes[filter]) { case "constant": return name === "associatedconstant"; @@ -621,32 +1156,31 @@ window.initSearch = function(rawSearchIndex) { } function handleAliases(ret, query, filterCrates) { + const lowerQuery = query.toLowerCase(); // We separate aliases and crate aliases because we want to have current crate // aliases to be before the others in the displayed results. - var aliases = []; - var crateAliases = []; + const aliases = []; + const crateAliases = []; if (filterCrates !== null) { - if (ALIASES[filterCrates] && ALIASES[filterCrates][query.search]) { - var query_aliases = ALIASES[filterCrates][query.search]; - var len = query_aliases.length; - for (var i = 0; i < len; ++i) { - aliases.push(createAliasFromItem(searchIndex[query_aliases[i]])); + if (ALIASES[filterCrates] && ALIASES[filterCrates][lowerQuery]) { + const query_aliases = ALIASES[filterCrates][lowerQuery]; + for (const alias of query_aliases) { + aliases.push(createAliasFromItem(searchIndex[alias])); } } } else { Object.keys(ALIASES).forEach(function(crate) { - if (ALIASES[crate][query.search]) { - var pushTo = crate === window.currentCrate ? crateAliases : aliases; - var query_aliases = ALIASES[crate][query.search]; - var len = query_aliases.length; - for (var i = 0; i < len; ++i) { - pushTo.push(createAliasFromItem(searchIndex[query_aliases[i]])); + if (ALIASES[crate][lowerQuery]) { + const pushTo = crate === window.currentCrate ? crateAliases : aliases; + const query_aliases = ALIASES[crate][lowerQuery]; + for (const alias of query_aliases) { + pushTo.push(createAliasFromItem(searchIndex[alias])); } } }); } - var sortFunc = function(aaa, bbb) { + const sortFunc = function(aaa, bbb) { if (aaa.path < bbb.path) { return 1; } else if (aaa.path === bbb.path) { @@ -657,9 +1191,9 @@ window.initSearch = function(rawSearchIndex) { crateAliases.sort(sortFunc); aliases.sort(sortFunc); - var pushFunc = function(alias) { - alias.alias = query.raw; - var res = buildHrefAndPath(alias); + const pushFunc = function(alias) { + alias.alias = query; + const res = buildHrefAndPath(alias); alias.displayPath = pathSplitter(res[0]); alias.fullPath = alias.displayPath + alias.name; alias.href = res[1]; @@ -674,208 +1208,235 @@ window.initSearch = function(rawSearchIndex) { } /** - * This function adds the given result into the provided `res` map if it matches the + * This function adds the given result into the provided `results` map if it matches the * following condition: * - * * If it is a "literal search" (`isExact`), then `lev` must be 0. + * * If it is a "literal search" (`parsedQuery.literalSearch`), then `lev` must be 0. * * If it is not a "literal search", `lev` must be <= `MAX_LEV_DISTANCE`. * - * The `res` map contains information which will be used to sort the search results: + * The `results` map contains information which will be used to sort the search results: * - * * `fullId` is a `string`` used as the key of the object we use for the `res` map. + * * `fullId` is a `string`` used as the key of the object we use for the `results` map. * * `id` is the index in both `searchWords` and `searchIndex` arrays for this element. * * `index` is an `integer`` used to sort by the position of the word in the item's name. * * `lev` is the main metric used to sort the search results. * - * @param {boolean} isExact - * @param {Object} res + * @param {Results} results * @param {string} fullId * @param {integer} id * @param {integer} index * @param {integer} lev */ - function addIntoResults(isExact, res, fullId, id, index, lev) { - if (lev === 0 || (!isExact && lev <= MAX_LEV_DISTANCE)) { - if (res[fullId] !== undefined) { - var result = res[fullId]; + function addIntoResults(results, fullId, id, index, lev) { + if (lev === 0 || (!parsedQuery.literalSearch && lev <= MAX_LEV_DISTANCE)) { + if (results[fullId] !== undefined) { + const result = results[fullId]; if (result.dontValidate || result.lev <= lev) { return; } } - res[fullId] = { + results[fullId] = { id: id, index: index, - dontValidate: isExact, + dontValidate: parsedQuery.literalSearch, lev: lev, }; } } - // quoted values mean literal search - var nSearchWords = searchWords.length; - var i, it; - var ty; - var fullId; - var returned; - var in_args; - var len; - if ((val.charAt(0) === "\"" || val.charAt(0) === "'") && - val.charAt(val.length - 1) === val.charAt(0)) - { - val = extractGenerics(val.substr(1, val.length - 2)); - for (i = 0; i < nSearchWords; ++i) { - if (filterCrates !== null && searchIndex[i].crate !== filterCrates) { - continue; + /** + * This function is called in case the query is only one element (with or without generics). + * This element will be compared to arguments' and returned values' items and also to items. + * + * Other important thing to note: since there is only one element, we use levenshtein + * distance for name comparisons. + * + * @param {Row} row + * @param {integer} pos - Position in the `searchIndex`. + * @param {QueryElement} elem - The element from the parsed query. + * @param {Results} results_others - Unqualified results (not in arguments nor in + * returned values). + * @param {Results} results_in_args - Matching arguments results. + * @param {Results} results_returned - Matching returned arguments results. + */ + function handleSingleArg( + row, + pos, + elem, + results_others, + results_in_args, + results_returned + ) { + if (!row || (filterCrates !== null && row.crate !== filterCrates)) { + return; + } + let lev, lev_add = 0, index = -1; + const fullId = row.id; + + const in_args = findArg(row, elem, parsedQuery.typeFilter); + const returned = checkReturned(row, elem, parsedQuery.typeFilter); + + addIntoResults(results_in_args, fullId, pos, index, in_args); + addIntoResults(results_returned, fullId, pos, index, returned); + + if (!typePassesFilter(parsedQuery.typeFilter, row.ty)) { + return; + } + const searchWord = searchWords[pos]; + + if (parsedQuery.literalSearch) { + if (searchWord === elem.name) { + addIntoResults(results_others, fullId, pos, -1, 0); + } + return; + } + + // No need to check anything else if it's a "pure" generics search. + if (elem.name.length === 0) { + if (row.type !== null) { + lev = checkGenerics(row.type, elem, MAX_LEV_DISTANCE + 1); + addIntoResults(results_others, fullId, pos, index, lev); } - in_args = findArg(searchIndex[i], val, true, typeFilter); - returned = checkReturned(searchIndex[i], val, true, typeFilter); - ty = searchIndex[i]; - fullId = ty.id; - - if (searchWords[i] === val.name - && typePassesFilter(typeFilter, searchIndex[i].ty)) { - addIntoResults(true, results, fullId, i, -1, 0); + return; + } + + if (elem.fullPath.length > 1) { + lev = checkPath(elem.pathWithoutLast, elem.pathLast, row); + if (lev > MAX_LEV_DISTANCE || (parsedQuery.literalSearch && lev !== 0)) { + return; + } else if (lev > 0) { + lev_add = lev / 10; } - addIntoResults(true, results_in_args, fullId, i, -1, in_args); - addIntoResults(true, results_returned, fullId, i, -1, returned); - } - query.inputs = [val]; - query.output = val; - query.search = val; - // searching by type - } else if (val.search("->") > -1) { - var trimmer = function(s) { return s.trim(); }; - var parts = val.split("->").map(trimmer); - var input = parts[0]; - // sort inputs so that order does not matter - var inputs = input.split(",").map(trimmer).sort(); - for (i = 0, len = inputs.length; i < len; ++i) { - inputs[i] = extractGenerics(inputs[i]); - } - var output = extractGenerics(parts[1]); - - for (i = 0; i < nSearchWords; ++i) { - if (filterCrates !== null && searchIndex[i].crate !== filterCrates) { - continue; + } + + if (searchWord.indexOf(elem.pathLast) > -1 || + row.normalizedName.indexOf(elem.pathLast) > -1) + { + // filter type: ... queries + if (!results_others[fullId] !== undefined) { + index = row.normalizedName.indexOf(elem.pathLast); } - var type = searchIndex[i].type; - ty = searchIndex[i]; - if (!type) { - continue; + } + lev = levenshtein(searchWord, elem.pathLast); + lev += lev_add; + if (lev > 0 && elem.pathLast.length > 2 && searchWord.indexOf(elem.pathLast) > -1) + { + if (elem.pathLast.length < 6) { + lev = 1; + } else { + lev = 0; } - fullId = ty.id; + } + if (lev > MAX_LEV_DISTANCE) { + return; + } else if (index !== -1 && elem.fullPath.length < 2) { + lev -= 1; + } + if (lev < 0) { + lev = 0; + } + addIntoResults(results_others, fullId, pos, index, lev); + } - returned = checkReturned(ty, output, true, NO_TYPE_FILTER); - if (output.name === "*" || returned === 0) { - in_args = false; - var is_module = false; + /** + * This function is called in case the query has more than one element. In this case, it'll + * try to match the items which validates all the elements. For `aa -> bb` will look for + * functions which have a parameter `aa` and has `bb` in its returned values. + * + * @param {Row} row + * @param {integer} pos - Position in the `searchIndex`. + * @param {Object} results + */ + function handleArgs(row, pos, results) { + if (!row || (filterCrates !== null && row.crate !== filterCrates)) { + return; + } - if (input === "*") { - is_module = true; + let totalLev = 0; + let nbLev = 0; + + // If the result is too "bad", we return false and it ends this search. + function checkArgs(elems, callback) { + for (const elem of elems) { + // There is more than one parameter to the query so all checks should be "exact" + const lev = callback(row, elem, NO_TYPE_FILTER); + if (lev <= 1) { + nbLev += 1; + totalLev += lev; } else { - var firstNonZeroDistance = 0; - for (it = 0, len = inputs.length; it < len; it++) { - var distance = checkType(type, inputs[it], true); - if (distance > 0) { - firstNonZeroDistance = distance; - break; - } - } - in_args = firstNonZeroDistance; - } - addIntoResults(true, results_in_args, fullId, i, -1, in_args); - addIntoResults(true, results_returned, fullId, i, -1, returned); - if (is_module) { - addIntoResults(true, results, fullId, i, -1, 0); + return false; } } + return true; + } + if (!checkArgs(parsedQuery.elems, findArg)) { + return; + } + if (!checkArgs(parsedQuery.returned, checkReturned)) { + return; } - query.inputs = inputs.map(function(input) { - return input.name; - }); - query.output = output.name; - } else { - query.inputs = [val]; - query.output = val; - query.search = val; - // gather matching search results up to a certain maximum - val = val.replace(/_/g, ""); - - var valGenerics = extractGenerics(val); - - var paths = valLower.split("::"); - removeEmptyStringsFromArray(paths); - val = paths[paths.length - 1]; - var contains = paths.slice(0, paths.length > 1 ? paths.length - 1 : 1); - - var lev, j; - for (j = 0; j < nSearchWords; ++j) { - ty = searchIndex[j]; - if (!ty || (filterCrates !== null && ty.crate !== filterCrates)) { - continue; - } - var lev_add = 0; - if (paths.length > 1) { - lev = checkPath(contains, paths[paths.length - 1], ty); - if (lev > MAX_LEV_DISTANCE) { - continue; - } else if (lev > 0) { - lev_add = lev / 10; - } - } - returned = MAX_LEV_DISTANCE + 1; - in_args = MAX_LEV_DISTANCE + 1; - var index = -1; - // we want lev results to go lower than others - lev = MAX_LEV_DISTANCE + 1; - fullId = ty.id; + if (nbLev === 0) { + return; + } + const lev = Math.round(totalLev / nbLev); + addIntoResults(results, row.id, pos, 0, lev); + } - if (searchWords[j].indexOf(split[i]) > -1 || - searchWords[j].indexOf(val) > -1 || - ty.normalizedName.indexOf(val) > -1) - { - // filter type: ... queries - if (typePassesFilter(typeFilter, ty.ty) && results[fullId] === undefined) { - index = ty.normalizedName.indexOf(val); + function innerRunQuery() { + let elem, i, nSearchWords, in_returned, row; + + if (parsedQuery.foundElems === 1) { + if (parsedQuery.elems.length === 1) { + elem = parsedQuery.elems[0]; + for (i = 0, nSearchWords = searchWords.length; i < nSearchWords; ++i) { + // It means we want to check for this element everywhere (in names, args and + // returned). + handleSingleArg( + searchIndex[i], + i, + elem, + results_others, + results_in_args, + results_returned + ); } - } - if ((lev = levenshtein(searchWords[j], val)) <= MAX_LEV_DISTANCE) { - if (typePassesFilter(typeFilter, ty.ty)) { - lev += 1; - } else { - lev = MAX_LEV_DISTANCE + 1; + } else if (parsedQuery.returned.length === 1) { + // We received one returned argument to check, so looking into returned values. + elem = parsedQuery.returned[0]; + for (i = 0, nSearchWords = searchWords.length; i < nSearchWords; ++i) { + row = searchIndex[i]; + in_returned = checkReturned(row, elem, parsedQuery.typeFilter); + addIntoResults(results_returned, row.id, i, -1, in_returned); } } - in_args = findArg(ty, valGenerics, false, typeFilter); - returned = checkReturned(ty, valGenerics, false, typeFilter); - - lev += lev_add; - if (lev > 0 && val.length > 3 && searchWords[j].indexOf(val) > -1) { - if (val.length < 6) { - lev -= 1; - } else { - lev = 0; - } + } else if (parsedQuery.foundElems > 0) { + let container = results_others; + // In the special case where only a "returned" information is available, we want to + // put the information into the "results_returned" dict. + if (parsedQuery.returned.length !== 0 && parsedQuery.elems.length === 0) { + container = results_returned; } - addIntoResults(false, results_in_args, fullId, j, index, in_args); - addIntoResults(false, results_returned, fullId, j, index, returned); - if (typePassesFilter(typeFilter, ty.ty) && - (index !== -1 || lev <= MAX_LEV_DISTANCE)) { - if (index !== -1 && paths.length < 2) { - lev = 0; - } - addIntoResults(false, results, fullId, j, index, lev); + for (i = 0, nSearchWords = searchWords.length; i < nSearchWords; ++i) { + handleArgs(searchIndex[i], i, container); } } } - var ret = { - "in_args": sortResults(results_in_args, true), - "returned": sortResults(results_returned, true), - "others": sortResults(results, false), - }; - handleAliases(ret, query, filterCrates); + if (parsedQuery.error === null) { + innerRunQuery(); + } + + const ret = createQueryResults( + sortResults(results_in_args, true), + sortResults(results_returned, true), + sortResults(results_others, false), + parsedQuery); + handleAliases(ret, parsedQuery.original.replace(/"/g, ""), filterCrates); + if (parsedQuery.error !== null && ret.others.length !== 0) { + // It means some doc aliases were found so let's "remove" the error! + ret.query.error = null; + } return ret; } @@ -892,53 +1453,33 @@ window.initSearch = function(rawSearchIndex) { * @param {string} path - The path of the result * @param {string} keys - The keys to be used (["file", "open"]) * @param {Object} parent - The parent of the result + * * @return {boolean} - Whether the result is valid or not */ function validateResult(name, path, keys, parent) { - for (var i = 0, len = keys.length; i < len; ++i) { + if (!keys || !keys.length) { + return true; + } + for (const key of keys) { // each check is for validation so we negate the conditions and invalidate if (!( // check for an exact name match - name.indexOf(keys[i]) > -1 || + name.indexOf(key) > -1 || // then an exact path match - path.indexOf(keys[i]) > -1 || + path.indexOf(key) > -1 || // next if there is a parent, check for exact parent match (parent !== undefined && parent.name !== undefined && - parent.name.toLowerCase().indexOf(keys[i]) > -1) || + parent.name.toLowerCase().indexOf(key) > -1) || // lastly check to see if the name was a levenshtein match - levenshtein(name, keys[i]) <= MAX_LEV_DISTANCE)) { + levenshtein(name, key) <= MAX_LEV_DISTANCE)) { return false; } } return true; } - /** - * Parse a string into a query object. - * - * @param {string} raw - The text that the user typed. - * @returns {ParsedQuery} - */ - function getQuery(raw) { - var matches, type = "", query; - query = raw; - - matches = query.match(/^(fn|mod|struct|enum|trait|type|const|macro)\s*:\s*/i); - if (matches) { - type = matches[1].replace(/^const$/, "constant"); - query = query.substring(matches[0].length); - } - - return { - raw: raw, - query: query, - type: type, - id: query + type - }; - } - function nextTab(direction) { - var next = (searchState.currentTab + direction + 3) % searchState.focusedByTab.length; + const next = (searchState.currentTab + direction + 3) % searchState.focusedByTab.length; searchState.focusedByTab[searchState.currentTab] = document.activeElement; printTab(next); focusSearchResult(); @@ -947,7 +1488,7 @@ window.initSearch = function(rawSearchIndex) { // Focus the first search result on the active tab, or the result that // was focused last time this tab was active. function focusSearchResult() { - var target = searchState.focusedByTab[searchState.currentTab] || + const target = searchState.focusedByTab[searchState.currentTab] || document.querySelectorAll(".search-results.active a").item(0) || document.querySelectorAll("#titles > button").item(searchState.currentTab); if (target) { @@ -956,11 +1497,11 @@ window.initSearch = function(rawSearchIndex) { } function buildHrefAndPath(item) { - var displayPath; - var href; - var type = itemTypes[item.ty]; - var name = item.name; - var path = item.path; + let displayPath; + let href; + const type = itemTypes[item.ty]; + const name = item.name; + let path = item.path; if (type === "mod") { displayPath = path + "::"; @@ -974,19 +1515,19 @@ window.initSearch = function(rawSearchIndex) { displayPath = ""; href = window.rootPath + name + "/index.html"; } else if (item.parent !== undefined) { - var myparent = item.parent; - var anchor = "#" + type + "." + name; - var parentType = itemTypes[myparent.ty]; - var pageType = parentType; - var pageName = myparent.name; + const myparent = item.parent; + let anchor = "#" + type + "." + name; + const parentType = itemTypes[myparent.ty]; + let pageType = parentType; + let pageName = myparent.name; if (parentType === "primitive") { displayPath = myparent.name + "::"; } else if (type === "structfield" && parentType === "variant") { // Structfields belonging to variants are special: the // final path element is the enum name. - var enumNameIdx = item.path.lastIndexOf("::"); - var enumName = item.path.substr(enumNameIdx + 2); + const enumNameIdx = item.path.lastIndexOf("::"); + const enumName = item.path.substr(enumNameIdx + 2); path = item.path.substr(0, enumNameIdx); displayPath = path + "::" + enumName + "::" + myparent.name + "::"; anchor = "#variant." + myparent.name + ".field." + name; @@ -1008,13 +1549,13 @@ window.initSearch = function(rawSearchIndex) { } function escape(content) { - var h1 = document.createElement("h1"); + const h1 = document.createElement("h1"); h1.textContent = content; return h1.innerHTML; } function pathSplitter(path) { - var tmp = "<span>" + path.replace(/::/g, "::</span><span>"); + const tmp = "<span>" + path.replace(/::/g, "::</span><span>"); if (tmp.endsWith("<span>")) { return tmp.slice(0, tmp.length - 6); } @@ -1028,42 +1569,42 @@ window.initSearch = function(rawSearchIndex) { * @param {boolean} display - True if this is the active tab */ function addTab(array, query, display) { - var extraClass = ""; + let extraClass = ""; if (display === true) { extraClass = " active"; } - var output = document.createElement("div"); - var length = 0; + const output = document.createElement("div"); + let length = 0; if (array.length > 0) { output.className = "search-results " + extraClass; array.forEach(function(item) { - var name = item.name; - var type = itemTypes[item.ty]; + const name = item.name; + const type = itemTypes[item.ty]; length += 1; - var extra = ""; + let extra = ""; if (type === "primitive") { extra = " <i>(primitive type)</i>"; } else if (type === "keyword") { extra = " <i>(keyword)</i>"; } - var link = document.createElement("a"); + const link = document.createElement("a"); link.className = "result-" + type; link.href = item.href; - var wrapper = document.createElement("div"); - var resultName = document.createElement("div"); + const wrapper = document.createElement("div"); + const resultName = document.createElement("div"); resultName.className = "result-name"; if (item.is_alias) { - var alias = document.createElement("span"); + const alias = document.createElement("span"); alias.className = "alias"; - var bold = document.createElement("b"); + const bold = document.createElement("b"); bold.innerText = item.alias; alias.appendChild(bold); @@ -1078,9 +1619,9 @@ window.initSearch = function(rawSearchIndex) { item.displayPath + "<span class=\"" + type + "\">" + name + extra + "</span>"); wrapper.appendChild(resultName); - var description = document.createElement("div"); + const description = document.createElement("div"); description.className = "desc"; - var spanDesc = document.createElement("span"); + const spanDesc = document.createElement("span"); spanDesc.insertAdjacentHTML("beforeend", item.desc); description.appendChild(spanDesc); @@ -1088,11 +1629,11 @@ window.initSearch = function(rawSearchIndex) { link.appendChild(wrapper); output.appendChild(link); }); - } else { + } else if (query.error === null) { output.className = "search-failed" + extraClass; output.innerHTML = "No results :(<br/>" + "Try on <a href=\"https://duckduckgo.com/?q=" + - encodeURIComponent("rust " + query.query) + + encodeURIComponent("rust " + query.userQuery) + "\">DuckDuckGo</a>?<br/><br/>" + "Or try looking in one of these:<ul><li>The <a " + "href=\"https://doc.rust-lang.org/reference/index.html\">Rust Reference</a> " + @@ -1115,8 +1656,13 @@ window.initSearch = function(rawSearchIndex) { return "<button>" + text + " <div class=\"count\">(" + nbElems + ")</div></button>"; } + /** + * @param {ResultsTable} results + * @param {boolean} go_to_first + * @param {string} filterCrates + */ function showResults(results, go_to_first, filterCrates) { - var search = searchState.outputElement(); + const search = searchState.outputElement(); if (go_to_first || (results.others.length === 1 && getSettingValue("go-to-only-result") === "true" // By default, the search DOM element is "empty" (meaning it has no children not @@ -1124,7 +1670,7 @@ window.initSearch = function(rawSearchIndex) { // ESC or empty the search input (which also "cancels" the search). && (!search.firstChild || search.firstChild.innerText !== searchState.loadingText))) { - var elem = document.createElement("a"); + const elem = document.createElement("a"); elem.href = results.others[0].href; removeClass(elem, "active"); // For firefox, we need the element to be in the DOM so it can be clicked. @@ -1132,18 +1678,20 @@ window.initSearch = function(rawSearchIndex) { elem.click(); return; } - var query = getQuery(searchState.input.value); + if (results.query === undefined) { + results.query = parseQuery(searchState.input.value); + } - currentResults = query.id; + currentResults = results.query.userQuery; - var ret_others = addTab(results.others, query, true); - var ret_in_args = addTab(results.in_args, query, false); - var ret_returned = addTab(results.returned, query, false); + const ret_others = addTab(results.others, results.query, true); + const ret_in_args = addTab(results.in_args, results.query, false); + const ret_returned = addTab(results.returned, results.query, false); // Navigate to the relevant tab if the current tab is empty, like in case users search // for "-> String". If they had selected another tab previously, they have to click on // it again. - var currentTab = searchState.currentTab; + let currentTab = searchState.currentTab; if ((currentTab === 0 && ret_others[1] === 0) || (currentTab === 1 && ret_in_args[1] === 0) || (currentTab === 2 && ret_returned[1] === 0)) { @@ -1159,29 +1707,37 @@ window.initSearch = function(rawSearchIndex) { let crates = ""; if (window.ALL_CRATES.length > 1) { crates = ` in <select id="crate-search"><option value="All crates">All crates</option>`; - for (let c of window.ALL_CRATES) { + for (const c of window.ALL_CRATES) { crates += `<option value="${c}" ${c == filterCrates && "selected"}>${c}</option>`; } crates += `</select>`; } - var output = `<div id="search-settings"> - <h1 class="search-results-title">Results for ${escape(query.query)} ` + - (query.type ? " (type: " + escape(query.type) + ")" : "") + "</h1>" + - crates + - `</div><div id="titles">` + + + let typeFilter = ""; + if (results.query.typeFilter !== NO_TYPE_FILTER) { + typeFilter = " (type: " + escape(itemTypes[results.query.typeFilter]) + ")"; + } + + let output = `<div id="search-settings">` + + `<h1 class="search-results-title">Results for ${escape(results.query.userQuery)}` + + `${typeFilter}</h1> in ${crates} </div>`; + if (results.query.error !== null) { + output += `<h3>Query parser error: "${results.query.error}".</h3>`; + } + output += `<div id="titles">` + makeTabHeader(0, "In Names", ret_others[1]) + makeTabHeader(1, "In Parameters", ret_in_args[1]) + makeTabHeader(2, "In Return Types", ret_returned[1]) + "</div>"; - var resultsElem = document.createElement("div"); + const resultsElem = document.createElement("div"); resultsElem.id = "results"; resultsElem.appendChild(ret_others[0]); resultsElem.appendChild(ret_in_args[0]); resultsElem.appendChild(ret_returned[0]); search.innerHTML = output; - let crateSearch = document.getElementById("crate-search"); + const crateSearch = document.getElementById("crate-search"); if (crateSearch) { crateSearch.addEventListener("input", updateCrate); } @@ -1189,35 +1745,13 @@ window.initSearch = function(rawSearchIndex) { // Reset focused elements. searchState.focusedByTab = [null, null, null]; searchState.showResults(search); - var elems = document.getElementById("titles").childNodes; + const elems = document.getElementById("titles").childNodes; elems[0].onclick = function() { printTab(0); }; elems[1].onclick = function() { printTab(1); }; elems[2].onclick = function() { printTab(2); }; printTab(currentTab); } - function execSearch(query, searchWords, filterCrates) { - query = query.raw.trim(); - var results = { - "in_args": [], - "returned": [], - "others": [], - }; - - if (query.length !== 0) { - var tmp = execQuery(getQuery(query), searchWords, filterCrates); - - results.in_args.push(tmp.in_args); - results.returned.push(tmp.returned); - results.others.push(tmp.others); - } - return { - "in_args": results.in_args[0], - "returned": results.returned[0], - "others": results.others[0], - }; - } - /** * Perform a search based on the current state of the search input element * and display the results. @@ -1225,24 +1759,21 @@ window.initSearch = function(rawSearchIndex) { * @param {boolean} [forced] */ function search(e, forced) { - var params = searchState.getQueryStringParams(); - var query = getQuery(searchState.input.value.trim()); + const params = searchState.getQueryStringParams(); + const query = parseQuery(searchState.input.value.trim()); if (e) { e.preventDefault(); } - if (query.query.length === 0) { - return; - } - if (!forced && query.id === currentResults) { - if (query.query.length > 0) { + if (!forced && query.userQuery === currentResults) { + if (query.userQuery.length > 0) { putBackSearch(); } return; } - var filterCrates = getFilterCrates(); + let filterCrates = getFilterCrates(); // In case we have no information about the saved crate and there is a URL query parameter, // we override it with the URL query parameter. @@ -1251,13 +1782,12 @@ window.initSearch = function(rawSearchIndex) { } // Update document title to maintain a meaningful browser history - searchState.title = "Results for " + query.query + " - Rust"; + searchState.title = "Results for " + query.original + " - Rust"; // Because searching is incremental by character, only the most // recent search query is added to the browser history. if (searchState.browserSupportsHistoryApi()) { - var newURL = buildUrl(query.raw, filterCrates); - + const newURL = buildUrl(query.original, filterCrates); if (!history.state && !params.search) { history.pushState(null, "", newURL); } else { @@ -1265,8 +1795,10 @@ window.initSearch = function(rawSearchIndex) { } } - showResults(execSearch(query, searchWords, filterCrates), - params["go_to_first"], filterCrates); + showResults( + execQuery(query, searchWords, filterCrates), + params.go_to_first, + filterCrates); } function buildIndex(rawSearchIndex) { @@ -1274,17 +1806,17 @@ window.initSearch = function(rawSearchIndex) { /** * @type {Array<string>} */ - var searchWords = []; - var i, word; - var currentIndex = 0; - var id = 0; + const searchWords = []; + let i, word; + let currentIndex = 0; + let id = 0; - for (var crate in rawSearchIndex) { + for (const crate in rawSearchIndex) { if (!hasOwnPropertyRustdoc(rawSearchIndex, crate)) { continue; } - var crateSize = 0; + let crateSize = 0; /** * The raw search data for a given crate. `n`, `t`, `d`, and `q`, `i`, and `f` @@ -1316,13 +1848,13 @@ window.initSearch = function(rawSearchIndex) { * p: Array<Object>, * }} */ - var crateCorpus = rawSearchIndex[crate]; + const crateCorpus = rawSearchIndex[crate]; searchWords.push(crate); // This object should have exactly the same set of fields as the "row" // object defined below. Your JavaScript runtime will thank you. // https://mathiasbynens.be/notes/shapes-ics - var crateRow = { + const crateRow = { crate: crate, ty: 1, // == ExternCrate name: crate, @@ -1338,26 +1870,26 @@ window.initSearch = function(rawSearchIndex) { currentIndex += 1; // an array of (Number) item types - var itemTypes = crateCorpus.t; + const itemTypes = crateCorpus.t; // an array of (String) item names - var itemNames = crateCorpus.n; + const itemNames = crateCorpus.n; // an array of (String) full paths (or empty string for previous path) - var itemPaths = crateCorpus.q; + const itemPaths = crateCorpus.q; // an array of (String) descriptions - var itemDescs = crateCorpus.d; + const itemDescs = crateCorpus.d; // an array of (Number) the parent path index + 1 to `paths`, or 0 if none - var itemParentIdxs = crateCorpus.i; + const itemParentIdxs = crateCorpus.i; // an array of (Object | null) the type of the function, if any - var itemFunctionSearchTypes = crateCorpus.f; + const itemFunctionSearchTypes = crateCorpus.f; // an array of [(Number) item type, // (String) name] - var paths = crateCorpus.p; + const paths = crateCorpus.p; // an array of [(String) alias name // [Number] index to items] - var aliases = crateCorpus.a; + const aliases = crateCorpus.a; // convert `rawPaths` entries into object form - var len = paths.length; + let len = paths.length; for (i = 0; i < len; ++i) { paths[i] = {ty: paths[i][0], name: paths[i][1]}; } @@ -1370,7 +1902,7 @@ window.initSearch = function(rawSearchIndex) { // all other search operations have access to this cached data for // faster analysis operations len = itemTypes.length; - var lastPath = ""; + let lastPath = ""; for (i = 0; i < len; ++i) { // This object should have exactly the same set of fields as the "crateRow" // object defined above. @@ -1381,7 +1913,7 @@ window.initSearch = function(rawSearchIndex) { word = ""; searchWords.push(""); } - var row = { + const row = { crate: crate, ty: itemTypes[i], name: itemNames[i], @@ -1400,8 +1932,7 @@ window.initSearch = function(rawSearchIndex) { if (aliases) { ALIASES[crate] = {}; - var j, local_aliases; - for (var alias_name in aliases) { + for (const alias_name in aliases) { if (!hasOwnPropertyRustdoc(aliases, alias_name)) { continue; } @@ -1409,9 +1940,8 @@ window.initSearch = function(rawSearchIndex) { if (!hasOwnPropertyRustdoc(ALIASES[crate], alias_name)) { ALIASES[crate][alias_name] = []; } - local_aliases = aliases[alias_name]; - for (j = 0, len = local_aliases.length; j < len; ++j) { - ALIASES[crate][alias_name].push(local_aliases[j] + currentIndex); + for (const local_alias of aliases[alias_name]) { + ALIASES[crate][alias_name].push(local_alias + currentIndex); } } } @@ -1431,11 +1961,11 @@ window.initSearch = function(rawSearchIndex) { } function putBackSearch() { - var search_input = searchState.input; + const search_input = searchState.input; if (!searchState.input) { return; } - var search = searchState.outputElement(); + const search = searchState.outputElement(); if (search_input.value !== "" && hasClass(search, "hidden")) { searchState.showResults(search); if (searchState.browserSupportsHistoryApi()) { @@ -1447,7 +1977,7 @@ window.initSearch = function(rawSearchIndex) { } function registerSearchEvents() { - var searchAfter500ms = function() { + const searchAfter500ms = function() { searchState.clearInputTimeout(); if (searchState.input.value.length === 0) { if (searchState.browserSupportsHistoryApi()) { @@ -1485,7 +2015,7 @@ window.initSearch = function(rawSearchIndex) { // up and down arrow select next/previous search result, or the // search box if we're already at the top. if (e.which === 38) { // up - var previous = document.activeElement.previousElementSibling; + const previous = document.activeElement.previousElementSibling; if (previous) { previous.focus(); } else { @@ -1493,11 +2023,11 @@ window.initSearch = function(rawSearchIndex) { } e.preventDefault(); } else if (e.which === 40) { // down - var next = document.activeElement.nextElementSibling; + const next = document.activeElement.nextElementSibling; if (next) { next.focus(); } - var rect = document.activeElement.getBoundingClientRect(); + const rect = document.activeElement.getBoundingClientRect(); if (window.innerHeight - rect.bottom < rect.height) { window.scrollBy(0, rect.height); } @@ -1530,10 +2060,10 @@ window.initSearch = function(rawSearchIndex) { // history. if (searchState.browserSupportsHistoryApi()) { // Store the previous <title> so we can revert back to it later. - var previousTitle = document.title; + const previousTitle = document.title; window.addEventListener("popstate", function(e) { - var params = searchState.getQueryStringParams(); + const params = searchState.getQueryStringParams(); // Revert to the previous title manually since the History // API ignores the title parameter. document.title = previousTitle; @@ -1569,7 +2099,7 @@ window.initSearch = function(rawSearchIndex) { // that try to sync state between the URL and the search input. To work around it, // do a small amount of re-init on page show. window.onpageshow = function(){ - var qSearch = searchState.getQueryStringParams().search; + const qSearch = searchState.getQueryStringParams().search; if (searchState.input.value === "" && qSearch) { searchState.input.value = qSearch; } @@ -1580,8 +2110,8 @@ window.initSearch = function(rawSearchIndex) { function updateCrate(ev) { if (ev.target.value === "All crates") { // If we don't remove it from the URL, it'll be picked up again by the search. - var params = searchState.getQueryStringParams(); - var query = searchState.input.value.trim(); + const params = searchState.getQueryStringParams(); + const query = searchState.input.value.trim(); if (!history.state && !params.search) { history.pushState(null, "", buildUrl(query, null)); } else { @@ -1595,7 +2125,10 @@ window.initSearch = function(rawSearchIndex) { search(undefined, true); } - searchWords = buildIndex(rawSearchIndex); + /** + * @type {Array<string>} + */ + const searchWords = buildIndex(rawSearchIndex); registerSearchEvents(); function runSearchIfNeeded() { diff --git a/src/librustdoc/html/static/js/settings.js b/src/librustdoc/html/static/js/settings.js index 139fa5c9a11..7bc6f6cfe04 100644 --- a/src/librustdoc/html/static/js/settings.js +++ b/src/librustdoc/html/static/js/settings.js @@ -1,3 +1,6 @@ +/* eslint-env es6 */ +/* eslint no-var: "error" */ +/* eslint prefer-const: "error" */ // Local js definitions: /* global getSettingValue, getVirtualKey, onEachLazy, updateLocalStorage, updateSystemTheme */ /* global addClass, removeClass */ @@ -55,9 +58,9 @@ function setEvents() { updateLightAndDark(); onEachLazy(document.getElementsByClassName("slider"), function(elem) { - var toggle = elem.previousElementSibling; - var settingId = toggle.id; - var settingValue = getSettingValue(settingId); + const toggle = elem.previousElementSibling; + const settingId = toggle.id; + const settingValue = getSettingValue(settingId); if (settingValue !== null) { toggle.checked = settingValue === "true"; } @@ -68,9 +71,9 @@ toggle.onkeyrelease = handleKey; }); onEachLazy(document.getElementsByClassName("select-wrapper"), function(elem) { - var select = elem.getElementsByTagName("select")[0]; - var settingId = select.id; - var settingValue = getSettingValue(settingId); + const select = elem.getElementsByTagName("select")[0]; + const settingId = select.id; + const settingValue = getSettingValue(settingId); if (settingValue !== null) { select.value = settingValue; } diff --git a/src/librustdoc/html/static/js/source-script.js b/src/librustdoc/html/static/js/source-script.js index aa77e62ba5a..c48a847665e 100644 --- a/src/librustdoc/html/static/js/source-script.js +++ b/src/librustdoc/html/static/js/source-script.js @@ -1,3 +1,7 @@ +/* eslint-env es6 */ +/* eslint no-var: "error" */ +/* eslint prefer-const: "error" */ + // From rust: /* global search, sourcesIndex */ @@ -7,15 +11,15 @@ (function() { function getCurrentFilePath() { - var parts = window.location.pathname.split("/"); - var rootPathParts = window.rootPath.split("/"); + const parts = window.location.pathname.split("/"); + const rootPathParts = window.rootPath.split("/"); - for (var i = 0, len = rootPathParts.length; i < len; ++i) { - if (rootPathParts[i] === "..") { + for (const rootPathPart of rootPathParts) { + if (rootPathPart === "..") { parts.pop(); } } - var file = window.location.pathname.substring(parts.join("/").length); + let file = window.location.pathname.substring(parts.join("/").length); if (file.startsWith("/")) { file = file.substring(1); } @@ -23,7 +27,7 @@ function getCurrentFilePath() { } function createDirEntry(elem, parent, fullPath, currentFile, hasFoundFile) { - var name = document.createElement("div"); + const name = document.createElement("div"); name.className = "name"; fullPath += elem["name"] + "/"; @@ -37,16 +41,13 @@ function createDirEntry(elem, parent, fullPath, currentFile, hasFoundFile) { }; name.innerText = elem["name"]; - var i, len; - - var children = document.createElement("div"); + const children = document.createElement("div"); children.className = "children"; - var folders = document.createElement("div"); + const folders = document.createElement("div"); folders.className = "folders"; if (elem.dirs) { - for (i = 0, len = elem.dirs.length; i < len; ++i) { - if (createDirEntry(elem.dirs[i], folders, fullPath, currentFile, - hasFoundFile)) { + for (const dir of elem.dirs) { + if (createDirEntry(dir, folders, fullPath, currentFile, hasFoundFile)) { addClass(name, "expand"); hasFoundFile = true; } @@ -54,14 +55,14 @@ function createDirEntry(elem, parent, fullPath, currentFile, hasFoundFile) { } children.appendChild(folders); - var files = document.createElement("div"); + const files = document.createElement("div"); files.className = "files"; if (elem.files) { - for (i = 0, len = elem.files.length; i < len; ++i) { - var file = document.createElement("a"); - file.innerText = elem.files[i]; - file.href = window.rootPath + "src/" + fullPath + elem.files[i] + ".html"; - if (!hasFoundFile && currentFile === fullPath + elem.files[i]) { + for (const file_text of elem.files) { + const file = document.createElement("a"); + file.innerText = file_text; + file.href = window.rootPath + "src/" + fullPath + file_text + ".html"; + if (!hasFoundFile && currentFile === fullPath + file_text) { file.className = "selected"; addClass(name, "expand"); hasFoundFile = true; @@ -77,8 +78,8 @@ function createDirEntry(elem, parent, fullPath, currentFile, hasFoundFile) { } function toggleSidebar() { - var sidebar = document.querySelector("nav.sidebar"); - var child = this.children[0]; + const sidebar = document.querySelector("nav.sidebar"); + const child = this.children[0]; if (child.innerText === ">") { sidebar.classList.add("expanded"); child.innerText = "<"; @@ -91,11 +92,11 @@ function toggleSidebar() { } function createSidebarToggle() { - var sidebarToggle = document.createElement("div"); + const sidebarToggle = document.createElement("div"); sidebarToggle.id = "sidebar-toggle"; sidebarToggle.onclick = toggleSidebar; - var inner = document.createElement("div"); + const inner = document.createElement("div"); if (getCurrentValue("source-sidebar-show") === "true") { inner.innerText = "<"; @@ -113,12 +114,12 @@ function createSourceSidebar() { if (!window.rootPath.endsWith("/")) { window.rootPath += "/"; } - var container = document.querySelector("nav.sidebar"); + const container = document.querySelector("nav.sidebar"); - var sidebarToggle = createSidebarToggle(); + const sidebarToggle = createSidebarToggle(); container.insertBefore(sidebarToggle, container.firstChild); - var sidebar = document.createElement("div"); + const sidebar = document.createElement("div"); sidebar.id = "source-sidebar"; if (getCurrentValue("source-sidebar-show") !== "true") { container.classList.remove("expanded"); @@ -126,10 +127,10 @@ function createSourceSidebar() { container.classList.add("expanded"); } - var currentFile = getCurrentFilePath(); - var hasFoundFile = false; + const currentFile = getCurrentFilePath(); + let hasFoundFile = false; - var title = document.createElement("div"); + const title = document.createElement("div"); title.className = "title"; title.innerText = "Files"; sidebar.appendChild(title); @@ -141,13 +142,13 @@ function createSourceSidebar() { container.appendChild(sidebar); // Focus on the current file in the source files sidebar. - var selected_elem = sidebar.getElementsByClassName("selected")[0]; + const selected_elem = sidebar.getElementsByClassName("selected")[0]; if (typeof selected_elem !== "undefined") { selected_elem.focus(); } } -var lineNumbersRegex = /^#?(\d+)(?:-(\d+))?$/; +const lineNumbersRegex = /^#?(\d+)(?:-(\d+))?$/; function highlightSourceLines(match) { if (typeof match === "undefined") { @@ -156,21 +157,21 @@ function highlightSourceLines(match) { if (!match) { return; } - var from = parseInt(match[1], 10); - var to = from; + let from = parseInt(match[1], 10); + let to = from; if (typeof match[2] !== "undefined") { to = parseInt(match[2], 10); } if (to < from) { - var tmp = to; + const tmp = to; to = from; from = tmp; } - var elem = document.getElementById(from); + let elem = document.getElementById(from); if (!elem) { return; } - var x = document.getElementById(from); + const x = document.getElementById(from); if (x) { x.scrollIntoView(); } @@ -179,7 +180,7 @@ function highlightSourceLines(match) { removeClass(i_e, "line-highlighted"); }); }); - for (var i = from; i <= to; ++i) { + for (let i = from; i <= to; ++i) { elem = document.getElementById(i); if (!elem) { break; @@ -188,11 +189,11 @@ function highlightSourceLines(match) { } } -var handleSourceHighlight = (function() { - var prev_line_id = 0; +const handleSourceHighlight = (function() { + let prev_line_id = 0; - var set_fragment = function(name) { - var x = window.scrollX, + const set_fragment = function(name) { + const x = window.scrollX, y = window.scrollY; if (searchState.browserSupportsHistoryApi()) { history.replaceState(null, null, "#" + name); @@ -205,13 +206,13 @@ var handleSourceHighlight = (function() { }; return function(ev) { - var cur_line_id = parseInt(ev.target.id, 10); + let cur_line_id = parseInt(ev.target.id, 10); ev.preventDefault(); if (ev.shiftKey && prev_line_id) { // Swap selection if needed if (prev_line_id > cur_line_id) { - var tmp = prev_line_id; + const tmp = prev_line_id; prev_line_id = cur_line_id; cur_line_id = tmp; } @@ -226,7 +227,7 @@ var handleSourceHighlight = (function() { }()); window.addEventListener("hashchange", function() { - var match = window.location.hash.match(lineNumbersRegex); + const match = window.location.hash.match(lineNumbersRegex); if (match) { return highlightSourceLines(match); } diff --git a/src/librustdoc/html/static/js/storage.js b/src/librustdoc/html/static/js/storage.js index ccf3d0a581a..ae670ed9894 100644 --- a/src/librustdoc/html/static/js/storage.js +++ b/src/librustdoc/html/static/js/storage.js @@ -1,13 +1,17 @@ -var darkThemes = ["dark", "ayu"]; +/* eslint-env es6 */ +/* eslint no-var: "error" */ +/* eslint prefer-const: "error" */ + +const darkThemes = ["dark", "ayu"]; window.currentTheme = document.getElementById("themeStyle"); window.mainTheme = document.getElementById("mainThemeStyle"); -var settingsDataset = (function () { - var settingsElement = document.getElementById("default-settings"); +const settingsDataset = (function () { + const settingsElement = document.getElementById("default-settings"); if (settingsElement === null) { return null; } - var dataset = settingsElement.dataset; + const dataset = settingsElement.dataset; if (dataset === undefined) { return null; } @@ -15,14 +19,14 @@ var settingsDataset = (function () { })(); function getSettingValue(settingName) { - var current = getCurrentValue(settingName); + const current = getCurrentValue(settingName); if (current !== null) { return current; } if (settingsDataset !== null) { // See the comment for `default_settings.into_iter()` etc. in // `Options::from_matches` in `librustdoc/config.rs`. - var def = settingsDataset[settingName.replace(/-/g,'_')]; + const def = settingsDataset[settingName.replace(/-/g,'_')]; if (def !== undefined) { return def; } @@ -30,9 +34,9 @@ function getSettingValue(settingName) { return null; } -var localStoredTheme = getSettingValue("theme"); +const localStoredTheme = getSettingValue("theme"); -var savedHref = []; +const savedHref = []; // eslint-disable-next-line no-unused-vars function hasClass(elem, className) { @@ -63,17 +67,16 @@ function removeClass(elem, className) { */ function onEach(arr, func, reversed) { if (arr && arr.length > 0 && func) { - var length = arr.length; - var i; if (reversed) { - for (i = length - 1; i >= 0; --i) { + const length = arr.length; + for (let i = length - 1; i >= 0; --i) { if (func(arr[i])) { return true; } } } else { - for (i = 0; i < length; ++i) { - if (func(arr[i])) { + for (const elem of arr) { + if (func(elem)) { return true; } } @@ -121,7 +124,7 @@ function getCurrentValue(name) { } function switchTheme(styleElem, mainStyleElem, newTheme, saveTheme) { - var newHref = mainStyleElem.href.replace( + const newHref = mainStyleElem.href.replace( /\/rustdoc([^/]*)\.css/, "/" + newTheme + "$1" + ".css"); // If this new value comes from a system setting or from the previously @@ -134,7 +137,7 @@ function switchTheme(styleElem, mainStyleElem, newTheme, saveTheme) { return; } - var found = false; + let found = false; if (savedHref.length === 0) { onEachLazy(document.getElementsByTagName("link"), function(el) { savedHref.push(el.href); @@ -161,17 +164,17 @@ function useSystemTheme(value) { updateLocalStorage("use-system-theme", value); // update the toggle if we're on the settings page - var toggle = document.getElementById("use-system-theme"); + const toggle = document.getElementById("use-system-theme"); if (toggle && toggle instanceof HTMLInputElement) { toggle.checked = value; } } -var updateSystemTheme = (function() { +const updateSystemTheme = (function() { if (!window.matchMedia) { // fallback to the CSS computed value return function() { - var cssTheme = getComputedStyle(document.documentElement) + const cssTheme = getComputedStyle(document.documentElement) .getPropertyValue('content'); switchTheme( @@ -184,16 +187,16 @@ var updateSystemTheme = (function() { } // only listen to (prefers-color-scheme: dark) because light is the default - var mql = window.matchMedia("(prefers-color-scheme: dark)"); + const mql = window.matchMedia("(prefers-color-scheme: dark)"); function handlePreferenceChange(mql) { - let use = function(theme) { + const use = function(theme) { switchTheme(window.currentTheme, window.mainTheme, theme, true); }; // maybe the user has disabled the setting in the meantime! if (getSettingValue("use-system-theme") !== "false") { - var lightTheme = getSettingValue("preferred-light-theme") || "light"; - var darkTheme = getSettingValue("preferred-dark-theme") || "dark"; + const lightTheme = getSettingValue("preferred-light-theme") || "light"; + const darkTheme = getSettingValue("preferred-dark-theme") || "dark"; if (mql.matches) { use(darkTheme); diff --git a/src/librustdoc/html/static_files.rs b/src/librustdoc/html/static_files.rs index 1837e4a3b65..bec5c083fed 100644 --- a/src/librustdoc/html/static_files.rs +++ b/src/librustdoc/html/static_files.rs @@ -92,17 +92,11 @@ crate mod themes { /// Files related to the Fira Sans font. crate mod fira_sans { - /// The file `FiraSans-Regular.woff`, the Regular variant of the Fira Sans font. - crate static REGULAR: &[u8] = include_bytes!("static/fonts/FiraSans-Regular.woff"); - /// The file `FiraSans-Regular.woff2`, the Regular variant of the Fira Sans font in woff2. - crate static REGULAR2: &[u8] = include_bytes!("static/fonts/FiraSans-Regular.woff2"); - - /// The file `FiraSans-Medium.woff`, the Medium variant of the Fira Sans font. - crate static MEDIUM: &[u8] = include_bytes!("static/fonts/FiraSans-Medium.woff"); + crate static REGULAR: &[u8] = include_bytes!("static/fonts/FiraSans-Regular.woff2"); /// The file `FiraSans-Medium.woff2`, the Medium variant of the Fira Sans font in woff2. - crate static MEDIUM2: &[u8] = include_bytes!("static/fonts/FiraSans-Medium.woff2"); + crate static MEDIUM: &[u8] = include_bytes!("static/fonts/FiraSans-Medium.woff2"); /// The file `FiraSans-LICENSE.txt`, the license text for the Fira Sans font. crate static LICENSE: &[u8] = include_bytes!("static/fonts/FiraSans-LICENSE.txt"); @@ -110,26 +104,17 @@ crate mod fira_sans { /// Files related to the Source Serif 4 font. crate mod source_serif_4 { - /// The file `SourceSerif4-Regular.ttf.woff`, the Regular variant of the Source Serif 4 font. - crate static REGULAR: &[u8] = include_bytes!("static/fonts/SourceSerif4-Regular.ttf.woff"); - /// The file `SourceSerif4-Regular.ttf.woff2`, the Regular variant of the Source Serif 4 font in /// woff2. - crate static REGULAR2: &[u8] = include_bytes!("static/fonts/SourceSerif4-Regular.ttf.woff2"); - - /// The file `SourceSerif4-Bold.ttf.woff`, the Bold variant of the Source Serif 4 font. - crate static BOLD: &[u8] = include_bytes!("static/fonts/SourceSerif4-Bold.ttf.woff"); + crate static REGULAR: &[u8] = include_bytes!("static/fonts/SourceSerif4-Regular.ttf.woff2"); /// The file `SourceSerif4-Bold.ttf.woff2`, the Bold variant of the Source Serif 4 font in /// woff2. - crate static BOLD2: &[u8] = include_bytes!("static/fonts/SourceSerif4-Bold.ttf.woff2"); - - /// The file `SourceSerif4-It.ttf.woff`, the Italic variant of the Source Serif 4 font. - crate static ITALIC: &[u8] = include_bytes!("static/fonts/SourceSerif4-It.ttf.woff"); + crate static BOLD: &[u8] = include_bytes!("static/fonts/SourceSerif4-Bold.ttf.woff2"); /// The file `SourceSerif4-It.ttf.woff2`, the Italic variant of the Source Serif 4 font in /// woff2. - crate static ITALIC2: &[u8] = include_bytes!("static/fonts/SourceSerif4-It.ttf.woff2"); + crate static ITALIC: &[u8] = include_bytes!("static/fonts/SourceSerif4-It.ttf.woff2"); /// The file `SourceSerif4-LICENSE.txt`, the license text for the Source Serif 4 font. crate static LICENSE: &[u8] = include_bytes!("static/fonts/SourceSerif4-LICENSE.md"); @@ -137,27 +122,17 @@ crate mod source_serif_4 { /// Files related to the Source Code Pro font. crate mod source_code_pro { - /// The file `SourceCodePro-Regular.ttf.woff`, the Regular variant of the Source Code Pro font. - crate static REGULAR: &[u8] = include_bytes!("static/fonts/SourceCodePro-Regular.ttf.woff"); - /// The file `SourceCodePro-Regular.ttf.woff2`, the Regular variant of the Source Code Pro font /// in woff2. - crate static REGULAR2: &[u8] = include_bytes!("static/fonts/SourceCodePro-Regular.ttf.woff2"); - - /// The file `SourceCodePro-Semibold.ttf.woff`, the Semibold variant of the Source Code Pro - /// font. - crate static SEMIBOLD: &[u8] = include_bytes!("static/fonts/SourceCodePro-Semibold.ttf.woff"); + crate static REGULAR: &[u8] = include_bytes!("static/fonts/SourceCodePro-Regular.ttf.woff2"); /// The file `SourceCodePro-Semibold.ttf.woff2`, the Semibold variant of the Source Code Pro /// font in woff2. - crate static SEMIBOLD2: &[u8] = include_bytes!("static/fonts/SourceCodePro-Semibold.ttf.woff2"); - - /// The file `SourceCodePro-It.ttf.woff`, the Italic variant of the Source Code Pro font. - crate static ITALIC: &[u8] = include_bytes!("static/fonts/SourceCodePro-It.ttf.woff"); + crate static SEMIBOLD: &[u8] = include_bytes!("static/fonts/SourceCodePro-Semibold.ttf.woff2"); /// The file `SourceCodePro-It.ttf.woff2`, the Italic variant of the Source Code Pro font in /// woff2. - crate static ITALIC2: &[u8] = include_bytes!("static/fonts/SourceCodePro-It.ttf.woff2"); + crate static ITALIC: &[u8] = include_bytes!("static/fonts/SourceCodePro-It.ttf.woff2"); /// The file `SourceCodePro-LICENSE.txt`, the license text of the Source Code Pro font. crate static LICENSE: &[u8] = include_bytes!("static/fonts/SourceCodePro-LICENSE.txt"); @@ -176,19 +151,11 @@ crate mod source_code_pro { /// ```sh /// pyftsubset NanumBarunGothic.ttf \ /// --unicodes=U+AC00-D7AF,U+1100-11FF,U+3130-318F,U+A960-A97F,U+D7B0-D7FF \ -/// --output-file=NanumBarunGothic.ttf.woff --flavor=woff -/// ``` -/// ```sh -/// pyftsubset NanumBarunGothic.ttf \ -/// --unicodes=U+AC00-D7AF,U+1100-11FF,U+3130-318F,U+A960-A97F,U+D7B0-D7FF \ /// --output-file=NanumBarunGothic.ttf.woff2 --flavor=woff2 /// ``` crate mod nanum_barun_gothic { - /// The file `NanumBarunGothic.ttf.woff`, the Regular variant of the Nanum Barun Gothic font. - crate static REGULAR: &[u8] = include_bytes!("static/fonts/NanumBarunGothic.ttf.woff"); - /// The file `NanumBarunGothic.ttf.woff2`, the Regular variant of the Nanum Barun Gothic font. - crate static REGULAR2: &[u8] = include_bytes!("static/fonts/NanumBarunGothic.ttf.woff2"); + crate static REGULAR: &[u8] = include_bytes!("static/fonts/NanumBarunGothic.ttf.woff2"); /// The file `NanumBarunGothic-LICENSE.txt`, the license text of the Nanum Barun Gothic font. crate static LICENSE: &[u8] = include_bytes!("static/fonts/NanumBarunGothic-LICENSE.txt"); diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index 0fcfabba4c0..cd196a01847 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -795,6 +795,7 @@ fn main_options(options: config::Options) -> MainResult { let resolver_caches = resolver.borrow_mut().access(|resolver| { collect_intra_doc_links::early_resolve_intra_doc_links( resolver, + sess, krate, externs, document_private, diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index c48f8bd0c7c..84512fab269 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -3,6 +3,7 @@ //! [RFC 1946]: https://github.com/rust-lang/rfcs/blob/master/text/1946-intra-rustdoc-links.md use pulldown_cmark::LinkType; +use rustc_ast::util::comments::may_have_doc_links; use rustc_data_structures::{fx::FxHashMap, intern::Interned, stable_set::FxHashSet}; use rustc_errors::{Applicability, Diagnostic}; use rustc_hir::def::Namespace::*; @@ -11,6 +12,7 @@ use rustc_hir::def_id::{DefId, CRATE_DEF_ID}; use rustc_hir::Mutability; use rustc_middle::ty::{DefIdTree, Ty, TyCtxt}; use rustc_middle::{bug, span_bug, ty}; +use rustc_resolve::ParentScope; use rustc_session::lint::Lint; use rustc_span::hygiene::MacroKind; use rustc_span::symbol::{sym, Ident, Symbol}; @@ -159,7 +161,7 @@ impl TryFrom<ResolveRes> for Res { } /// A link failed to resolve. -#[derive(Debug)] +#[derive(Clone, Debug)] enum ResolutionFailure<'a> { /// This resolved, but with the wrong namespace. WrongNamespace { @@ -199,7 +201,7 @@ enum ResolutionFailure<'a> { Dummy, } -#[derive(Debug)] +#[derive(Clone, Debug)] enum MalformedGenerics { /// This link has unbalanced angle brackets. /// @@ -252,6 +254,7 @@ impl ResolutionFailure<'_> { } } +#[derive(Clone, Copy)] enum AnchorFailure { /// User error: `[std#x#y]` is not valid MultipleAnchors, @@ -556,7 +559,17 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> { // Resolver doesn't know about true, false, and types that aren't paths (e.g. `()`). let result = self .cx - .enter_resolver(|resolver| resolver.resolve_rustdoc_path(path_str, ns, module_id)) + .resolver_caches + .doc_link_resolutions + .get(&(Symbol::intern(path_str), ns, module_id)) + .copied() + .unwrap_or_else(|| { + self.cx.enter_resolver(|resolver| { + let parent_scope = + ParentScope::module(resolver.expect_module(module_id), resolver); + resolver.resolve_rustdoc_path(path_str, ns, parent_scope) + }) + }) .and_then(|res| res.try_into().ok()) .or_else(|| resolve_primitive(path_str, ns)) .or_else(|| self.resolve_macro_rules(path_str, ns)); @@ -1040,17 +1053,30 @@ impl<'a, 'tcx> DocVisitor for LinkCollector<'a, 'tcx> { // In the presence of re-exports, this is not the same as the module of the item. // Rather than merging all documentation into one, resolve it one attribute at a time // so we know which module it came from. - for (parent_module, doc) in item.attrs.collapsed_doc_value_by_module_level() { + for (parent_module, doc) in item.attrs.prepare_to_doc_link_resolution() { + if !may_have_doc_links(&doc) { + continue; + } debug!("combined_docs={}", doc); // NOTE: if there are links that start in one crate and end in another, this will not resolve them. // This is a degenerate case and it's not supported by rustdoc. let parent_node = parent_module.or(parent_node); - for md_link in markdown_links(&doc) { + let mut tmp_links = self + .cx + .resolver_caches + .markdown_links + .take() + .expect("`markdown_links` are already borrowed"); + if !tmp_links.contains_key(&doc) { + tmp_links.insert(doc.clone(), preprocessed_markdown_links(&doc)); + } + for md_link in &tmp_links[&doc] { let link = self.resolve_link(&item, &doc, parent_node, md_link); if let Some(link) = link { self.cx.cache.intra_doc_links.entry(item.item_id).or_default().push(link); } } + self.cx.resolver_caches.markdown_links = Some(tmp_links); } if item.is_mod() { @@ -1066,18 +1092,19 @@ impl<'a, 'tcx> DocVisitor for LinkCollector<'a, 'tcx> { } } -enum PreprocessingError<'a> { +enum PreprocessingError { Anchor(AnchorFailure), Disambiguator(Range<usize>, String), - Resolution(ResolutionFailure<'a>, String, Option<Disambiguator>), + Resolution(ResolutionFailure<'static>, String, Option<Disambiguator>), } -impl From<AnchorFailure> for PreprocessingError<'_> { +impl From<AnchorFailure> for PreprocessingError { fn from(err: AnchorFailure) -> Self { Self::Anchor(err) } } +#[derive(Clone)] struct PreprocessingInfo { path_str: String, disambiguator: Option<Disambiguator>, @@ -1085,15 +1112,18 @@ struct PreprocessingInfo { link_text: String, } +// Not a typedef to avoid leaking several private structures from this module. +crate struct PreprocessedMarkdownLink(Result<PreprocessingInfo, PreprocessingError>, MarkdownLink); + /// Returns: /// - `None` if the link should be ignored. /// - `Some(Err)` if the link should emit an error /// - `Some(Ok)` if the link is valid /// /// `link_buffer` is needed for lifetime reasons; it will always be overwritten and the contents ignored. -fn preprocess_link<'a>( - ori_link: &'a MarkdownLink, -) -> Option<Result<PreprocessingInfo, PreprocessingError<'a>>> { +fn preprocess_link( + ori_link: &MarkdownLink, +) -> Option<Result<PreprocessingInfo, PreprocessingError>> { // [] is mostly likely not supposed to be a link if ori_link.link.is_empty() { return None; @@ -1172,6 +1202,12 @@ fn preprocess_link<'a>( })) } +fn preprocessed_markdown_links(s: &str) -> Vec<PreprocessedMarkdownLink> { + markdown_links(s, |link| { + preprocess_link(&link).map(|pp_link| PreprocessedMarkdownLink(pp_link, link)) + }) +} + impl LinkCollector<'_, '_> { /// This is the entry point for resolving an intra-doc link. /// @@ -1181,8 +1217,9 @@ impl LinkCollector<'_, '_> { item: &Item, dox: &str, parent_node: Option<DefId>, - ori_link: MarkdownLink, + link: &PreprocessedMarkdownLink, ) -> Option<ItemLink> { + let PreprocessedMarkdownLink(pp_link, ori_link) = link; trace!("considering link '{}'", ori_link.link); let diag_info = DiagnosticInfo { @@ -1192,28 +1229,29 @@ impl LinkCollector<'_, '_> { link_range: ori_link.range.clone(), }; - let PreprocessingInfo { ref path_str, disambiguator, extra_fragment, link_text } = - match preprocess_link(&ori_link)? { - Ok(x) => x, - Err(err) => { - match err { - PreprocessingError::Anchor(err) => anchor_failure(self.cx, diag_info, err), - PreprocessingError::Disambiguator(range, msg) => { - disambiguator_error(self.cx, diag_info, range, &msg) - } - PreprocessingError::Resolution(err, path_str, disambiguator) => { - resolution_failure( - self, - diag_info, - &path_str, - disambiguator, - smallvec![err], - ); - } + let PreprocessingInfo { path_str, disambiguator, extra_fragment, link_text } = match pp_link + { + Ok(x) => x, + Err(err) => { + match err { + PreprocessingError::Anchor(err) => anchor_failure(self.cx, diag_info, *err), + PreprocessingError::Disambiguator(range, msg) => { + disambiguator_error(self.cx, diag_info, range.clone(), msg) + } + PreprocessingError::Resolution(err, path_str, disambiguator) => { + resolution_failure( + self, + diag_info, + path_str, + *disambiguator, + smallvec![err.clone()], + ); } - return None; } - }; + return None; + } + }; + let disambiguator = *disambiguator; let inner_docs = item.inner_docs(self.cx.tcx); @@ -1250,7 +1288,7 @@ impl LinkCollector<'_, '_> { module_id, dis: disambiguator, path_str: path_str.to_owned(), - extra_fragment, + extra_fragment: extra_fragment.clone(), }, diag_info.clone(), // this struct should really be Copy, but Range is not :( matches!(ori_link.kind, LinkType::Reference | LinkType::Shortcut), @@ -1320,8 +1358,8 @@ impl LinkCollector<'_, '_> { } Some(ItemLink { - link: ori_link.link, - link_text, + link: ori_link.link.clone(), + link_text: link_text.clone(), did: res.def_id(self.cx.tcx), fragment, }) @@ -1343,7 +1381,12 @@ impl LinkCollector<'_, '_> { &diag_info, )?; let id = clean::register_res(self.cx, rustc_hir::def::Res::Def(kind, id)); - Some(ItemLink { link: ori_link.link, link_text, did: id, fragment }) + Some(ItemLink { + link: ori_link.link.clone(), + link_text: link_text.clone(), + did: id, + fragment, + }) } } } diff --git a/src/librustdoc/passes/collect_intra_doc_links/early.rs b/src/librustdoc/passes/collect_intra_doc_links/early.rs index dffceff045d..3858c1cb056 100644 --- a/src/librustdoc/passes/collect_intra_doc_links/early.rs +++ b/src/librustdoc/passes/collect_intra_doc_links/early.rs @@ -1,33 +1,42 @@ use crate::clean::Attributes; use crate::core::ResolverCaches; -use crate::html::markdown::markdown_links; -use crate::passes::collect_intra_doc_links::preprocess_link; +use crate::passes::collect_intra_doc_links::preprocessed_markdown_links; +use crate::passes::collect_intra_doc_links::{Disambiguator, PreprocessedMarkdownLink}; use rustc_ast::visit::{self, AssocCtxt, Visitor}; use rustc_ast::{self as ast, ItemKind}; use rustc_ast_lowering::ResolverAstLowering; -use rustc_hir::def::Namespace::TypeNS; -use rustc_hir::def::{DefKind, Res}; -use rustc_hir::def_id::{DefId, DefIdMap, DefIdSet, LocalDefId, CRATE_DEF_ID}; +use rustc_data_structures::fx::FxHashMap; +use rustc_hir::def::Namespace::*; +use rustc_hir::def::{DefKind, Namespace, Res}; +use rustc_hir::def_id::{DefId, DefIdMap, DefIdSet, CRATE_DEF_ID}; use rustc_hir::TraitCandidate; use rustc_middle::ty::{DefIdTree, Visibility}; use rustc_resolve::{ParentScope, Resolver}; use rustc_session::config::Externs; -use rustc_span::SyntaxContext; +use rustc_session::Session; +use rustc_span::symbol::sym; +use rustc_span::{Symbol, SyntaxContext}; use std::collections::hash_map::Entry; use std::mem; crate fn early_resolve_intra_doc_links( resolver: &mut Resolver<'_>, + sess: &Session, krate: &ast::Crate, externs: Externs, document_private_items: bool, ) -> ResolverCaches { + let parent_scope = + ParentScope::module(resolver.expect_module(CRATE_DEF_ID.to_def_id()), resolver); let mut link_resolver = EarlyDocLinkResolver { resolver, - current_mod: CRATE_DEF_ID, + sess, + parent_scope, visited_mods: Default::default(), + markdown_links: Default::default(), + doc_link_resolutions: Default::default(), traits_in_scope: Default::default(), all_traits: Default::default(), all_trait_impls: Default::default(), @@ -36,7 +45,7 @@ crate fn early_resolve_intra_doc_links( // Overridden `visit_item` below doesn't apply to the crate root, // so we have to visit its attributes and reexports separately. - link_resolver.load_links_in_attrs(&krate.attrs); + link_resolver.resolve_doc_links_local(&krate.attrs); link_resolver.process_module_children_or_reexports(CRATE_DEF_ID.to_def_id()); visit::walk_crate(&mut link_resolver, krate); link_resolver.process_extern_impls(); @@ -46,10 +55,12 @@ crate fn early_resolve_intra_doc_links( // DO NOT REMOVE THIS without first testing on the reproducer in // https://github.com/jyn514/objr/commit/edcee7b8124abf0e4c63873e8422ff81beb11ebb for (extern_name, _) in externs.iter().filter(|(_, entry)| entry.add_prelude) { - link_resolver.resolver.resolve_rustdoc_path(extern_name, TypeNS, CRATE_DEF_ID.to_def_id()); + link_resolver.resolver.resolve_rustdoc_path(extern_name, TypeNS, parent_scope); } ResolverCaches { + markdown_links: Some(link_resolver.markdown_links), + doc_link_resolutions: link_resolver.doc_link_resolutions, traits_in_scope: link_resolver.traits_in_scope, all_traits: Some(link_resolver.all_traits), all_trait_impls: Some(link_resolver.all_trait_impls), @@ -57,17 +68,24 @@ crate fn early_resolve_intra_doc_links( } } +fn doc_attrs<'a>(attrs: impl Iterator<Item = &'a ast::Attribute>) -> Attributes { + Attributes::from_ast_iter(attrs.map(|attr| (attr, None)), true) +} + struct EarlyDocLinkResolver<'r, 'ra> { resolver: &'r mut Resolver<'ra>, - current_mod: LocalDefId, + sess: &'r Session, + parent_scope: ParentScope<'ra>, visited_mods: DefIdSet, + markdown_links: FxHashMap<String, Vec<PreprocessedMarkdownLink>>, + doc_link_resolutions: FxHashMap<(Symbol, Namespace, DefId), Option<Res<ast::NodeId>>>, traits_in_scope: DefIdMap<Vec<TraitCandidate>>, all_traits: Vec<DefId>, all_trait_impls: Vec<DefId>, document_private_items: bool, } -impl EarlyDocLinkResolver<'_, '_> { +impl<'ra> EarlyDocLinkResolver<'_, 'ra> { fn add_traits_in_scope(&mut self, def_id: DefId) { // Calls to `traits_in_scope` are expensive, so try to avoid them if only possible. // Keys in the `traits_in_scope` cache are always module IDs. @@ -92,18 +110,11 @@ impl EarlyDocLinkResolver<'_, '_> { } } - fn add_traits_in_parent_scope(&mut self, def_id: DefId) { - if let Some(module_id) = self.resolver.parent(def_id) { - self.add_traits_in_scope(module_id); - } - } - /// Add traits in scope for links in impls collected by the `collect-intra-doc-links` pass. /// That pass filters impls using type-based information, but we don't yet have such /// information here, so we just conservatively calculate traits in scope for *all* modules /// having impls in them. fn process_extern_impls(&mut self) { - // FIXME: Need to resolve doc links on all these impl and trait items below. // Resolving links in already existing crates may trigger loading of new crates. let mut start_cnum = 0; loop { @@ -124,7 +135,7 @@ impl EarlyDocLinkResolver<'_, '_> { // the current crate, and links in their doc comments are not resolved. for &def_id in &all_traits { if self.resolver.cstore().visibility_untracked(def_id) == Visibility::Public { - self.add_traits_in_parent_scope(def_id); + self.resolve_doc_links_extern_impl(def_id, false); } } for &(trait_def_id, impl_def_id, simplified_self_ty) in &all_trait_impls { @@ -135,17 +146,17 @@ impl EarlyDocLinkResolver<'_, '_> { == Visibility::Public }) { - self.add_traits_in_parent_scope(impl_def_id); + self.resolve_doc_links_extern_impl(impl_def_id, false); } } for (ty_def_id, impl_def_id) in all_inherent_impls { if self.resolver.cstore().visibility_untracked(ty_def_id) == Visibility::Public { - self.add_traits_in_parent_scope(impl_def_id); + self.resolve_doc_links_extern_impl(impl_def_id, true); } } - for def_id in all_incoherent_impls { - self.add_traits_in_parent_scope(def_id); + for impl_def_id in all_incoherent_impls { + self.resolve_doc_links_extern_impl(impl_def_id, true); } self.all_traits.extend(all_traits); @@ -161,23 +172,100 @@ impl EarlyDocLinkResolver<'_, '_> { } } - fn load_links_in_attrs(&mut self, attrs: &[ast::Attribute]) { - let module_id = self.current_mod.to_def_id(); + fn resolve_doc_links_extern_impl(&mut self, def_id: DefId, is_inherent: bool) { + self.resolve_doc_links_extern_outer(def_id, def_id); + let assoc_item_def_ids = Vec::from_iter( + self.resolver.cstore().associated_item_def_ids_untracked(def_id, self.sess), + ); + for assoc_def_id in assoc_item_def_ids { + if !is_inherent + || self.resolver.cstore().visibility_untracked(assoc_def_id) == Visibility::Public + { + self.resolve_doc_links_extern_outer(assoc_def_id, def_id); + } + } + } + + fn resolve_doc_links_extern_outer(&mut self, def_id: DefId, scope_id: DefId) { + if !self.resolver.cstore().may_have_doc_links_untracked(def_id) { + return; + } + // FIXME: actually resolve links, not just add traits in scope. + if let Some(parent_id) = self.resolver.parent(scope_id) { + self.add_traits_in_scope(parent_id); + } + } + + fn resolve_doc_links_extern_inner(&mut self, def_id: DefId) { + if !self.resolver.cstore().may_have_doc_links_untracked(def_id) { + return; + } + // FIXME: actually resolve links, not just add traits in scope. + self.add_traits_in_scope(def_id); + } + + fn resolve_doc_links_local(&mut self, attrs: &[ast::Attribute]) { + if !attrs.iter().any(|attr| attr.may_have_doc_links()) { + return; + } + self.resolve_doc_links(doc_attrs(attrs.iter()), self.parent_scope); + } + + fn resolve_and_cache( + &mut self, + path_str: &str, + ns: Namespace, + parent_scope: &ParentScope<'ra>, + ) -> bool { + // FIXME: This caching may be incorrect in case of multiple `macro_rules` + // items with the same name in the same module. + self.doc_link_resolutions + .entry((Symbol::intern(path_str), ns, parent_scope.module.def_id())) + .or_insert_with_key(|(path, ns, _)| { + self.resolver.resolve_rustdoc_path(path.as_str(), *ns, *parent_scope) + }) + .is_some() + } + + fn resolve_doc_links(&mut self, attrs: Attributes, parent_scope: ParentScope<'ra>) { let mut need_traits_in_scope = false; - for (doc_module, doc) in - Attributes::from_ast(attrs, None).collapsed_doc_value_by_module_level() - { + for (doc_module, doc) in attrs.prepare_to_doc_link_resolution() { assert_eq!(doc_module, None); - for link in markdown_links(&doc.as_str()) { - if let Some(Ok(pinfo)) = preprocess_link(&link) { - self.resolver.resolve_rustdoc_path(&pinfo.path_str, TypeNS, module_id); - need_traits_in_scope = true; + let mut tmp_links = mem::take(&mut self.markdown_links); + let links = + tmp_links.entry(doc).or_insert_with_key(|doc| preprocessed_markdown_links(doc)); + for PreprocessedMarkdownLink(pp_link, _) in links { + if let Ok(pinfo) = pp_link { + // The logic here is a conservative approximation for path resolution in + // `resolve_with_disambiguator`. + if let Some(ns) = pinfo.disambiguator.map(Disambiguator::ns) { + if self.resolve_and_cache(&pinfo.path_str, ns, &parent_scope) { + continue; + } + } + + // Resolve all namespaces due to no disambiguator or for diagnostics. + let mut any_resolved = false; + let mut need_assoc = false; + for ns in [TypeNS, ValueNS, MacroNS] { + if self.resolve_and_cache(&pinfo.path_str, ns, &parent_scope) { + any_resolved = true; + } else if ns != MacroNS { + need_assoc = true; + } + } + + // FIXME: Resolve all prefixes for type-relative resolution or for diagnostics. + if (need_assoc || !any_resolved) && pinfo.path_str.contains("::") { + need_traits_in_scope = true; + } } } + self.markdown_links = tmp_links; } if need_traits_in_scope { - self.add_traits_in_scope(module_id); + self.add_traits_in_scope(parent_scope.module.def_id()); } } @@ -197,15 +285,13 @@ impl EarlyDocLinkResolver<'_, '_> { && module_id.is_local() { if let Some(def_id) = child.res.opt_def_id() && !def_id.is_local() { - // FIXME: Need to resolve doc links on all these extern items - // reached through reexports. let scope_id = match child.res { Res::Def(DefKind::Variant, ..) => self.resolver.parent(def_id).unwrap(), _ => def_id, }; - self.add_traits_in_parent_scope(scope_id); // Outer attribute scope + self.resolve_doc_links_extern_outer(def_id, scope_id); // Outer attribute scope if let Res::Def(DefKind::Mod, ..) = child.res { - self.add_traits_in_scope(def_id); // Inner attribute scope + self.resolve_doc_links_extern_inner(def_id); // Inner attribute scope } // Traits are processed in `add_extern_traits_in_scope`. if let Res::Def(DefKind::Mod | DefKind::Enum, ..) = child.res { @@ -219,21 +305,35 @@ impl EarlyDocLinkResolver<'_, '_> { impl Visitor<'_> for EarlyDocLinkResolver<'_, '_> { fn visit_item(&mut self, item: &ast::Item) { - self.load_links_in_attrs(&item.attrs); // Outer attribute scope + self.resolve_doc_links_local(&item.attrs); // Outer attribute scope if let ItemKind::Mod(..) = item.kind { - let old_mod = mem::replace(&mut self.current_mod, self.resolver.local_def_id(item.id)); - self.load_links_in_attrs(&item.attrs); // Inner attribute scope - self.process_module_children_or_reexports(self.current_mod.to_def_id()); + let module_def_id = self.resolver.local_def_id(item.id).to_def_id(); + let module = self.resolver.expect_module(module_def_id); + let old_module = mem::replace(&mut self.parent_scope.module, module); + let old_macro_rules = self.parent_scope.macro_rules; + self.resolve_doc_links_local(&item.attrs); // Inner attribute scope + self.process_module_children_or_reexports(module_def_id); visit::walk_item(self, item); - self.current_mod = old_mod; + if item + .attrs + .iter() + .all(|attr| !attr.has_name(sym::macro_use) && !attr.has_name(sym::macro_escape)) + { + self.parent_scope.macro_rules = old_macro_rules; + } + self.parent_scope.module = old_module; } else { - match item.kind { + match &item.kind { ItemKind::Trait(..) => { self.all_traits.push(self.resolver.local_def_id(item.id).to_def_id()); } ItemKind::Impl(box ast::Impl { of_trait: Some(..), .. }) => { self.all_trait_impls.push(self.resolver.local_def_id(item.id).to_def_id()); } + ItemKind::MacroDef(macro_def) if macro_def.macro_rules => { + self.parent_scope.macro_rules = + self.resolver.macro_rules_scope(self.resolver.local_def_id(item.id)); + } _ => {} } visit::walk_item(self, item); @@ -241,25 +341,31 @@ impl Visitor<'_> for EarlyDocLinkResolver<'_, '_> { } fn visit_assoc_item(&mut self, item: &ast::AssocItem, ctxt: AssocCtxt) { - self.load_links_in_attrs(&item.attrs); + self.resolve_doc_links_local(&item.attrs); visit::walk_assoc_item(self, item, ctxt) } fn visit_foreign_item(&mut self, item: &ast::ForeignItem) { - self.load_links_in_attrs(&item.attrs); + self.resolve_doc_links_local(&item.attrs); visit::walk_foreign_item(self, item) } fn visit_variant(&mut self, v: &ast::Variant) { - self.load_links_in_attrs(&v.attrs); + self.resolve_doc_links_local(&v.attrs); visit::walk_variant(self, v) } fn visit_field_def(&mut self, field: &ast::FieldDef) { - self.load_links_in_attrs(&field.attrs); + self.resolve_doc_links_local(&field.attrs); visit::walk_field_def(self, field) } + fn visit_block(&mut self, block: &ast::Block) { + let old_macro_rules = self.parent_scope.macro_rules; + visit::walk_block(self, block); + self.parent_scope.macro_rules = old_macro_rules; + } + // NOTE: if doc-comments are ever allowed on other nodes (e.g. function parameters), // then this will have to implement other visitor methods too. } diff --git a/src/librustdoc/passes/collect_trait_impls.rs b/src/librustdoc/passes/collect_trait_impls.rs index 65459913eea..9644e3d15fd 100644 --- a/src/librustdoc/passes/collect_trait_impls.rs +++ b/src/librustdoc/passes/collect_trait_impls.rs @@ -33,26 +33,60 @@ crate fn collect_trait_impls(mut krate: Crate, cx: &mut DocContext<'_>) -> Crate coll.items }; - let mut new_items = Vec::new(); + let mut new_items_external = Vec::new(); + let mut new_items_local = Vec::new(); // External trait impls. cx.with_all_trait_impls(|cx, all_trait_impls| { let _prof_timer = cx.tcx.sess.prof.generic_activity("build_extern_trait_impls"); for &impl_def_id in all_trait_impls.iter().skip_while(|def_id| def_id.is_local()) { - inline::build_impl(cx, None, impl_def_id, None, &mut new_items); + inline::build_impl(cx, None, impl_def_id, None, &mut new_items_external); + } + }); + + // Local trait impls. + cx.with_all_trait_impls(|cx, all_trait_impls| { + let _prof_timer = cx.tcx.sess.prof.generic_activity("build_local_trait_impls"); + let mut attr_buf = Vec::new(); + for &impl_def_id in all_trait_impls.iter().take_while(|def_id| def_id.is_local()) { + let mut parent = cx.tcx.parent(impl_def_id); + while let Some(did) = parent { + attr_buf.extend( + cx.tcx + .get_attrs(did) + .iter() + .filter(|attr| attr.has_name(sym::doc)) + .filter(|attr| { + if let Some([attr]) = attr.meta_item_list().as_deref() { + attr.has_name(sym::cfg) + } else { + false + } + }) + .cloned(), + ); + parent = cx.tcx.parent(did); + } + inline::build_impl(cx, None, impl_def_id, Some(&attr_buf), &mut new_items_local); + attr_buf.clear(); } }); - // Also try to inline primitive impls from other crates. cx.tcx.sess.prof.generic_activity("build_primitive_trait_impls").run(|| { for def_id in PrimitiveType::all_impls(cx.tcx) { + // Try to inline primitive impls from other crates. if !def_id.is_local() { - inline::build_impl(cx, None, def_id, None, &mut new_items); - - // FIXME(eddyb) is this `doc(hidden)` check needed? - if !cx.tcx.is_doc_hidden(def_id) { + inline::build_impl(cx, None, def_id, None, &mut new_items_external); + } + } + for (prim, did) in PrimitiveType::primitive_locations(cx.tcx) { + // Do not calculate blanket impl list for docs that are not going to be rendered. + // While the `impl` blocks themselves are only in `libcore`, the module with `doc` + // attached is directly included in `libstd` as well. + if did.is_local() { + for def_id in prim.impls(cx.tcx) { let impls = get_auto_trait_and_blanket_impls(cx, def_id); - new_items.extend(impls.filter(|i| cx.inlined.insert(i.item_id))); + new_items_external.extend(impls.filter(|i| cx.inlined.insert(i.item_id))); } } } @@ -66,6 +100,7 @@ crate fn collect_trait_impls(mut krate: Crate, cx: &mut DocContext<'_>) -> Crate cx: &DocContext<'_>, map: &FxHashMap<DefId, &Type>, cleaner: &mut BadImplStripper<'_>, + targets: &mut FxHashSet<DefId>, type_did: DefId, ) { if let Some(target) = map.get(&type_did) { @@ -74,18 +109,18 @@ crate fn collect_trait_impls(mut krate: Crate, cx: &mut DocContext<'_>) -> Crate cleaner.prims.insert(target_prim); } else if let Some(target_did) = target.def_id(&cx.cache) { // `impl Deref<Target = S> for S` - if target_did == type_did { + if !targets.insert(target_did) { // Avoid infinite cycles return; } cleaner.items.insert(target_did.into()); - add_deref_target(cx, map, cleaner, target_did); + add_deref_target(cx, map, cleaner, targets, target_did); } } } // scan through included items ahead of time to splice in Deref targets to the "valid" sets - for it in &new_items { + for it in new_items_external.iter().chain(new_items_local.iter()) { if let ImplItem(Impl { ref for_, ref trait_, ref items, .. }) = *it.kind { if trait_.as_ref().map(|t| t.def_id()) == cx.tcx.lang_items().deref_trait() && cleaner.keep_impl(for_, true) @@ -109,7 +144,15 @@ crate fn collect_trait_impls(mut krate: Crate, cx: &mut DocContext<'_>) -> Crate // `Deref` target type and the impl for type positions, this map of types is keyed by // `DefId` and for convenience uses a special cleaner that accepts `DefId`s directly. if cleaner.keep_impl_with_def_id(for_did.into()) { - add_deref_target(cx, &type_did_to_deref_target, &mut cleaner, for_did); + let mut targets = FxHashSet::default(); + targets.insert(for_did); + add_deref_target( + cx, + &type_did_to_deref_target, + &mut cleaner, + &mut targets, + for_did, + ); } } } @@ -117,7 +160,8 @@ crate fn collect_trait_impls(mut krate: Crate, cx: &mut DocContext<'_>) -> Crate } } - new_items.retain(|it| { + // Filter out external items that are not needed + new_items_external.retain(|it| { if let ImplItem(Impl { ref for_, ref trait_, ref kind, .. }) = *it.kind { cleaner.keep_impl( for_, @@ -129,37 +173,10 @@ crate fn collect_trait_impls(mut krate: Crate, cx: &mut DocContext<'_>) -> Crate } }); - // Local trait impls. - cx.with_all_trait_impls(|cx, all_trait_impls| { - let _prof_timer = cx.tcx.sess.prof.generic_activity("build_local_trait_impls"); - let mut attr_buf = Vec::new(); - for &impl_def_id in all_trait_impls.iter().take_while(|def_id| def_id.is_local()) { - let mut parent = cx.tcx.parent(impl_def_id); - while let Some(did) = parent { - attr_buf.extend( - cx.tcx - .get_attrs(did) - .iter() - .filter(|attr| attr.has_name(sym::doc)) - .filter(|attr| { - if let Some([attr]) = attr.meta_item_list().as_deref() { - attr.has_name(sym::cfg) - } else { - false - } - }) - .cloned(), - ); - parent = cx.tcx.parent(did); - } - inline::build_impl(cx, None, impl_def_id, Some(&attr_buf), &mut new_items); - attr_buf.clear(); - } - }); - if let ModuleItem(Module { items, .. }) = &mut *krate.module.kind { items.extend(synth_impls); - items.extend(new_items); + items.extend(new_items_external); + items.extend(new_items_local); } else { panic!("collect-trait-impls can't run"); }; diff --git a/src/librustdoc/passes/mod.rs b/src/librustdoc/passes/mod.rs index 5db2d0747c8..97a436c7500 100644 --- a/src/librustdoc/passes/mod.rs +++ b/src/librustdoc/passes/mod.rs @@ -24,9 +24,6 @@ crate use self::strip_private::STRIP_PRIVATE; mod strip_priv_imports; crate use self::strip_priv_imports::STRIP_PRIV_IMPORTS; -mod unindent_comments; -crate use self::unindent_comments::UNINDENT_COMMENTS; - mod propagate_doc_cfg; crate use self::propagate_doc_cfg::PROPAGATE_DOC_CFG; @@ -81,7 +78,6 @@ crate enum Condition { crate const PASSES: &[Pass] = &[ CHECK_DOC_TEST_VISIBILITY, STRIP_HIDDEN, - UNINDENT_COMMENTS, STRIP_PRIVATE, STRIP_PRIV_IMPORTS, PROPAGATE_DOC_CFG, @@ -96,7 +92,6 @@ crate const PASSES: &[Pass] = &[ /// The list of passes run by default. crate const DEFAULT_PASSES: &[ConditionalPass] = &[ ConditionalPass::always(COLLECT_TRAIT_IMPLS), - ConditionalPass::always(UNINDENT_COMMENTS), ConditionalPass::always(CHECK_DOC_TEST_VISIBILITY), ConditionalPass::new(STRIP_HIDDEN, WhenNotDocumentHidden), ConditionalPass::new(STRIP_PRIVATE, WhenNotDocumentPrivate), diff --git a/src/librustdoc/passes/unindent_comments.rs b/src/librustdoc/passes/unindent_comments.rs deleted file mode 100644 index 0f604157291..00000000000 --- a/src/librustdoc/passes/unindent_comments.rs +++ /dev/null @@ -1,116 +0,0 @@ -//! Removes excess indentation on comments in order for the Markdown -//! to be parsed correctly. This is necessary because the convention for -//! writing documentation is to provide a space between the /// or //! marker -//! and the doc text, but Markdown is whitespace-sensitive. For example, -//! a block of text with four-space indentation is parsed as a code block, -//! so if we didn't unindent comments, these list items -//! -//! /// A list: -//! /// -//! /// - Foo -//! /// - Bar -//! -//! would be parsed as if they were in a code block, which is likely not what the user intended. -use std::cmp; - -use rustc_span::symbol::kw; - -use crate::clean::{self, DocFragment, DocFragmentKind, Item}; -use crate::core::DocContext; -use crate::fold::{self, DocFolder}; -use crate::passes::Pass; - -#[cfg(test)] -mod tests; - -crate const UNINDENT_COMMENTS: Pass = Pass { - name: "unindent-comments", - run: unindent_comments, - description: "removes excess indentation on comments in order for markdown to like it", -}; - -crate fn unindent_comments(krate: clean::Crate, _: &mut DocContext<'_>) -> clean::Crate { - CommentCleaner.fold_crate(krate) -} - -struct CommentCleaner; - -impl fold::DocFolder for CommentCleaner { - fn fold_item(&mut self, mut i: Item) -> Option<Item> { - i.attrs.unindent_doc_comments(); - Some(self.fold_item_recur(i)) - } -} - -impl clean::Attributes { - crate fn unindent_doc_comments(&mut self) { - unindent_fragments(&mut self.doc_strings); - } -} - -fn unindent_fragments(docs: &mut Vec<DocFragment>) { - // `add` is used in case the most common sugared doc syntax is used ("/// "). The other - // fragments kind's lines are never starting with a whitespace unless they are using some - // markdown formatting requiring it. Therefore, if the doc block have a mix between the two, - // we need to take into account the fact that the minimum indent minus one (to take this - // whitespace into account). - // - // For example: - // - // /// hello! - // #[doc = "another"] - // - // In this case, you want "hello! another" and not "hello! another". - let add = if docs.windows(2).any(|arr| arr[0].kind != arr[1].kind) - && docs.iter().any(|d| d.kind == DocFragmentKind::SugaredDoc) - { - // In case we have a mix of sugared doc comments and "raw" ones, we want the sugared one to - // "decide" how much the minimum indent will be. - 1 - } else { - 0 - }; - - // `min_indent` is used to know how much whitespaces from the start of each lines must be - // removed. Example: - // - // /// hello! - // #[doc = "another"] - // - // In here, the `min_indent` is 1 (because non-sugared fragment are always counted with minimum - // 1 whitespace), meaning that "hello!" will be considered a codeblock because it starts with 4 - // (5 - 1) whitespaces. - let Some(min_indent) = docs - .iter() - .map(|fragment| { - fragment.doc.as_str().lines().fold(usize::MAX, |min_indent, line| { - if line.chars().all(|c| c.is_whitespace()) { - min_indent - } else { - // Compare against either space or tab, ignoring whether they are - // mixed or not. - let whitespace = line.chars().take_while(|c| *c == ' ' || *c == '\t').count(); - cmp::min(min_indent, whitespace) - + if fragment.kind == DocFragmentKind::SugaredDoc { 0 } else { add } - } - }) - }) - .min() - else { - return; - }; - - for fragment in docs { - if fragment.doc == kw::Empty { - continue; - } - - let min_indent = if fragment.kind != DocFragmentKind::SugaredDoc && min_indent > 0 { - min_indent - add - } else { - min_indent - }; - - fragment.indent = min_indent; - } -} diff --git a/src/llvm-project b/src/llvm-project -Subproject fd336816c3a6d228dcef22171c43140f6fa7656 +Subproject fc10370ef7d91babf512c10505f8f2176bc8519 diff --git a/src/test/assembly/nvptx-kernel-abi/nvptx-kernel-args-abi-v7.rs b/src/test/assembly/nvptx-kernel-abi/nvptx-kernel-args-abi-v7.rs new file mode 100644 index 00000000000..5bf44f949fd --- /dev/null +++ b/src/test/assembly/nvptx-kernel-abi/nvptx-kernel-args-abi-v7.rs @@ -0,0 +1,254 @@ +// assembly-output: ptx-linker +// compile-flags: --crate-type cdylib -C target-cpu=sm_86 +// only-nvptx64 +// ignore-nvptx64 + +// The following ABI tests are made with nvcc 11.6 does. +// +// The PTX ABI stability is tied to major versions of the PTX ISA +// These tests assume major version 7 +// +// +// The following correspondence between types are assumed: +// u<N> - uint<N>_t +// i<N> - int<N>_t +// [T, N] - std::array<T, N> +// &T - T const* +// &mut T - T* + +// CHECK: .version 7 + +#![feature(abi_ptx, lang_items, no_core)] +#![no_core] + +#[lang = "sized"] +trait Sized {} +#[lang = "copy"] +trait Copy {} + +#[repr(C)] +pub struct SingleU8 { + f: u8, +} + +#[repr(C)] +pub struct DoubleU8 { + f: u8, + g: u8, +} + +#[repr(C)] +pub struct TripleU8 { + f: u8, + g: u8, + h: u8, +} + +#[repr(C)] +pub struct TripleU16 { + f: u16, + g: u16, + h: u16, +} +#[repr(C)] +pub struct TripleU32 { + f: u32, + g: u32, + h: u32, +} +#[repr(C)] +pub struct TripleU64 { + f: u64, + g: u64, + h: u64, +} + +#[repr(C)] +pub struct DoubleFloat { + f: f32, + g: f32, +} + +#[repr(C)] +pub struct TripleFloat { + f: f32, + g: f32, + h: f32, +} + +#[repr(C)] +pub struct TripleDouble { + f: f64, + g: f64, + h: f64, +} + +#[repr(C)] +pub struct ManyIntegers { + f: u8, + g: u16, + h: u32, + i: u64, +} + +#[repr(C)] +pub struct ManyNumerics { + f: u8, + g: u16, + h: u32, + i: u64, + j: f32, + k: f64, +} + +// CHECK: .visible .entry f_u8_arg( +// CHECK: .param .u8 f_u8_arg_param_0 +#[no_mangle] +pub unsafe extern "ptx-kernel" fn f_u8_arg(_a: u8) {} + +// CHECK: .visible .entry f_u16_arg( +// CHECK: .param .u16 f_u16_arg_param_0 +#[no_mangle] +pub unsafe extern "ptx-kernel" fn f_u16_arg(_a: u16) {} + +// CHECK: .visible .entry f_u32_arg( +// CHECK: .param .u32 f_u32_arg_param_0 +#[no_mangle] +pub unsafe extern "ptx-kernel" fn f_u32_arg(_a: u32) {} + +// CHECK: .visible .entry f_u64_arg( +// CHECK: .param .u64 f_u64_arg_param_0 +#[no_mangle] +pub unsafe extern "ptx-kernel" fn f_u64_arg(_a: u64) {} + +// CHECK: .visible .entry f_u128_arg( +// CHECK: .param .align 16 .b8 f_u128_arg_param_0[16] +#[no_mangle] +pub unsafe extern "ptx-kernel" fn f_u128_arg(_a: u128) {} + +// CHECK: .visible .entry f_i8_arg( +// CHECK: .param .u8 f_i8_arg_param_0 +#[no_mangle] +pub unsafe extern "ptx-kernel" fn f_i8_arg(_a: i8) {} + +// CHECK: .visible .entry f_i16_arg( +// CHECK: .param .u16 f_i16_arg_param_0 +#[no_mangle] +pub unsafe extern "ptx-kernel" fn f_i16_arg(_a: i16) {} + +// CHECK: .visible .entry f_i32_arg( +// CHECK: .param .u32 f_i32_arg_param_0 +#[no_mangle] +pub unsafe extern "ptx-kernel" fn f_i32_arg(_a: i32) {} + +// CHECK: .visible .entry f_i64_arg( +// CHECK: .param .u64 f_i64_arg_param_0 +#[no_mangle] +pub unsafe extern "ptx-kernel" fn f_i64_arg(_a: i64) {} + +// CHECK: .visible .entry f_i128_arg( +// CHECK: .param .align 16 .b8 f_i128_arg_param_0[16] +#[no_mangle] +pub unsafe extern "ptx-kernel" fn f_i128_arg(_a: i128) {} + +// CHECK: .visible .entry f_f32_arg( +// CHECK: .param .f32 f_f32_arg_param_0 +#[no_mangle] +pub unsafe extern "ptx-kernel" fn f_f32_arg(_a: f32) {} + +// CHECK: .visible .entry f_f64_arg( +// CHECK: .param .f64 f_f64_arg_param_0 +#[no_mangle] +pub unsafe extern "ptx-kernel" fn f_f64_arg(_a: f64) {} + +// CHECK: .visible .entry f_single_u8_arg( +// CHECK: .param .align 1 .b8 f_single_u8_arg_param_0[1] +#[no_mangle] +pub unsafe extern "ptx-kernel" fn f_single_u8_arg(_a: SingleU8) {} + +// CHECK: .visible .entry f_double_u8_arg( +// CHECK: .param .align 1 .b8 f_double_u8_arg_param_0[2] +#[no_mangle] +pub unsafe extern "ptx-kernel" fn f_double_u8_arg(_a: DoubleU8) {} + +// CHECK: .visible .entry f_triple_u8_arg( +// CHECK: .param .align 1 .b8 f_triple_u8_arg_param_0[3] +#[no_mangle] +pub unsafe extern "ptx-kernel" fn f_triple_u8_arg(_a: TripleU8) {} + +// CHECK: .visible .entry f_triple_u16_arg( +// CHECK: .param .align 2 .b8 f_triple_u16_arg_param_0[6] +#[no_mangle] +pub unsafe extern "ptx-kernel" fn f_triple_u16_arg(_a: TripleU16) {} + +// CHECK: .visible .entry f_triple_u32_arg( +// CHECK: .param .align 4 .b8 f_triple_u32_arg_param_0[12] +#[no_mangle] +pub unsafe extern "ptx-kernel" fn f_triple_u32_arg(_a: TripleU32) {} + +// CHECK: .visible .entry f_triple_u64_arg( +// CHECK: .param .align 8 .b8 f_triple_u64_arg_param_0[24] +#[no_mangle] +pub unsafe extern "ptx-kernel" fn f_triple_u64_arg(_a: TripleU64) {} + +// CHECK: .visible .entry f_many_integers_arg( +// CHECK: .param .align 8 .b8 f_many_integers_arg_param_0[16] +#[no_mangle] +pub unsafe extern "ptx-kernel" fn f_many_integers_arg(_a: ManyIntegers) {} + +// CHECK: .visible .entry f_double_float_arg( +// CHECK: .param .align 4 .b8 f_double_float_arg_param_0[8] +#[no_mangle] +pub unsafe extern "ptx-kernel" fn f_double_float_arg(_a: DoubleFloat) {} + +// CHECK: .visible .entry f_triple_float_arg( +// CHECK: .param .align 4 .b8 f_triple_float_arg_param_0[12] +#[no_mangle] +pub unsafe extern "ptx-kernel" fn f_triple_float_arg(_a: TripleFloat) {} + +// CHECK: .visible .entry f_triple_double_arg( +// CHECK: .param .align 8 .b8 f_triple_double_arg_param_0[24] +#[no_mangle] +pub unsafe extern "ptx-kernel" fn f_triple_double_arg(_a: TripleDouble) {} + +// CHECK: .visible .entry f_many_numerics_arg( +// CHECK: .param .align 8 .b8 f_many_numerics_arg_param_0[32] +#[no_mangle] +pub unsafe extern "ptx-kernel" fn f_many_numerics_arg(_a: ManyNumerics) {} + +// CHECK: .visible .entry f_byte_array_arg( +// CHECK: .param .align 1 .b8 f_byte_array_arg_param_0[5] +#[no_mangle] +pub unsafe extern "ptx-kernel" fn f_byte_array_arg(_a: [u8; 5]) {} + +// CHECK: .visible .entry f_float_array_arg( +// CHECK: .param .align 4 .b8 f_float_array_arg_param_0[20] +#[no_mangle] +pub unsafe extern "ptx-kernel" fn f_float_array_arg(_a: [f32; 5]) {} + +// CHECK: .visible .entry f_u128_array_arg( +// CHECK: .param .align 16 .b8 f_u128_array_arg_param_0[80] +#[no_mangle] +pub unsafe extern "ptx-kernel" fn f_u128_array_arg(_a: [u128; 5]) {} + +// CHECK: .visible .entry f_u32_slice_arg( +// CHECK: .param .u64 f_u32_slice_arg_param_0 +// CHECK: .param .u64 f_u32_slice_arg_param_1 +#[no_mangle] +pub unsafe extern "ptx-kernel" fn f_u32_slice_arg(_a: &[u32]) {} + +// CHECK: .visible .entry f_tuple_u8_u8_arg( +// CHECK: .param .align 1 .b8 f_tuple_u8_u8_arg_param_0[2] +#[no_mangle] +pub unsafe extern "ptx-kernel" fn f_tuple_u8_u8_arg(_a: (u8, u8)) {} + +// CHECK: .visible .entry f_tuple_u32_u32_arg( +// CHECK: .param .align 4 .b8 f_tuple_u32_u32_arg_param_0[8] +#[no_mangle] +pub unsafe extern "ptx-kernel" fn f_tuple_u32_u32_arg(_a: (u32, u32)) {} + + +// CHECK: .visible .entry f_tuple_u8_u8_u32_arg( +// CHECK: .param .align 4 .b8 f_tuple_u8_u8_u32_arg_param_0[8] +#[no_mangle] +pub unsafe extern "ptx-kernel" fn f_tuple_u8_u8_u32_arg(_a: (u8, u8, u32)) {} diff --git a/src/test/codegen/asm-clobber_abi.rs b/src/test/codegen/asm-clobber_abi.rs index 69e35270266..a87152e0321 100644 --- a/src/test/codegen/asm-clobber_abi.rs +++ b/src/test/codegen/asm-clobber_abi.rs @@ -6,21 +6,21 @@ use std::arch::asm; // CHECK-LABEL: @clobber_sysv64 -// CHECK: ={ax},={cx},={dx},={si},={di},={r8},={r9},={r10},={r11},={xmm0},={xmm1},={xmm2},={xmm3},={xmm4},={xmm5},={xmm6},={xmm7},={xmm8},={xmm9},={xmm10},={xmm11},={xmm12},={xmm13},={xmm14},={xmm15},~{xmm16},~{xmm17},~{xmm18},~{xmm19},~{xmm20},~{xmm21},~{xmm22},~{xmm23},~{xmm24},~{xmm25},~{xmm26},~{xmm27},~{xmm28},~{xmm29},~{xmm30},~{xmm31},~{k1},~{k2},~{k3},~{k4},~{k5},~{k6},~{k7},~{st},~{st(1)},~{st(2)},~{st(3)},~{st(4)},~{st(5)},~{st(6)},~{st(7)},~{dirflag},~{fpsr},~{flags},~{memory} +// CHECK: ={ax},={cx},={dx},={si},={di},={r8},={r9},={r10},={r11},={xmm0},={xmm1},={xmm2},={xmm3},={xmm4},={xmm5},={xmm6},={xmm7},={xmm8},={xmm9},={xmm10},={xmm11},={xmm12},={xmm13},={xmm14},={xmm15},~{xmm16},~{xmm17},~{xmm18},~{xmm19},~{xmm20},~{xmm21},~{xmm22},~{xmm23},~{xmm24},~{xmm25},~{xmm26},~{xmm27},~{xmm28},~{xmm29},~{xmm30},~{xmm31},~{k0},~{k1},~{k2},~{k3},~{k4},~{k5},~{k6},~{k7},~{st},~{st(1)},~{st(2)},~{st(3)},~{st(4)},~{st(5)},~{st(6)},~{st(7)},~{dirflag},~{fpsr},~{flags},~{memory} #[no_mangle] pub unsafe fn clobber_sysv64() { asm!("", clobber_abi("sysv64")); } // CHECK-LABEL: @clobber_win64 -// CHECK: ={ax},={cx},={dx},={r8},={r9},={r10},={r11},={xmm0},={xmm1},={xmm2},={xmm3},={xmm4},={xmm5},={xmm6},={xmm7},={xmm8},={xmm9},={xmm10},={xmm11},={xmm12},={xmm13},={xmm14},={xmm15},~{xmm16},~{xmm17},~{xmm18},~{xmm19},~{xmm20},~{xmm21},~{xmm22},~{xmm23},~{xmm24},~{xmm25},~{xmm26},~{xmm27},~{xmm28},~{xmm29},~{xmm30},~{xmm31},~{k1},~{k2},~{k3},~{k4},~{k5},~{k6},~{k7},~{st},~{st(1)},~{st(2)},~{st(3)},~{st(4)},~{st(5)},~{st(6)},~{st(7)},~{dirflag},~{fpsr},~{flags},~{memory} +// CHECK: ={ax},={cx},={dx},={r8},={r9},={r10},={r11},={xmm0},={xmm1},={xmm2},={xmm3},={xmm4},={xmm5},={xmm6},={xmm7},={xmm8},={xmm9},={xmm10},={xmm11},={xmm12},={xmm13},={xmm14},={xmm15},~{xmm16},~{xmm17},~{xmm18},~{xmm19},~{xmm20},~{xmm21},~{xmm22},~{xmm23},~{xmm24},~{xmm25},~{xmm26},~{xmm27},~{xmm28},~{xmm29},~{xmm30},~{xmm31},~{k0},~{k1},~{k2},~{k3},~{k4},~{k5},~{k6},~{k7},~{st},~{st(1)},~{st(2)},~{st(3)},~{st(4)},~{st(5)},~{st(6)},~{st(7)},~{dirflag},~{fpsr},~{flags},~{memory} #[no_mangle] pub unsafe fn clobber_win64() { asm!("", clobber_abi("win64")); } // CHECK-LABEL: @clobber_sysv64 -// CHECK: =&{dx},={ax},={cx},={si},={di},={r8},={r9},={r10},={r11},={xmm0},={xmm1},={xmm2},={xmm3},={xmm4},={xmm5},={xmm6},={xmm7},={xmm8},={xmm9},={xmm10},={xmm11},={xmm12},={xmm13},={xmm14},={xmm15},~{xmm16},~{xmm17},~{xmm18},~{xmm19},~{xmm20},~{xmm21},~{xmm22},~{xmm23},~{xmm24},~{xmm25},~{xmm26},~{xmm27},~{xmm28},~{xmm29},~{xmm30},~{xmm31},~{k1},~{k2},~{k3},~{k4},~{k5},~{k6},~{k7},~{st},~{st(1)},~{st(2)},~{st(3)},~{st(4)},~{st(5)},~{st(6)},~{st(7)},~{dirflag},~{fpsr},~{flags},~{memory} +// CHECK: =&{dx},={ax},={cx},={si},={di},={r8},={r9},={r10},={r11},={xmm0},={xmm1},={xmm2},={xmm3},={xmm4},={xmm5},={xmm6},={xmm7},={xmm8},={xmm9},={xmm10},={xmm11},={xmm12},={xmm13},={xmm14},={xmm15},~{xmm16},~{xmm17},~{xmm18},~{xmm19},~{xmm20},~{xmm21},~{xmm22},~{xmm23},~{xmm24},~{xmm25},~{xmm26},~{xmm27},~{xmm28},~{xmm29},~{xmm30},~{xmm31},~{k0},~{k1},~{k2},~{k3},~{k4},~{k5},~{k6},~{k7},~{st},~{st(1)},~{st(2)},~{st(3)},~{st(4)},~{st(5)},~{st(6)},~{st(7)},~{dirflag},~{fpsr},~{flags},~{memory} #[no_mangle] pub unsafe fn clobber_sysv64_edx() { let foo: i32; @@ -28,7 +28,7 @@ pub unsafe fn clobber_sysv64_edx() { } // CHECK-LABEL: @clobber_win64 -// CHECK: =&{dx},={ax},={cx},={r8},={r9},={r10},={r11},={xmm0},={xmm1},={xmm2},={xmm3},={xmm4},={xmm5},={xmm6},={xmm7},={xmm8},={xmm9},={xmm10},={xmm11},={xmm12},={xmm13},={xmm14},={xmm15},~{xmm16},~{xmm17},~{xmm18},~{xmm19},~{xmm20},~{xmm21},~{xmm22},~{xmm23},~{xmm24},~{xmm25},~{xmm26},~{xmm27},~{xmm28},~{xmm29},~{xmm30},~{xmm31},~{k1},~{k2},~{k3},~{k4},~{k5},~{k6},~{k7},~{st},~{st(1)},~{st(2)},~{st(3)},~{st(4)},~{st(5)},~{st(6)},~{st(7)},~{dirflag},~{fpsr},~{flags},~{memory} +// CHECK: =&{dx},={ax},={cx},={r8},={r9},={r10},={r11},={xmm0},={xmm1},={xmm2},={xmm3},={xmm4},={xmm5},={xmm6},={xmm7},={xmm8},={xmm9},={xmm10},={xmm11},={xmm12},={xmm13},={xmm14},={xmm15},~{xmm16},~{xmm17},~{xmm18},~{xmm19},~{xmm20},~{xmm21},~{xmm22},~{xmm23},~{xmm24},~{xmm25},~{xmm26},~{xmm27},~{xmm28},~{xmm29},~{xmm30},~{xmm31},~{k0},~{k1},~{k2},~{k3},~{k4},~{k5},~{k6},~{k7},~{st},~{st(1)},~{st(2)},~{st(3)},~{st(4)},~{st(5)},~{st(6)},~{st(7)},~{dirflag},~{fpsr},~{flags},~{memory} #[no_mangle] pub unsafe fn clobber_win64_edx() { let foo: i32; diff --git a/src/test/codegen/panic-in-drop-abort.rs b/src/test/codegen/panic-in-drop-abort.rs index 39f73c4e396..7a84484c419 100644 --- a/src/test/codegen/panic-in-drop-abort.rs +++ b/src/test/codegen/panic-in-drop-abort.rs @@ -1,14 +1,12 @@ -// compile-flags: -Z panic-in-drop=abort -O -Z new-llvm-pass-manager=no +// compile-flags: -Z panic-in-drop=abort -O +// ignore-msvc // Ensure that unwinding code paths are eliminated from the output after // optimization. -// This test uses -Z new-llvm-pass-manager=no, because the expected optimization does not happen -// on targets using SEH exceptions (i.e. MSVC) anymore. The core issue is that Rust promises that -// the drop_in_place() function can't unwind, but implements it in a way that *can*, because we -// currently go out of our way to allow longjmps, which also use the unwinding mechanism on MSVC -// targets. We should either forbid longjmps, or not assume nounwind, making this optimization -// incompatible with the current behavior of running cleanuppads on longjmp unwinding. +// This test uses ignore-msvc, because the expected optimization does not happen on targets using +// SEH exceptions with the new LLVM pass manager anymore, see +// https://github.com/llvm/llvm-project/issues/51311. // CHECK-NOT: {{(call|invoke).*}}should_not_appear_in_output diff --git a/src/test/codegen/remap_path_prefix/main.rs b/src/test/codegen/remap_path_prefix/main.rs index 698dfe6b4f3..b13d576295c 100644 --- a/src/test/codegen/remap_path_prefix/main.rs +++ b/src/test/codegen/remap_path_prefix/main.rs @@ -22,7 +22,7 @@ fn main() { } // Here we check that local debuginfo is mapped correctly. -// CHECK: !DIFile(filename: "/the/src/remap_path_prefix/main.rs", directory: "/the/cwd/" +// CHECK: !DIFile(filename: "/the/src/remap_path_prefix/main.rs", directory: "/the/cwd" // And here that debuginfo from other crates are expanded to absolute paths. // CHECK: !DIFile(filename: "/the/aux-src/remap_path_prefix_aux.rs", directory: "" diff --git a/src/test/codegen/set-discriminant-invalid.rs b/src/test/codegen/set-discriminant-invalid.rs index d9614f062b7..bccb9e4c758 100644 --- a/src/test/codegen/set-discriminant-invalid.rs +++ b/src/test/codegen/set-discriminant-invalid.rs @@ -28,7 +28,7 @@ impl IntoError<Error> for Api #[no_mangle] fn into_error(self, error: Self::Source) -> Error { Error::Api { - source: (|v| v)(error), + source: error, } } } diff --git a/src/test/debuginfo/thread.rs b/src/test/debuginfo/thread.rs index 531c37a3421..388d50c5cdc 100644 --- a/src/test/debuginfo/thread.rs +++ b/src/test/debuginfo/thread.rs @@ -14,7 +14,7 @@ // // cdb-command:dx t,d // cdb-check:t,d : [...] [Type: std::thread::Thread *] -// cdb-check: [...] inner : {...} [Type: alloc::sync::Arc<std::thread::Inner>] +// cdb-check:[...] inner [...][Type: core::pin::Pin<alloc::sync::Arc<std::thread::Inner> >] use std::thread; diff --git a/src/test/debuginfo/unit-type.rs b/src/test/debuginfo/unit-type.rs new file mode 100644 index 00000000000..7aab41a3e7c --- /dev/null +++ b/src/test/debuginfo/unit-type.rs @@ -0,0 +1,71 @@ +// compile-flags:-g + +// We only test Rust-aware versions of GDB: +// min-gdb-version: 8.2 + +// === GDB TESTS =================================================================================== + +// gdb-command: run + +// gdb-command: print _ref +// gdb-check: $1 = (*mut ()) 0x[...] + +// gdb-command: print _ptr +// gdb-check: $2 = (*mut ()) 0x[...] + +// gdb-command: print _local +// gdb-check: $3 = () + +// gdb-command: print _field +// gdb-check: $4 = unit_type::_TypeContainingUnitField {_a: 123, _unit: (), _b: 456} + +// Check that we can cast "void pointers" to their actual type in the debugger +// gdb-command: print /x *(_ptr as *const u64) +// gdb-check: $5 = 0x1122334455667788 + +// === CDB TESTS =================================================================================== + +// cdb-command: g +// cdb-check: Breakpoint 0 hit + +// cdb-command: dx _ref +// cdb-check: _ref : 0x[...] : () [Type: tuple$<> *] + +// cdb-command: dx _ptr +// cdb-check: _ptr : 0x[...] : () [Type: tuple$<> *] + +// cdb-command: dx _local +// cdb-check: _local : () [Type: tuple$<>] + +// cdb-command: dx _field,d +// cdb-check: _field,d [Type: unit_type::_TypeContainingUnitField] +// cdb-check: [+0x[...]] _a : 123 [Type: unsigned int] +// cdb-check: [+0x[...]] _unit : () [Type: tuple$<>] +// cdb-check: [+0x[...]] _b : 456 [Type: unsigned __int64] + +// Check that we can cast "void pointers" to their actual type in the debugger +// cdb-command: dx ((__int64 *)_ptr),x +// cdb-check: ((__int64 *)_ptr),x : 0x[...] : 0x1122334455667788 [Type: __int64 *] +// cdb-check: 0x1122334455667788 [Type: __int64] + +struct _TypeContainingUnitField { + _a: u32, + _unit: (), + _b: u64, +} + +fn foo(_ref: &(), _ptr: *const ()) { + let _local = (); + let _field = _TypeContainingUnitField { _a: 123, _unit: (), _b: 456 }; + + zzz(); // #break +} + +fn main() { + let pointee = 0x1122_3344_5566_7788i64; + + foo(&(), &pointee as *const i64 as *const ()); +} + +#[inline(never)] +fn zzz() {} diff --git a/src/test/incremental/hashes/enum_defs.rs b/src/test/incremental/hashes/enum_defs.rs index ab9c740844b..6582cdc4a2c 100644 --- a/src/test/incremental/hashes/enum_defs.rs +++ b/src/test/incremental/hashes/enum_defs.rs @@ -29,16 +29,14 @@ // Change enum visibility ----------------------------------------------------- #[cfg(any(cfail1,cfail4))] -enum EnumVisibility { A } +enum EnumVisibility { A } #[cfg(not(any(cfail1,cfail4)))] -#[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes")] +#[rustc_clean(cfg="cfail2")] #[rustc_clean(cfg="cfail3")] #[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes")] #[rustc_clean(cfg="cfail6")] -pub enum EnumVisibility { - A -} +pub enum EnumVisibility { A } diff --git a/src/test/incremental/hashes/inherent_impls.rs b/src/test/incremental/hashes/inherent_impls.rs index 22508e41bf8..5463b0dc87e 100644 --- a/src/test/incremental/hashes/inherent_impls.rs +++ b/src/test/incremental/hashes/inherent_impls.rs @@ -116,7 +116,7 @@ impl Foo { // Change Method Privacy ------------------------------------------------------- #[cfg(any(cfail1,cfail4))] impl Foo { - //------------------------------------------------------------------------------ + //---------------------------------------------------- //-------------------------- //------------------------------------------------------------------------------ //-------------------------- @@ -129,9 +129,9 @@ impl Foo { #[rustc_clean(cfg="cfail5")] #[rustc_clean(cfg="cfail6")] impl Foo { - #[rustc_clean(cfg="cfail2", except="associated_item,hir_owner,hir_owner_nodes")] + #[rustc_clean(cfg="cfail2", except="associated_item")] #[rustc_clean(cfg="cfail3")] - #[rustc_clean(cfg="cfail5", except="associated_item,hir_owner,hir_owner_nodes")] + #[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes,associated_item")] #[rustc_clean(cfg="cfail6")] fn method_privacy() { } } diff --git a/src/test/incremental/hashes/statics.rs b/src/test/incremental/hashes/statics.rs index 2b2658b2f5f..697be056761 100644 --- a/src/test/incremental/hashes/statics.rs +++ b/src/test/incremental/hashes/statics.rs @@ -24,10 +24,10 @@ // Change static visibility #[cfg(any(cfail1,cfail4))] -static STATIC_VISIBILITY: u8 = 0; +static STATIC_VISIBILITY: u8 = 0; #[cfg(not(any(cfail1,cfail4)))] -#[rustc_clean(cfg="cfail2", except="hir_owner,hir_owner_nodes")] +#[rustc_clean(cfg="cfail2")] #[rustc_clean(cfg="cfail3")] #[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes")] #[rustc_clean(cfg="cfail6")] diff --git a/src/test/incremental/hashes/struct_defs.rs b/src/test/incremental/hashes/struct_defs.rs index b5d8a3ab341..b4d558d259f 100644 --- a/src/test/incremental/hashes/struct_defs.rs +++ b/src/test/incremental/hashes/struct_defs.rs @@ -84,12 +84,12 @@ struct TupleStructAddField( // Tuple Struct Field Visibility ----------------------------------------------- #[cfg(any(cfail1,cfail4))] -struct TupleStructFieldVisibility(char); +struct TupleStructFieldVisibility( char); #[cfg(not(any(cfail1,cfail4)))] -#[rustc_clean(except="hir_owner,hir_owner_nodes,type_of", cfg="cfail2")] +#[rustc_clean(cfg="cfail2", except="type_of")] #[rustc_clean(cfg="cfail3")] -#[rustc_clean(except="hir_owner,hir_owner_nodes,type_of", cfg="cfail5")] +#[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes,type_of")] #[rustc_clean(cfg="cfail6")] struct TupleStructFieldVisibility(pub char); @@ -142,16 +142,14 @@ struct RecordStructAddField { // Record Struct Field Visibility ---------------------------------------------- #[cfg(any(cfail1,cfail4))] -struct RecordStructFieldVisibility { x: f32 } +struct RecordStructFieldVisibility { x: f32 } #[cfg(not(any(cfail1,cfail4)))] -#[rustc_clean(except="hir_owner,hir_owner_nodes,type_of", cfg="cfail2")] +#[rustc_clean(cfg="cfail2", except="type_of")] #[rustc_clean(cfg="cfail3")] -#[rustc_clean(except="hir_owner,hir_owner_nodes,type_of", cfg="cfail5")] +#[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes,type_of")] #[rustc_clean(cfg="cfail6")] -struct RecordStructFieldVisibility { - pub x: f32 -} +struct RecordStructFieldVisibility { pub x: f32 } // Add Lifetime Parameter ------------------------------------------------------ @@ -257,12 +255,12 @@ pub struct EmptyStruct; // Visibility ------------------------------------------------------------------ #[cfg(any(cfail1,cfail4))] -struct Visibility; +struct Visibility; #[cfg(not(any(cfail1,cfail4)))] -#[rustc_clean(except="hir_owner,hir_owner_nodes", cfg="cfail2")] +#[rustc_clean(cfg="cfail2")] #[rustc_clean(cfg="cfail3")] -#[rustc_clean(except="hir_owner,hir_owner_nodes", cfg="cfail5")] +#[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes")] #[rustc_clean(cfg="cfail6")] pub struct Visibility; diff --git a/src/test/incremental/hashes/trait_defs.rs b/src/test/incremental/hashes/trait_defs.rs index 279449fce5e..717e9e8c8e1 100644 --- a/src/test/incremental/hashes/trait_defs.rs +++ b/src/test/incremental/hashes/trait_defs.rs @@ -31,9 +31,9 @@ trait TraitVisibility { } #[cfg(not(any(cfail1,cfail4)))] -#[rustc_clean(except="hir_owner,hir_owner_nodes", cfg="cfail2")] +#[rustc_clean(cfg="cfail2")] #[rustc_clean(cfg="cfail3")] -#[rustc_clean(except="hir_owner,hir_owner_nodes", cfg="cfail5")] +#[rustc_clean(cfg="cfail5", except="hir_owner,hir_owner_nodes")] #[rustc_clean(cfg="cfail6")] pub trait TraitVisibility { } diff --git a/src/test/mir-opt/combine_clone_of_primitives.rs b/src/test/mir-opt/combine_clone_of_primitives.rs index 0972d2d68a1..7cc50a86e21 100644 --- a/src/test/mir-opt/combine_clone_of_primitives.rs +++ b/src/test/mir-opt/combine_clone_of_primitives.rs @@ -1,4 +1,4 @@ -// compile-flags: -C opt-level=0 -Z inline_mir=no +// unit-test: InstCombine // ignore-wasm32 compiled with panic=abort by default // EMIT_MIR combine_clone_of_primitives.{impl#0}-clone.InstCombine.diff diff --git a/src/test/mir-opt/combine_clone_of_primitives.{impl#0}-clone.InstCombine.diff b/src/test/mir-opt/combine_clone_of_primitives.{impl#0}-clone.InstCombine.diff index 678e965cd67..fdc016a95d5 100644 --- a/src/test/mir-opt/combine_clone_of_primitives.{impl#0}-clone.InstCombine.diff +++ b/src/test/mir-opt/combine_clone_of_primitives.{impl#0}-clone.InstCombine.diff @@ -23,9 +23,15 @@ } bb0: { + StorageLive(_2); // scope 0 at $DIR/combine_clone_of_primitives.rs:8:5: 8:9 _2 = &((*_1).0: T); // scope 0 at $DIR/combine_clone_of_primitives.rs:8:5: 8:9 + StorageLive(_3); // scope 0 at $DIR/combine_clone_of_primitives.rs:9:5: 9:11 _3 = &((*_1).1: u64); // scope 0 at $DIR/combine_clone_of_primitives.rs:9:5: 9:11 + StorageLive(_4); // scope 0 at $DIR/combine_clone_of_primitives.rs:10:5: 10:16 _4 = &((*_1).2: [f32; 3]); // scope 0 at $DIR/combine_clone_of_primitives.rs:10:5: 10:16 + StorageLive(_5); // scope 1 at $DIR/combine_clone_of_primitives.rs:8:5: 8:9 + StorageLive(_6); // scope 1 at $DIR/combine_clone_of_primitives.rs:8:5: 8:9 + StorageLive(_7); // scope 1 at $DIR/combine_clone_of_primitives.rs:8:5: 8:9 - _7 = &(*_2); // scope 1 at $DIR/combine_clone_of_primitives.rs:8:5: 8:9 - _6 = &(*_7); // scope 1 at $DIR/combine_clone_of_primitives.rs:8:5: 8:9 + _7 = _2; // scope 1 at $DIR/combine_clone_of_primitives.rs:8:5: 8:9 @@ -37,6 +43,10 @@ } bb1: { + StorageDead(_6); // scope 1 at $DIR/combine_clone_of_primitives.rs:8:8: 8:9 + StorageLive(_8); // scope 1 at $DIR/combine_clone_of_primitives.rs:9:5: 9:11 + StorageLive(_9); // scope 1 at $DIR/combine_clone_of_primitives.rs:9:5: 9:11 + StorageLive(_10); // scope 1 at $DIR/combine_clone_of_primitives.rs:9:5: 9:11 - _10 = &(*_3); // scope 1 at $DIR/combine_clone_of_primitives.rs:9:5: 9:11 - _9 = &(*_10); // scope 1 at $DIR/combine_clone_of_primitives.rs:9:5: 9:11 - _8 = <u64 as Clone>::clone(move _9) -> [return: bb2, unwind: bb4]; // scope 1 at $DIR/combine_clone_of_primitives.rs:9:5: 9:11 @@ -50,6 +60,10 @@ } bb2: { + StorageDead(_9); // scope 1 at $DIR/combine_clone_of_primitives.rs:9:10: 9:11 + StorageLive(_11); // scope 1 at $DIR/combine_clone_of_primitives.rs:10:5: 10:16 + StorageLive(_12); // scope 1 at $DIR/combine_clone_of_primitives.rs:10:5: 10:16 + StorageLive(_13); // scope 1 at $DIR/combine_clone_of_primitives.rs:10:5: 10:16 - _13 = &(*_4); // scope 1 at $DIR/combine_clone_of_primitives.rs:10:5: 10:16 - _12 = &(*_13); // scope 1 at $DIR/combine_clone_of_primitives.rs:10:5: 10:16 - _11 = <[f32; 3] as Clone>::clone(move _12) -> [return: bb3, unwind: bb4]; // scope 1 at $DIR/combine_clone_of_primitives.rs:10:5: 10:16 @@ -63,10 +77,20 @@ } bb3: { + StorageDead(_12); // scope 1 at $DIR/combine_clone_of_primitives.rs:10:15: 10:16 Deinit(_0); // scope 1 at $DIR/combine_clone_of_primitives.rs:6:10: 6:15 (_0.0: T) = move _5; // scope 1 at $DIR/combine_clone_of_primitives.rs:6:10: 6:15 (_0.1: u64) = move _8; // scope 1 at $DIR/combine_clone_of_primitives.rs:6:10: 6:15 (_0.2: [f32; 3]) = move _11; // scope 1 at $DIR/combine_clone_of_primitives.rs:6:10: 6:15 + StorageDead(_13); // scope 1 at $DIR/combine_clone_of_primitives.rs:6:14: 6:15 + StorageDead(_11); // scope 1 at $DIR/combine_clone_of_primitives.rs:6:14: 6:15 + StorageDead(_10); // scope 1 at $DIR/combine_clone_of_primitives.rs:6:14: 6:15 + StorageDead(_8); // scope 1 at $DIR/combine_clone_of_primitives.rs:6:14: 6:15 + StorageDead(_7); // scope 1 at $DIR/combine_clone_of_primitives.rs:6:14: 6:15 + StorageDead(_5); // scope 1 at $DIR/combine_clone_of_primitives.rs:6:14: 6:15 + StorageDead(_4); // scope 0 at $DIR/combine_clone_of_primitives.rs:6:14: 6:15 + StorageDead(_3); // scope 0 at $DIR/combine_clone_of_primitives.rs:6:14: 6:15 + StorageDead(_2); // scope 0 at $DIR/combine_clone_of_primitives.rs:6:14: 6:15 return; // scope 0 at $DIR/combine_clone_of_primitives.rs:6:15: 6:15 } diff --git a/src/test/mir-opt/derefer_complex_case.main.Derefer.diff b/src/test/mir-opt/derefer_complex_case.main.Derefer.diff new file mode 100644 index 00000000000..f5eabf86967 --- /dev/null +++ b/src/test/mir-opt/derefer_complex_case.main.Derefer.diff @@ -0,0 +1,111 @@ +- // MIR for `main` before Derefer ++ // MIR for `main` after Derefer + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/derefer_complex_case.rs:3:11: 3:11 + let mut _1: std::slice::Iter<i32>; // in scope 0 at $DIR/derefer_complex_case.rs:4:17: 4:26 + let mut _2: &[i32; 2]; // in scope 0 at $DIR/derefer_complex_case.rs:4:17: 4:26 + let _3: [i32; 2]; // in scope 0 at $DIR/derefer_complex_case.rs:4:18: 4:26 + let mut _4: std::slice::Iter<i32>; // in scope 0 at $DIR/derefer_complex_case.rs:4:17: 4:26 + let mut _5: (); // in scope 0 at $DIR/derefer_complex_case.rs:3:1: 5:2 + let _6: (); // in scope 0 at $DIR/derefer_complex_case.rs:4:17: 4:26 + let mut _7: std::option::Option<&i32>; // in scope 0 at $DIR/derefer_complex_case.rs:4:17: 4:26 + let mut _8: &mut std::slice::Iter<i32>; // in scope 0 at $DIR/derefer_complex_case.rs:4:17: 4:26 + let mut _9: &mut std::slice::Iter<i32>; // in scope 0 at $DIR/derefer_complex_case.rs:4:17: 4:26 + let mut _10: isize; // in scope 0 at $DIR/derefer_complex_case.rs:4:5: 4:40 + let mut _11: !; // in scope 0 at $DIR/derefer_complex_case.rs:4:5: 4:40 + let mut _13: i32; // in scope 0 at $DIR/derefer_complex_case.rs:4:34: 4:37 + let mut _14: &[i32; 2]; // in scope 0 at $DIR/derefer_complex_case.rs:4:17: 4:26 ++ let mut _15: &i32; // in scope 0 at $DIR/derefer_complex_case.rs:4:17: 4:26 + scope 1 { + debug iter => _4; // in scope 1 at $DIR/derefer_complex_case.rs:4:17: 4:26 + let _12: i32; // in scope 1 at $DIR/derefer_complex_case.rs:4:10: 4:13 + scope 2 { + debug foo => _12; // in scope 2 at $DIR/derefer_complex_case.rs:4:10: 4:13 + } + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/derefer_complex_case.rs:4:17: 4:26 + StorageLive(_2); // scope 0 at $DIR/derefer_complex_case.rs:4:17: 4:26 + _14 = const main::promoted[0]; // scope 0 at $DIR/derefer_complex_case.rs:4:17: 4:26 + // mir::Constant + // + span: $DIR/derefer_complex_case.rs:4:17: 4:26 + // + literal: Const { ty: &[i32; 2], val: Unevaluated(main, [], Some(promoted[0])) } + _2 = &(*_14); // scope 0 at $DIR/derefer_complex_case.rs:4:17: 4:26 + _1 = <&[i32; 2] as IntoIterator>::into_iter(move _2) -> bb1; // scope 0 at $DIR/derefer_complex_case.rs:4:17: 4:26 + // mir::Constant + // + span: $DIR/derefer_complex_case.rs:4:17: 4:26 + // + literal: Const { ty: fn(&[i32; 2]) -> <&[i32; 2] as IntoIterator>::IntoIter {<&[i32; 2] as IntoIterator>::into_iter}, val: Value(Scalar(<ZST>)) } + } + + bb1: { + StorageDead(_2); // scope 0 at $DIR/derefer_complex_case.rs:4:25: 4:26 + StorageLive(_4); // scope 0 at $DIR/derefer_complex_case.rs:4:17: 4:26 + _4 = move _1; // scope 0 at $DIR/derefer_complex_case.rs:4:17: 4:26 + goto -> bb2; // scope 1 at $DIR/derefer_complex_case.rs:4:5: 4:40 + } + + bb2: { + StorageLive(_6); // scope 1 at $DIR/derefer_complex_case.rs:4:17: 4:26 + StorageLive(_7); // scope 1 at $DIR/derefer_complex_case.rs:4:17: 4:26 + StorageLive(_8); // scope 1 at $DIR/derefer_complex_case.rs:4:17: 4:26 + StorageLive(_9); // scope 1 at $DIR/derefer_complex_case.rs:4:17: 4:26 + _9 = &mut _4; // scope 1 at $DIR/derefer_complex_case.rs:4:17: 4:26 + _8 = &mut (*_9); // scope 1 at $DIR/derefer_complex_case.rs:4:17: 4:26 + _7 = <std::slice::Iter<i32> as Iterator>::next(move _8) -> bb3; // scope 1 at $DIR/derefer_complex_case.rs:4:17: 4:26 + // mir::Constant + // + span: $DIR/derefer_complex_case.rs:4:17: 4:26 + // + literal: Const { ty: for<'r> fn(&'r mut std::slice::Iter<i32>) -> Option<<std::slice::Iter<i32> as Iterator>::Item> {<std::slice::Iter<i32> as Iterator>::next}, val: Value(Scalar(<ZST>)) } + } + + bb3: { + StorageDead(_8); // scope 1 at $DIR/derefer_complex_case.rs:4:25: 4:26 + _10 = discriminant(_7); // scope 1 at $DIR/derefer_complex_case.rs:4:17: 4:26 + switchInt(move _10) -> [0_isize: bb6, 1_isize: bb4, otherwise: bb5]; // scope 1 at $DIR/derefer_complex_case.rs:4:17: 4:26 + } + + bb4: { + StorageLive(_12); // scope 1 at $DIR/derefer_complex_case.rs:4:10: 4:13 +- _12 = (*((_7 as Some).0: &i32)); // scope 1 at $DIR/derefer_complex_case.rs:4:10: 4:13 ++ StorageLive(_15); // scope 1 at $DIR/derefer_complex_case.rs:4:10: 4:13 ++ _15 = move ((_7 as Some).0: &i32); // scope 1 at $DIR/derefer_complex_case.rs:4:10: 4:13 ++ _12 = (*_15); // scope 1 at $DIR/derefer_complex_case.rs:4:10: 4:13 ++ StorageDead(_15); // scope 2 at $DIR/derefer_complex_case.rs:4:34: 4:37 + StorageLive(_13); // scope 2 at $DIR/derefer_complex_case.rs:4:34: 4:37 + _13 = _12; // scope 2 at $DIR/derefer_complex_case.rs:4:34: 4:37 + _6 = std::mem::drop::<i32>(move _13) -> bb7; // scope 2 at $DIR/derefer_complex_case.rs:4:29: 4:38 + // mir::Constant + // + span: $DIR/derefer_complex_case.rs:4:29: 4:33 + // + literal: Const { ty: fn(i32) {std::mem::drop::<i32>}, val: Value(Scalar(<ZST>)) } + } + + bb5: { + unreachable; // scope 1 at $DIR/derefer_complex_case.rs:4:17: 4:26 + } + + bb6: { + _0 = const (); // scope 1 at $DIR/derefer_complex_case.rs:4:5: 4:40 + StorageDead(_9); // scope 1 at $DIR/derefer_complex_case.rs:4:39: 4:40 + StorageDead(_7); // scope 1 at $DIR/derefer_complex_case.rs:4:39: 4:40 + StorageDead(_6); // scope 1 at $DIR/derefer_complex_case.rs:4:39: 4:40 + StorageDead(_4); // scope 0 at $DIR/derefer_complex_case.rs:4:39: 4:40 + StorageDead(_1); // scope 0 at $DIR/derefer_complex_case.rs:4:39: 4:40 + return; // scope 0 at $DIR/derefer_complex_case.rs:5:2: 5:2 + } + + bb7: { + StorageDead(_13); // scope 2 at $DIR/derefer_complex_case.rs:4:37: 4:38 + StorageDead(_12); // scope 1 at $DIR/derefer_complex_case.rs:4:39: 4:40 + StorageDead(_9); // scope 1 at $DIR/derefer_complex_case.rs:4:39: 4:40 + StorageDead(_7); // scope 1 at $DIR/derefer_complex_case.rs:4:39: 4:40 + StorageDead(_6); // scope 1 at $DIR/derefer_complex_case.rs:4:39: 4:40 + _5 = const (); // scope 1 at $DIR/derefer_complex_case.rs:4:5: 4:40 + goto -> bb2; // scope 1 at $DIR/derefer_complex_case.rs:4:5: 4:40 + } + + bb8 (cleanup): { + resume; // scope 0 at $DIR/derefer_complex_case.rs:3:1: 5:2 + } + } + diff --git a/src/test/mir-opt/derefer_complex_case.rs b/src/test/mir-opt/derefer_complex_case.rs new file mode 100644 index 00000000000..6abf49f9966 --- /dev/null +++ b/src/test/mir-opt/derefer_complex_case.rs @@ -0,0 +1,5 @@ +// EMIT_MIR derefer_complex_case.main.Derefer.diff + +fn main() { + for &foo in &[42, 43] { drop(foo) } +} diff --git a/src/test/mir-opt/derefer_terminator_test.main.Derefer.diff b/src/test/mir-opt/derefer_terminator_test.main.Derefer.diff new file mode 100644 index 00000000000..8b91a65bf3d --- /dev/null +++ b/src/test/mir-opt/derefer_terminator_test.main.Derefer.diff @@ -0,0 +1,103 @@ +- // MIR for `main` before Derefer ++ // MIR for `main` after Derefer + + fn main() -> () { + let mut _0: (); // return place in scope 0 at $DIR/derefer_terminator_test.rs:2:11: 2:11 + let _1: bool; // in scope 0 at $DIR/derefer_terminator_test.rs:3:9: 3:10 + let _3: (); // in scope 0 at $DIR/derefer_terminator_test.rs:5:5: 8:6 + let mut _4: &&&&bool; // in scope 0 at $DIR/derefer_terminator_test.rs:5:15: 5:22 + let _5: &&&bool; // in scope 0 at $DIR/derefer_terminator_test.rs:5:17: 5:21 + let _6: &&bool; // in scope 0 at $DIR/derefer_terminator_test.rs:5:18: 5:21 + let _7: &bool; // in scope 0 at $DIR/derefer_terminator_test.rs:5:19: 5:21 ++ let mut _10: &&&bool; // in scope 0 at $DIR/derefer_terminator_test.rs:5:15: 5:22 ++ let mut _11: &&bool; // in scope 0 at $DIR/derefer_terminator_test.rs:5:15: 5:22 ++ let mut _12: &bool; // in scope 0 at $DIR/derefer_terminator_test.rs:5:15: 5:22 + scope 1 { + debug b => _1; // in scope 1 at $DIR/derefer_terminator_test.rs:3:9: 3:10 + let _2: bool; // in scope 1 at $DIR/derefer_terminator_test.rs:4:9: 4:10 + scope 2 { + debug d => _2; // in scope 2 at $DIR/derefer_terminator_test.rs:4:9: 4:10 + let _8: i32; // in scope 2 at $DIR/derefer_terminator_test.rs:6:22: 6:23 + let _9: i32; // in scope 2 at $DIR/derefer_terminator_test.rs:9:9: 9:10 + scope 3 { + debug x => _8; // in scope 3 at $DIR/derefer_terminator_test.rs:6:22: 6:23 + } + scope 4 { + debug y => _9; // in scope 4 at $DIR/derefer_terminator_test.rs:9:9: 9:10 + } + } + } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/derefer_terminator_test.rs:3:9: 3:10 + _1 = foo() -> bb1; // scope 0 at $DIR/derefer_terminator_test.rs:3:13: 3:18 + // mir::Constant + // + span: $DIR/derefer_terminator_test.rs:3:13: 3:16 + // + literal: Const { ty: fn() -> bool {foo}, val: Value(Scalar(<ZST>)) } + } + + bb1: { + StorageLive(_2); // scope 1 at $DIR/derefer_terminator_test.rs:4:9: 4:10 + _2 = foo() -> bb2; // scope 1 at $DIR/derefer_terminator_test.rs:4:13: 4:18 + // mir::Constant + // + span: $DIR/derefer_terminator_test.rs:4:13: 4:16 + // + literal: Const { ty: fn() -> bool {foo}, val: Value(Scalar(<ZST>)) } + } + + bb2: { + StorageLive(_3); // scope 2 at $DIR/derefer_terminator_test.rs:5:5: 8:6 + StorageLive(_4); // scope 2 at $DIR/derefer_terminator_test.rs:5:15: 5:22 + StorageLive(_5); // scope 2 at $DIR/derefer_terminator_test.rs:5:17: 5:21 + StorageLive(_6); // scope 2 at $DIR/derefer_terminator_test.rs:5:18: 5:21 + StorageLive(_7); // scope 2 at $DIR/derefer_terminator_test.rs:5:19: 5:21 + _7 = &_1; // scope 2 at $DIR/derefer_terminator_test.rs:5:19: 5:21 + _6 = &_7; // scope 2 at $DIR/derefer_terminator_test.rs:5:18: 5:21 + _5 = &_6; // scope 2 at $DIR/derefer_terminator_test.rs:5:17: 5:21 + _4 = &_5; // scope 2 at $DIR/derefer_terminator_test.rs:5:15: 5:22 +- switchInt((*(*(*(*_4))))) -> [false: bb3, otherwise: bb4]; // scope 2 at $DIR/derefer_terminator_test.rs:5:5: 5:22 ++ StorageLive(_10); // scope 2 at $DIR/derefer_terminator_test.rs:5:5: 5:22 ++ _10 = move (*_4); // scope 2 at $DIR/derefer_terminator_test.rs:5:5: 5:22 ++ StorageLive(_11); // scope 2 at $DIR/derefer_terminator_test.rs:5:5: 5:22 ++ _11 = move (*_10); // scope 2 at $DIR/derefer_terminator_test.rs:5:5: 5:22 ++ StorageDead(_10); // scope 2 at $DIR/derefer_terminator_test.rs:5:5: 5:22 ++ StorageLive(_12); // scope 2 at $DIR/derefer_terminator_test.rs:5:5: 5:22 ++ _12 = move (*_11); // scope 2 at $DIR/derefer_terminator_test.rs:5:5: 5:22 ++ StorageDead(_11); // scope 2 at $DIR/derefer_terminator_test.rs:5:5: 5:22 ++ switchInt((*_12)) -> [false: bb3, otherwise: bb4]; // scope 2 at $DIR/derefer_terminator_test.rs:5:5: 5:22 + } + + bb3: { ++ StorageDead(_12); // scope 2 at $DIR/derefer_terminator_test.rs:5:5: 5:22 + _3 = const (); // scope 2 at $DIR/derefer_terminator_test.rs:7:18: 7:20 + goto -> bb5; // scope 2 at $DIR/derefer_terminator_test.rs:7:18: 7:20 + } + + bb4: { ++ StorageDead(_12); // scope 2 at $DIR/derefer_terminator_test.rs:5:5: 5:22 + StorageLive(_8); // scope 2 at $DIR/derefer_terminator_test.rs:6:22: 6:23 + _8 = const 5_i32; // scope 2 at $DIR/derefer_terminator_test.rs:6:26: 6:27 + _3 = const (); // scope 2 at $DIR/derefer_terminator_test.rs:6:17: 6:29 + StorageDead(_8); // scope 2 at $DIR/derefer_terminator_test.rs:6:28: 6:29 + goto -> bb5; // scope 2 at $DIR/derefer_terminator_test.rs:6:28: 6:29 + } + + bb5: { + StorageDead(_7); // scope 2 at $DIR/derefer_terminator_test.rs:8:5: 8:6 + StorageDead(_6); // scope 2 at $DIR/derefer_terminator_test.rs:8:5: 8:6 + StorageDead(_5); // scope 2 at $DIR/derefer_terminator_test.rs:8:5: 8:6 + StorageDead(_4); // scope 2 at $DIR/derefer_terminator_test.rs:8:5: 8:6 + StorageDead(_3); // scope 2 at $DIR/derefer_terminator_test.rs:8:5: 8:6 + StorageLive(_9); // scope 2 at $DIR/derefer_terminator_test.rs:9:9: 9:10 + _9 = const 42_i32; // scope 2 at $DIR/derefer_terminator_test.rs:9:13: 9:15 + _0 = const (); // scope 0 at $DIR/derefer_terminator_test.rs:2:11: 10:2 + StorageDead(_9); // scope 2 at $DIR/derefer_terminator_test.rs:10:1: 10:2 + StorageDead(_2); // scope 1 at $DIR/derefer_terminator_test.rs:10:1: 10:2 + StorageDead(_1); // scope 0 at $DIR/derefer_terminator_test.rs:10:1: 10:2 + return; // scope 0 at $DIR/derefer_terminator_test.rs:10:2: 10:2 + } + + bb6 (cleanup): { + resume; // scope 0 at $DIR/derefer_terminator_test.rs:2:1: 10:2 + } + } + diff --git a/src/test/mir-opt/derefer_terminator_test.rs b/src/test/mir-opt/derefer_terminator_test.rs new file mode 100644 index 00000000000..11f5b20636d --- /dev/null +++ b/src/test/mir-opt/derefer_terminator_test.rs @@ -0,0 +1,14 @@ +// EMIT_MIR derefer_terminator_test.main.Derefer.diff +fn main() { + let b = foo(); + let d = foo(); + match ****(&&&&b) { + true => {let x = 5;}, + false => {} + } + let y = 42; +} + +fn foo() -> bool { + true +} diff --git a/src/test/mir-opt/derefer_test.main.Derefer.diff b/src/test/mir-opt/derefer_test.main.Derefer.diff index d58e4eb838d..84476aeed7a 100644 --- a/src/test/mir-opt/derefer_test.main.Derefer.diff +++ b/src/test/mir-opt/derefer_test.main.Derefer.diff @@ -5,8 +5,8 @@ let mut _0: (); // return place in scope 0 at $DIR/derefer_test.rs:2:11: 2:11 let mut _1: (i32, i32); // in scope 0 at $DIR/derefer_test.rs:3:9: 3:14 let mut _3: &mut (i32, i32); // in scope 0 at $DIR/derefer_test.rs:4:22: 4:28 -+ let mut _6: &mut (i32, i32); // in scope 0 at $DIR/derefer_test.rs:5:13: 5:26 -+ let mut _7: &mut (i32, i32); // in scope 0 at $DIR/derefer_test.rs:6:13: 6:26 ++ let mut _6: &mut (i32, i32); // in scope 0 at $DIR/derefer_test.rs:4:9: 4:14 ++ let mut _7: &mut (i32, i32); // in scope 0 at $DIR/derefer_test.rs:4:9: 4:14 scope 1 { debug a => _1; // in scope 1 at $DIR/derefer_test.rs:3:9: 3:14 let mut _2: (i32, &mut (i32, i32)); // in scope 1 at $DIR/derefer_test.rs:4:9: 4:14 @@ -25,15 +25,11 @@ bb0: { StorageLive(_1); // scope 0 at $DIR/derefer_test.rs:3:9: 3:14 - Deinit(_1); // scope 0 at $DIR/derefer_test.rs:3:17: 3:24 - (_1.0: i32) = const 42_i32; // scope 0 at $DIR/derefer_test.rs:3:17: 3:24 - (_1.1: i32) = const 43_i32; // scope 0 at $DIR/derefer_test.rs:3:17: 3:24 + _1 = (const 42_i32, const 43_i32); // scope 0 at $DIR/derefer_test.rs:3:17: 3:24 StorageLive(_2); // scope 1 at $DIR/derefer_test.rs:4:9: 4:14 StorageLive(_3); // scope 1 at $DIR/derefer_test.rs:4:22: 4:28 _3 = &mut _1; // scope 1 at $DIR/derefer_test.rs:4:22: 4:28 - Deinit(_2); // scope 1 at $DIR/derefer_test.rs:4:17: 4:29 - (_2.0: i32) = const 99_i32; // scope 1 at $DIR/derefer_test.rs:4:17: 4:29 - (_2.1: &mut (i32, i32)) = move _3; // scope 1 at $DIR/derefer_test.rs:4:17: 4:29 + _2 = (const 99_i32, move _3); // scope 1 at $DIR/derefer_test.rs:4:17: 4:29 StorageDead(_3); // scope 1 at $DIR/derefer_test.rs:4:28: 4:29 StorageLive(_4); // scope 2 at $DIR/derefer_test.rs:5:9: 5:10 - _4 = &mut ((*(_2.1: &mut (i32, i32))).0: i32); // scope 2 at $DIR/derefer_test.rs:5:13: 5:26 @@ -53,10 +49,10 @@ StorageDead(_2); // scope 1 at $DIR/derefer_test.rs:7:1: 7:2 StorageDead(_1); // scope 0 at $DIR/derefer_test.rs:7:1: 7:2 return; // scope 0 at $DIR/derefer_test.rs:7:2: 7:2 -+ } -+ -+ bb1 (cleanup): { -+ resume; // scope 0 at $DIR/derefer_test.rs:2:1: 7:2 + } + + bb1 (cleanup): { + resume; // scope 0 at $DIR/derefer_test.rs:2:1: 7:2 } } diff --git a/src/test/mir-opt/derefer_test_multiple.main.Derefer.diff b/src/test/mir-opt/derefer_test_multiple.main.Derefer.diff index db24f71c750..b8e5a0c328f 100644 --- a/src/test/mir-opt/derefer_test_multiple.main.Derefer.diff +++ b/src/test/mir-opt/derefer_test_multiple.main.Derefer.diff @@ -7,12 +7,12 @@ let mut _3: &mut (i32, i32); // in scope 0 at $DIR/derefer_test_multiple.rs:4:22: 4:28 let mut _5: &mut (i32, &mut (i32, i32)); // in scope 0 at $DIR/derefer_test_multiple.rs:5:22: 5:28 let mut _7: &mut (i32, &mut (i32, &mut (i32, i32))); // in scope 0 at $DIR/derefer_test_multiple.rs:6:22: 6:28 -+ let mut _10: &mut (i32, &mut (i32, &mut (i32, i32))); // in scope 0 at $DIR/derefer_test_multiple.rs:7:13: 7:30 -+ let mut _11: &mut (i32, &mut (i32, i32)); // in scope 0 at $DIR/derefer_test_multiple.rs:7:13: 7:30 -+ let mut _12: &mut (i32, i32); // in scope 0 at $DIR/derefer_test_multiple.rs:7:13: 7:30 -+ let mut _13: &mut (i32, &mut (i32, &mut (i32, i32))); // in scope 0 at $DIR/derefer_test_multiple.rs:8:13: 8:30 -+ let mut _14: &mut (i32, &mut (i32, i32)); // in scope 0 at $DIR/derefer_test_multiple.rs:8:13: 8:30 -+ let mut _15: &mut (i32, i32); // in scope 0 at $DIR/derefer_test_multiple.rs:8:13: 8:30 ++ let mut _10: &mut (i32, &mut (i32, &mut (i32, i32))); // in scope 0 at $DIR/derefer_test_multiple.rs:6:9: 6:14 ++ let mut _11: &mut (i32, &mut (i32, i32)); // in scope 0 at $DIR/derefer_test_multiple.rs:6:9: 6:14 ++ let mut _12: &mut (i32, i32); // in scope 0 at $DIR/derefer_test_multiple.rs:6:9: 6:14 ++ let mut _13: &mut (i32, &mut (i32, &mut (i32, i32))); // in scope 0 at $DIR/derefer_test_multiple.rs:6:9: 6:14 ++ let mut _14: &mut (i32, &mut (i32, i32)); // in scope 0 at $DIR/derefer_test_multiple.rs:6:9: 6:14 ++ let mut _15: &mut (i32, i32); // in scope 0 at $DIR/derefer_test_multiple.rs:6:9: 6:14 scope 1 { debug a => _1; // in scope 1 at $DIR/derefer_test_multiple.rs:3:9: 3:14 let mut _2: (i32, &mut (i32, i32)); // in scope 1 at $DIR/derefer_test_multiple.rs:4:9: 4:14 @@ -39,29 +39,21 @@ bb0: { StorageLive(_1); // scope 0 at $DIR/derefer_test_multiple.rs:3:9: 3:14 - Deinit(_1); // scope 0 at $DIR/derefer_test_multiple.rs:3:17: 3:25 - (_1.0: i32) = const 42_i32; // scope 0 at $DIR/derefer_test_multiple.rs:3:17: 3:25 - (_1.1: i32) = const 43_i32; // scope 0 at $DIR/derefer_test_multiple.rs:3:17: 3:25 + _1 = (const 42_i32, const 43_i32); // scope 0 at $DIR/derefer_test_multiple.rs:3:17: 3:25 StorageLive(_2); // scope 1 at $DIR/derefer_test_multiple.rs:4:9: 4:14 StorageLive(_3); // scope 1 at $DIR/derefer_test_multiple.rs:4:22: 4:28 _3 = &mut _1; // scope 1 at $DIR/derefer_test_multiple.rs:4:22: 4:28 - Deinit(_2); // scope 1 at $DIR/derefer_test_multiple.rs:4:17: 4:29 - (_2.0: i32) = const 99_i32; // scope 1 at $DIR/derefer_test_multiple.rs:4:17: 4:29 - (_2.1: &mut (i32, i32)) = move _3; // scope 1 at $DIR/derefer_test_multiple.rs:4:17: 4:29 + _2 = (const 99_i32, move _3); // scope 1 at $DIR/derefer_test_multiple.rs:4:17: 4:29 StorageDead(_3); // scope 1 at $DIR/derefer_test_multiple.rs:4:28: 4:29 StorageLive(_4); // scope 2 at $DIR/derefer_test_multiple.rs:5:9: 5:14 StorageLive(_5); // scope 2 at $DIR/derefer_test_multiple.rs:5:22: 5:28 _5 = &mut _2; // scope 2 at $DIR/derefer_test_multiple.rs:5:22: 5:28 - Deinit(_4); // scope 2 at $DIR/derefer_test_multiple.rs:5:17: 5:29 - (_4.0: i32) = const 11_i32; // scope 2 at $DIR/derefer_test_multiple.rs:5:17: 5:29 - (_4.1: &mut (i32, &mut (i32, i32))) = move _5; // scope 2 at $DIR/derefer_test_multiple.rs:5:17: 5:29 + _4 = (const 11_i32, move _5); // scope 2 at $DIR/derefer_test_multiple.rs:5:17: 5:29 StorageDead(_5); // scope 2 at $DIR/derefer_test_multiple.rs:5:28: 5:29 StorageLive(_6); // scope 3 at $DIR/derefer_test_multiple.rs:6:9: 6:14 StorageLive(_7); // scope 3 at $DIR/derefer_test_multiple.rs:6:22: 6:28 _7 = &mut _4; // scope 3 at $DIR/derefer_test_multiple.rs:6:22: 6:28 - Deinit(_6); // scope 3 at $DIR/derefer_test_multiple.rs:6:17: 6:29 - (_6.0: i32) = const 13_i32; // scope 3 at $DIR/derefer_test_multiple.rs:6:17: 6:29 - (_6.1: &mut (i32, &mut (i32, &mut (i32, i32)))) = move _7; // scope 3 at $DIR/derefer_test_multiple.rs:6:17: 6:29 + _6 = (const 13_i32, move _7); // scope 3 at $DIR/derefer_test_multiple.rs:6:17: 6:29 StorageDead(_7); // scope 3 at $DIR/derefer_test_multiple.rs:6:28: 6:29 StorageLive(_8); // scope 4 at $DIR/derefer_test_multiple.rs:7:9: 7:10 - _8 = &mut ((*((*((*(_6.1: &mut (i32, &mut (i32, &mut (i32, i32))))).1: &mut (i32, &mut (i32, i32)))).1: &mut (i32, i32))).1: i32); // scope 4 at $DIR/derefer_test_multiple.rs:7:13: 7:30 @@ -69,11 +61,11 @@ + _10 = move (_6.1: &mut (i32, &mut (i32, &mut (i32, i32)))); // scope 4 at $DIR/derefer_test_multiple.rs:7:13: 7:30 + StorageLive(_11); // scope 4 at $DIR/derefer_test_multiple.rs:7:13: 7:30 + _11 = move ((*_10).1: &mut (i32, &mut (i32, i32))); // scope 4 at $DIR/derefer_test_multiple.rs:7:13: 7:30 ++ StorageDead(_10); // scope 4 at $DIR/derefer_test_multiple.rs:7:13: 7:30 + StorageLive(_12); // scope 4 at $DIR/derefer_test_multiple.rs:7:13: 7:30 + _12 = move ((*_11).1: &mut (i32, i32)); // scope 4 at $DIR/derefer_test_multiple.rs:7:13: 7:30 ++ StorageDead(_11); // scope 4 at $DIR/derefer_test_multiple.rs:7:13: 7:30 + _8 = &mut ((*_12).1: i32); // scope 4 at $DIR/derefer_test_multiple.rs:7:13: 7:30 -+ StorageDead(_10); // scope 5 at $DIR/derefer_test_multiple.rs:8:9: 8:10 -+ StorageDead(_11); // scope 5 at $DIR/derefer_test_multiple.rs:8:9: 8:10 + StorageDead(_12); // scope 5 at $DIR/derefer_test_multiple.rs:8:9: 8:10 StorageLive(_9); // scope 5 at $DIR/derefer_test_multiple.rs:8:9: 8:10 - _9 = &mut ((*((*((*(_6.1: &mut (i32, &mut (i32, &mut (i32, i32))))).1: &mut (i32, &mut (i32, i32)))).1: &mut (i32, i32))).1: i32); // scope 5 at $DIR/derefer_test_multiple.rs:8:13: 8:30 @@ -81,11 +73,11 @@ + _13 = move (_6.1: &mut (i32, &mut (i32, &mut (i32, i32)))); // scope 5 at $DIR/derefer_test_multiple.rs:8:13: 8:30 + StorageLive(_14); // scope 5 at $DIR/derefer_test_multiple.rs:8:13: 8:30 + _14 = move ((*_13).1: &mut (i32, &mut (i32, i32))); // scope 5 at $DIR/derefer_test_multiple.rs:8:13: 8:30 ++ StorageDead(_13); // scope 5 at $DIR/derefer_test_multiple.rs:8:13: 8:30 + StorageLive(_15); // scope 5 at $DIR/derefer_test_multiple.rs:8:13: 8:30 + _15 = move ((*_14).1: &mut (i32, i32)); // scope 5 at $DIR/derefer_test_multiple.rs:8:13: 8:30 ++ StorageDead(_14); // scope 5 at $DIR/derefer_test_multiple.rs:8:13: 8:30 + _9 = &mut ((*_15).1: i32); // scope 5 at $DIR/derefer_test_multiple.rs:8:13: 8:30 -+ StorageDead(_13); // scope 0 at $DIR/derefer_test_multiple.rs:2:12: 9:2 -+ StorageDead(_14); // scope 0 at $DIR/derefer_test_multiple.rs:2:12: 9:2 + StorageDead(_15); // scope 0 at $DIR/derefer_test_multiple.rs:2:12: 9:2 _0 = const (); // scope 0 at $DIR/derefer_test_multiple.rs:2:12: 9:2 StorageDead(_9); // scope 5 at $DIR/derefer_test_multiple.rs:9:1: 9:2 @@ -95,10 +87,10 @@ StorageDead(_2); // scope 1 at $DIR/derefer_test_multiple.rs:9:1: 9:2 StorageDead(_1); // scope 0 at $DIR/derefer_test_multiple.rs:9:1: 9:2 return; // scope 0 at $DIR/derefer_test_multiple.rs:9:2: 9:2 -+ } -+ -+ bb1 (cleanup): { -+ resume; // scope 0 at $DIR/derefer_test_multiple.rs:2:1: 9:2 + } + + bb1 (cleanup): { + resume; // scope 0 at $DIR/derefer_test_multiple.rs:2:1: 9:2 } } diff --git a/src/test/mir-opt/early_otherwise_branch.opt2.EarlyOtherwiseBranch.diff b/src/test/mir-opt/early_otherwise_branch.opt2.EarlyOtherwiseBranch.diff index 4f2b9696f8c..1cdd97ab283 100644 --- a/src/test/mir-opt/early_otherwise_branch.opt2.EarlyOtherwiseBranch.diff +++ b/src/test/mir-opt/early_otherwise_branch.opt2.EarlyOtherwiseBranch.diff @@ -32,7 +32,7 @@ StorageDead(_5); // scope 0 at $DIR/early_otherwise_branch.rs:12:16: 12:17 StorageDead(_4); // scope 0 at $DIR/early_otherwise_branch.rs:12:16: 12:17 _8 = discriminant((_3.0: std::option::Option<u32>)); // scope 0 at $DIR/early_otherwise_branch.rs:12:11: 12:17 -- switchInt(move _8) -> [0_isize: bb1, 1_isize: bb3, otherwise: bb7]; // scope 0 at $DIR/early_otherwise_branch.rs:12:5: 12:17 +- switchInt(move _8) -> [0_isize: bb1, 1_isize: bb3, otherwise: bb2]; // scope 0 at $DIR/early_otherwise_branch.rs:12:5: 12:17 + StorageLive(_11); // scope 0 at $DIR/early_otherwise_branch.rs:12:5: 12:17 + _11 = discriminant((_3.1: std::option::Option<u32>)); // scope 0 at $DIR/early_otherwise_branch.rs:12:5: 12:17 + StorageLive(_12); // scope 0 at $DIR/early_otherwise_branch.rs:12:5: 12:17 @@ -82,10 +82,8 @@ + bb4: { StorageDead(_3); // scope 0 at $DIR/early_otherwise_branch.rs:17:1: 17:2 return; // scope 0 at $DIR/early_otherwise_branch.rs:17:2: 17:2 - } - -- bb7: { -- unreachable; // scope 0 at $DIR/early_otherwise_branch.rs:15:14: 15:15 ++ } ++ + bb5: { + StorageDead(_12); // scope 0 at $DIR/early_otherwise_branch.rs:12:5: 12:17 + switchInt(_8) -> [0_isize: bb3, 1_isize: bb2, otherwise: bb1]; // scope 0 at $DIR/early_otherwise_branch.rs:12:5: 12:17 diff --git a/src/test/mir-opt/early_otherwise_branch.rs b/src/test/mir-opt/early_otherwise_branch.rs index e0ebcfeebfc..7be9fbd0326 100644 --- a/src/test/mir-opt/early_otherwise_branch.rs +++ b/src/test/mir-opt/early_otherwise_branch.rs @@ -1,4 +1,4 @@ -// compile-flags: -Z mir-opt-level=4 -Z unsound-mir-opts +// unit-test: EarlyOtherwiseBranch // EMIT_MIR early_otherwise_branch.opt1.EarlyOtherwiseBranch.diff fn opt1(x: Option<u32>, y: Option<u32>) -> u32 { match (x, y) { diff --git a/src/test/mir-opt/early_otherwise_branch_3_element_tuple.rs b/src/test/mir-opt/early_otherwise_branch_3_element_tuple.rs index 8527c01d756..76055e1330f 100644 --- a/src/test/mir-opt/early_otherwise_branch_3_element_tuple.rs +++ b/src/test/mir-opt/early_otherwise_branch_3_element_tuple.rs @@ -1,4 +1,4 @@ -// compile-flags: -Z mir-opt-level=4 -Z unsound-mir-opts +// unit-test: EarlyOtherwiseBranch // EMIT_MIR early_otherwise_branch_3_element_tuple.opt1.EarlyOtherwiseBranch.diff fn opt1(x: Option<u32>, y: Option<u32>, z: Option<u32>) -> u32 { diff --git a/src/test/mir-opt/early_otherwise_branch_68867.try_sum.EarlyOtherwiseBranch.before-SimplifyConstCondition-final.after.diff b/src/test/mir-opt/early_otherwise_branch_68867.try_sum.EarlyOtherwiseBranch.before-SimplifyConstCondition-final.after.diff index 592388e69a9..67ce0c2aabb 100644 --- a/src/test/mir-opt/early_otherwise_branch_68867.try_sum.EarlyOtherwiseBranch.before-SimplifyConstCondition-final.after.diff +++ b/src/test/mir-opt/early_otherwise_branch_68867.try_sum.EarlyOtherwiseBranch.before-SimplifyConstCondition-final.after.diff @@ -36,8 +36,19 @@ let mut _31: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:25:50: 25:55 let mut _32: !; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:26:14: 26:28 let mut _33: (); // in scope 0 at $DIR/early_otherwise_branch_68867.rs:26:25: 26:27 -+ let mut _34: isize; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:21:8: 21:24 -+ let mut _35: bool; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:21:8: 21:24 + let mut _34: &ViewportPercentageLength; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24 + let mut _35: &ViewportPercentageLength; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24 + let mut _36: &ViewportPercentageLength; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24 + let mut _37: &ViewportPercentageLength; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24 + let mut _38: &ViewportPercentageLength; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24 + let mut _39: &ViewportPercentageLength; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24 + let mut _40: &ViewportPercentageLength; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24 + let mut _41: &ViewportPercentageLength; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24 + let mut _42: &ViewportPercentageLength; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24 + let mut _43: &ViewportPercentageLength; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24 + let mut _44: &ViewportPercentageLength; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24 + let mut _45: &ViewportPercentageLength; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24 + let mut _46: &ViewportPercentageLength; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24 scope 1 { - debug one => _12; // in scope 1 at $DIR/early_otherwise_branch_68867.rs:22:14: 22:17 - debug other => _13; // in scope 1 at $DIR/early_otherwise_branch_68867.rs:22:24: 22:29 @@ -81,27 +92,26 @@ StorageDead(_6); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:23: 21:24 - StorageDead(_5); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:23: 21:24 + nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:23: 21:24 - _11 = discriminant((*(_4.0: &ViewportPercentageLength))); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24 -- switchInt(move _11) -> [0_isize: bb1, 1_isize: bb3, 2_isize: bb4, 3_isize: bb5, otherwise: bb11]; // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:8: 21:24 -+ StorageLive(_34); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:8: 21:24 -+ _34 = discriminant((*(_4.1: &ViewportPercentageLength))); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:8: 21:24 -+ StorageLive(_35); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:8: 21:24 -+ _35 = Ne(_11, move _34); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:8: 21:24 -+ StorageDead(_34); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:8: 21:24 -+ switchInt(move _35) -> [false: bb7, otherwise: bb1]; // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:8: 21:24 + StorageLive(_34); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24 + _34 = move (_4.0: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24 + _11 = discriminant((*_34)); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24 + StorageDead(_34); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:8: 21:24 + switchInt(move _11) -> [0_isize: bb1, 1_isize: bb3, 2_isize: bb4, 3_isize: bb5, otherwise: bb2]; // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:8: 21:24 } bb1: { -- _7 = discriminant((*(_4.1: &ViewportPercentageLength))); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24 -- switchInt(move _7) -> [0_isize: bb6, otherwise: bb2]; // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:8: 21:24 -- } -- -- bb2: { -+ StorageDead(_35); // scope 0 at $DIR/early_otherwise_branch_68867.rs:26:25: 26:27 + StorageLive(_35); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24 + _35 = move (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24 + _7 = discriminant((*_35)); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24 + StorageDead(_35); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:8: 21:24 + switchInt(move _7) -> [0_isize: bb6, otherwise: bb2]; // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:8: 21:24 + } + + bb2: { StorageLive(_33); // scope 0 at $DIR/early_otherwise_branch_68867.rs:26:25: 26:27 -- nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:26:25: 26:27 + nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:26:25: 26:27 Deinit(_0); // scope 0 at $DIR/early_otherwise_branch_68867.rs:26:21: 26:28 -- nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:26:21: 26:28 + nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:26:21: 26:28 discriminant(_0) = 1; // scope 0 at $DIR/early_otherwise_branch_68867.rs:26:21: 26:28 StorageDead(_33); // scope 0 at $DIR/early_otherwise_branch_68867.rs:26:27: 26:28 - StorageDead(_3); // scope 0 at $DIR/early_otherwise_branch_68867.rs:27:6: 27:7 @@ -111,105 +121,45 @@ return; // scope 0 at $DIR/early_otherwise_branch_68867.rs:28:2: 28:2 } -+ bb2: { -+ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:14: 22:17 -+ _15 = (((*(_4.0: &ViewportPercentageLength)) as Vw).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:14: 22:17 -+ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:24: 22:29 -+ _16 = (((*(_4.1: &ViewportPercentageLength)) as Vw).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:24: 22:29 -+ nop; // scope 1 at $DIR/early_otherwise_branch_68867.rs:22:38: 22:49 -+ nop; // scope 1 at $DIR/early_otherwise_branch_68867.rs:22:38: 22:41 -+ nop; // scope 1 at $DIR/early_otherwise_branch_68867.rs:22:38: 22:41 -+ nop; // scope 1 at $DIR/early_otherwise_branch_68867.rs:22:44: 22:49 -+ nop; // scope 1 at $DIR/early_otherwise_branch_68867.rs:22:44: 22:49 -+ ((((_0 as Ok).0: ViewportPercentageLength) as Vw).0: f32) = Add(move _15, move _16); // scope 1 at $DIR/early_otherwise_branch_68867.rs:22:38: 22:49 -+ nop; // scope 1 at $DIR/early_otherwise_branch_68867.rs:22:48: 22:49 -+ nop; // scope 1 at $DIR/early_otherwise_branch_68867.rs:22:48: 22:49 -+ Deinit(((_0 as Ok).0: ViewportPercentageLength)); // scope 1 at $DIR/early_otherwise_branch_68867.rs:22:35: 22:50 -+ nop; // scope 1 at $DIR/early_otherwise_branch_68867.rs:22:35: 22:50 -+ discriminant(((_0 as Ok).0: ViewportPercentageLength)) = 0; // scope 1 at $DIR/early_otherwise_branch_68867.rs:22:35: 22:50 -+ nop; // scope 1 at $DIR/early_otherwise_branch_68867.rs:22:49: 22:50 -+ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:49: 22:50 -+ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:49: 22:50 -+ goto -> bb6; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:49: 22:50 -+ } -+ bb3: { -- _8 = discriminant((*(_4.1: &ViewportPercentageLength))); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24 -- switchInt(move _8) -> [1_isize: bb7, otherwise: bb2]; // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:8: 21:24 -+ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:14: 23:17 -+ _20 = (((*(_4.0: &ViewportPercentageLength)) as Vh).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:14: 23:17 -+ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:24: 23:29 -+ _21 = (((*(_4.1: &ViewportPercentageLength)) as Vh).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:24: 23:29 -+ nop; // scope 2 at $DIR/early_otherwise_branch_68867.rs:23:38: 23:49 -+ nop; // scope 2 at $DIR/early_otherwise_branch_68867.rs:23:38: 23:41 -+ nop; // scope 2 at $DIR/early_otherwise_branch_68867.rs:23:38: 23:41 -+ nop; // scope 2 at $DIR/early_otherwise_branch_68867.rs:23:44: 23:49 -+ nop; // scope 2 at $DIR/early_otherwise_branch_68867.rs:23:44: 23:49 -+ ((((_0 as Ok).0: ViewportPercentageLength) as Vh).0: f32) = Add(move _20, move _21); // scope 2 at $DIR/early_otherwise_branch_68867.rs:23:38: 23:49 -+ nop; // scope 2 at $DIR/early_otherwise_branch_68867.rs:23:48: 23:49 -+ nop; // scope 2 at $DIR/early_otherwise_branch_68867.rs:23:48: 23:49 -+ Deinit(((_0 as Ok).0: ViewportPercentageLength)); // scope 2 at $DIR/early_otherwise_branch_68867.rs:23:35: 23:50 -+ nop; // scope 2 at $DIR/early_otherwise_branch_68867.rs:23:35: 23:50 -+ discriminant(((_0 as Ok).0: ViewportPercentageLength)) = 1; // scope 2 at $DIR/early_otherwise_branch_68867.rs:23:35: 23:50 -+ nop; // scope 2 at $DIR/early_otherwise_branch_68867.rs:23:49: 23:50 -+ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:49: 23:50 -+ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:49: 23:50 -+ goto -> bb6; // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:49: 23:50 + StorageLive(_36); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24 + _36 = move (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24 + _8 = discriminant((*_36)); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24 + StorageDead(_36); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:8: 21:24 + switchInt(move _8) -> [1_isize: bb7, otherwise: bb2]; // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:8: 21:24 } bb4: { -- _9 = discriminant((*(_4.1: &ViewportPercentageLength))); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24 -- switchInt(move _9) -> [2_isize: bb8, otherwise: bb2]; // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:8: 21:24 -+ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:16: 24:19 -+ _25 = (((*(_4.0: &ViewportPercentageLength)) as Vmin).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:16: 24:19 -+ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:28: 24:33 -+ _26 = (((*(_4.1: &ViewportPercentageLength)) as Vmin).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:28: 24:33 -+ nop; // scope 3 at $DIR/early_otherwise_branch_68867.rs:24:44: 24:55 -+ nop; // scope 3 at $DIR/early_otherwise_branch_68867.rs:24:44: 24:47 -+ nop; // scope 3 at $DIR/early_otherwise_branch_68867.rs:24:44: 24:47 -+ nop; // scope 3 at $DIR/early_otherwise_branch_68867.rs:24:50: 24:55 -+ nop; // scope 3 at $DIR/early_otherwise_branch_68867.rs:24:50: 24:55 -+ ((((_0 as Ok).0: ViewportPercentageLength) as Vmin).0: f32) = Add(move _25, move _26); // scope 3 at $DIR/early_otherwise_branch_68867.rs:24:44: 24:55 -+ nop; // scope 3 at $DIR/early_otherwise_branch_68867.rs:24:54: 24:55 -+ nop; // scope 3 at $DIR/early_otherwise_branch_68867.rs:24:54: 24:55 -+ Deinit(((_0 as Ok).0: ViewportPercentageLength)); // scope 3 at $DIR/early_otherwise_branch_68867.rs:24:39: 24:56 -+ nop; // scope 3 at $DIR/early_otherwise_branch_68867.rs:24:39: 24:56 -+ discriminant(((_0 as Ok).0: ViewportPercentageLength)) = 2; // scope 3 at $DIR/early_otherwise_branch_68867.rs:24:39: 24:56 -+ nop; // scope 3 at $DIR/early_otherwise_branch_68867.rs:24:55: 24:56 -+ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:55: 24:56 -+ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:55: 24:56 -+ goto -> bb6; // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:55: 24:56 + StorageLive(_37); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24 + _37 = move (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24 + _9 = discriminant((*_37)); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24 + StorageDead(_37); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:8: 21:24 + switchInt(move _9) -> [2_isize: bb8, otherwise: bb2]; // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:8: 21:24 } bb5: { -- _10 = discriminant((*(_4.1: &ViewportPercentageLength))); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24 -- switchInt(move _10) -> [3_isize: bb9, otherwise: bb2]; // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:8: 21:24 -+ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:16: 25:19 -+ _30 = (((*(_4.0: &ViewportPercentageLength)) as Vmax).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:16: 25:19 -+ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:28: 25:33 -+ _31 = (((*(_4.1: &ViewportPercentageLength)) as Vmax).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:28: 25:33 -+ nop; // scope 4 at $DIR/early_otherwise_branch_68867.rs:25:44: 25:55 -+ nop; // scope 4 at $DIR/early_otherwise_branch_68867.rs:25:44: 25:47 -+ nop; // scope 4 at $DIR/early_otherwise_branch_68867.rs:25:44: 25:47 -+ nop; // scope 4 at $DIR/early_otherwise_branch_68867.rs:25:50: 25:55 -+ nop; // scope 4 at $DIR/early_otherwise_branch_68867.rs:25:50: 25:55 -+ ((((_0 as Ok).0: ViewportPercentageLength) as Vmax).0: f32) = Add(move _30, move _31); // scope 4 at $DIR/early_otherwise_branch_68867.rs:25:44: 25:55 -+ nop; // scope 4 at $DIR/early_otherwise_branch_68867.rs:25:54: 25:55 -+ nop; // scope 4 at $DIR/early_otherwise_branch_68867.rs:25:54: 25:55 -+ Deinit(((_0 as Ok).0: ViewportPercentageLength)); // scope 4 at $DIR/early_otherwise_branch_68867.rs:25:39: 25:56 -+ nop; // scope 4 at $DIR/early_otherwise_branch_68867.rs:25:39: 25:56 -+ discriminant(((_0 as Ok).0: ViewportPercentageLength)) = 3; // scope 4 at $DIR/early_otherwise_branch_68867.rs:25:39: 25:56 -+ nop; // scope 4 at $DIR/early_otherwise_branch_68867.rs:25:55: 25:56 -+ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:55: 25:56 -+ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:55: 25:56 -+ goto -> bb6; // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:55: 25:56 + StorageLive(_38); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24 + _38 = move (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24 + _10 = discriminant((*_38)); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24 + StorageDead(_38); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:8: 21:24 + switchInt(move _10) -> [3_isize: bb9, otherwise: bb2]; // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:8: 21:24 } bb6: { - StorageLive(_12); // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:14: 22:17 -- _12 = (((*(_4.0: &ViewportPercentageLength)) as Vw).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:14: 22:17 ++ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:14: 22:17 + StorageLive(_39); // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:14: 22:17 + _39 = move (_4.0: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:14: 22:17 +- _12 = (((*_39) as Vw).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:14: 22:17 ++ _15 = (((*_39) as Vw).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:14: 22:17 + StorageDead(_39); // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:24: 22:29 - StorageLive(_13); // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:24: 22:29 -- _13 = (((*(_4.1: &ViewportPercentageLength)) as Vw).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:24: 22:29 ++ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:24: 22:29 + StorageLive(_40); // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:24: 22:29 + _40 = move (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:24: 22:29 +- _13 = (((*_40) as Vw).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:24: 22:29 ++ _16 = (((*_40) as Vw).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:24: 22:29 + StorageDead(_40); // scope 1 at $DIR/early_otherwise_branch_68867.rs:22:38: 22:49 - StorageLive(_14); // scope 1 at $DIR/early_otherwise_branch_68867.rs:22:38: 22:49 - StorageLive(_15); // scope 1 at $DIR/early_otherwise_branch_68867.rs:22:38: 22:41 - _15 = _12; // scope 1 at $DIR/early_otherwise_branch_68867.rs:22:38: 22:41 @@ -224,14 +174,38 @@ - StorageDead(_14); // scope 1 at $DIR/early_otherwise_branch_68867.rs:22:49: 22:50 - StorageDead(_13); // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:49: 22:50 - StorageDead(_12); // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:49: 22:50 -- goto -> bb10; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:49: 22:50 -- } -- -- bb7: { ++ nop; // scope 1 at $DIR/early_otherwise_branch_68867.rs:22:38: 22:49 ++ nop; // scope 1 at $DIR/early_otherwise_branch_68867.rs:22:38: 22:41 ++ nop; // scope 1 at $DIR/early_otherwise_branch_68867.rs:22:38: 22:41 ++ nop; // scope 1 at $DIR/early_otherwise_branch_68867.rs:22:44: 22:49 ++ nop; // scope 1 at $DIR/early_otherwise_branch_68867.rs:22:44: 22:49 ++ ((((_0 as Ok).0: ViewportPercentageLength) as Vw).0: f32) = Add(move _15, move _16); // scope 1 at $DIR/early_otherwise_branch_68867.rs:22:38: 22:49 ++ nop; // scope 1 at $DIR/early_otherwise_branch_68867.rs:22:48: 22:49 ++ nop; // scope 1 at $DIR/early_otherwise_branch_68867.rs:22:48: 22:49 ++ Deinit(((_0 as Ok).0: ViewportPercentageLength)); // scope 1 at $DIR/early_otherwise_branch_68867.rs:22:35: 22:50 ++ nop; // scope 1 at $DIR/early_otherwise_branch_68867.rs:22:35: 22:50 ++ discriminant(((_0 as Ok).0: ViewportPercentageLength)) = 0; // scope 1 at $DIR/early_otherwise_branch_68867.rs:22:35: 22:50 ++ nop; // scope 1 at $DIR/early_otherwise_branch_68867.rs:22:49: 22:50 ++ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:49: 22:50 ++ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:49: 22:50 + goto -> bb10; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:49: 22:50 + } + + bb7: { - StorageLive(_17); // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:14: 23:17 -- _17 = (((*(_4.0: &ViewportPercentageLength)) as Vh).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:14: 23:17 ++ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:14: 23:17 + StorageLive(_41); // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:14: 23:17 + _41 = move (_4.0: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:14: 23:17 +- _17 = (((*_41) as Vh).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:14: 23:17 ++ _20 = (((*_41) as Vh).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:14: 23:17 + StorageDead(_41); // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:24: 23:29 - StorageLive(_18); // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:24: 23:29 -- _18 = (((*(_4.1: &ViewportPercentageLength)) as Vh).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:24: 23:29 ++ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:24: 23:29 + StorageLive(_42); // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:24: 23:29 + _42 = move (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:24: 23:29 +- _18 = (((*_42) as Vh).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:24: 23:29 ++ _21 = (((*_42) as Vh).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:24: 23:29 + StorageDead(_42); // scope 2 at $DIR/early_otherwise_branch_68867.rs:23:38: 23:49 - StorageLive(_19); // scope 2 at $DIR/early_otherwise_branch_68867.rs:23:38: 23:49 - StorageLive(_20); // scope 2 at $DIR/early_otherwise_branch_68867.rs:23:38: 23:41 - _20 = _17; // scope 2 at $DIR/early_otherwise_branch_68867.rs:23:38: 23:41 @@ -246,14 +220,38 @@ - StorageDead(_19); // scope 2 at $DIR/early_otherwise_branch_68867.rs:23:49: 23:50 - StorageDead(_18); // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:49: 23:50 - StorageDead(_17); // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:49: 23:50 -- goto -> bb10; // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:49: 23:50 -- } -- -- bb8: { ++ nop; // scope 2 at $DIR/early_otherwise_branch_68867.rs:23:38: 23:49 ++ nop; // scope 2 at $DIR/early_otherwise_branch_68867.rs:23:38: 23:41 ++ nop; // scope 2 at $DIR/early_otherwise_branch_68867.rs:23:38: 23:41 ++ nop; // scope 2 at $DIR/early_otherwise_branch_68867.rs:23:44: 23:49 ++ nop; // scope 2 at $DIR/early_otherwise_branch_68867.rs:23:44: 23:49 ++ ((((_0 as Ok).0: ViewportPercentageLength) as Vh).0: f32) = Add(move _20, move _21); // scope 2 at $DIR/early_otherwise_branch_68867.rs:23:38: 23:49 ++ nop; // scope 2 at $DIR/early_otherwise_branch_68867.rs:23:48: 23:49 ++ nop; // scope 2 at $DIR/early_otherwise_branch_68867.rs:23:48: 23:49 ++ Deinit(((_0 as Ok).0: ViewportPercentageLength)); // scope 2 at $DIR/early_otherwise_branch_68867.rs:23:35: 23:50 ++ nop; // scope 2 at $DIR/early_otherwise_branch_68867.rs:23:35: 23:50 ++ discriminant(((_0 as Ok).0: ViewportPercentageLength)) = 1; // scope 2 at $DIR/early_otherwise_branch_68867.rs:23:35: 23:50 ++ nop; // scope 2 at $DIR/early_otherwise_branch_68867.rs:23:49: 23:50 ++ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:49: 23:50 ++ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:49: 23:50 + goto -> bb10; // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:49: 23:50 + } + + bb8: { - StorageLive(_22); // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:16: 24:19 -- _22 = (((*(_4.0: &ViewportPercentageLength)) as Vmin).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:16: 24:19 ++ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:16: 24:19 + StorageLive(_43); // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:16: 24:19 + _43 = move (_4.0: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:16: 24:19 +- _22 = (((*_43) as Vmin).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:16: 24:19 ++ _25 = (((*_43) as Vmin).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:16: 24:19 + StorageDead(_43); // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:28: 24:33 - StorageLive(_23); // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:28: 24:33 -- _23 = (((*(_4.1: &ViewportPercentageLength)) as Vmin).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:28: 24:33 ++ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:28: 24:33 + StorageLive(_44); // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:28: 24:33 + _44 = move (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:28: 24:33 +- _23 = (((*_44) as Vmin).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:28: 24:33 ++ _26 = (((*_44) as Vmin).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:28: 24:33 + StorageDead(_44); // scope 3 at $DIR/early_otherwise_branch_68867.rs:24:44: 24:55 - StorageLive(_24); // scope 3 at $DIR/early_otherwise_branch_68867.rs:24:44: 24:55 - StorageLive(_25); // scope 3 at $DIR/early_otherwise_branch_68867.rs:24:44: 24:47 - _25 = _22; // scope 3 at $DIR/early_otherwise_branch_68867.rs:24:44: 24:47 @@ -268,14 +266,38 @@ - StorageDead(_24); // scope 3 at $DIR/early_otherwise_branch_68867.rs:24:55: 24:56 - StorageDead(_23); // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:55: 24:56 - StorageDead(_22); // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:55: 24:56 -- goto -> bb10; // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:55: 24:56 -- } -- -- bb9: { ++ nop; // scope 3 at $DIR/early_otherwise_branch_68867.rs:24:44: 24:55 ++ nop; // scope 3 at $DIR/early_otherwise_branch_68867.rs:24:44: 24:47 ++ nop; // scope 3 at $DIR/early_otherwise_branch_68867.rs:24:44: 24:47 ++ nop; // scope 3 at $DIR/early_otherwise_branch_68867.rs:24:50: 24:55 ++ nop; // scope 3 at $DIR/early_otherwise_branch_68867.rs:24:50: 24:55 ++ ((((_0 as Ok).0: ViewportPercentageLength) as Vmin).0: f32) = Add(move _25, move _26); // scope 3 at $DIR/early_otherwise_branch_68867.rs:24:44: 24:55 ++ nop; // scope 3 at $DIR/early_otherwise_branch_68867.rs:24:54: 24:55 ++ nop; // scope 3 at $DIR/early_otherwise_branch_68867.rs:24:54: 24:55 ++ Deinit(((_0 as Ok).0: ViewportPercentageLength)); // scope 3 at $DIR/early_otherwise_branch_68867.rs:24:39: 24:56 ++ nop; // scope 3 at $DIR/early_otherwise_branch_68867.rs:24:39: 24:56 ++ discriminant(((_0 as Ok).0: ViewportPercentageLength)) = 2; // scope 3 at $DIR/early_otherwise_branch_68867.rs:24:39: 24:56 ++ nop; // scope 3 at $DIR/early_otherwise_branch_68867.rs:24:55: 24:56 ++ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:55: 24:56 ++ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:55: 24:56 + goto -> bb10; // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:55: 24:56 + } + + bb9: { - StorageLive(_27); // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:16: 25:19 -- _27 = (((*(_4.0: &ViewportPercentageLength)) as Vmax).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:16: 25:19 ++ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:16: 25:19 + StorageLive(_45); // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:16: 25:19 + _45 = move (_4.0: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:16: 25:19 +- _27 = (((*_45) as Vmax).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:16: 25:19 ++ _30 = (((*_45) as Vmax).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:16: 25:19 + StorageDead(_45); // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:28: 25:33 - StorageLive(_28); // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:28: 25:33 -- _28 = (((*(_4.1: &ViewportPercentageLength)) as Vmax).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:28: 25:33 ++ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:28: 25:33 + StorageLive(_46); // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:28: 25:33 + _46 = move (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:28: 25:33 +- _28 = (((*_46) as Vmax).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:28: 25:33 ++ _31 = (((*_46) as Vmax).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:28: 25:33 + StorageDead(_46); // scope 4 at $DIR/early_otherwise_branch_68867.rs:25:44: 25:55 - StorageLive(_29); // scope 4 at $DIR/early_otherwise_branch_68867.rs:25:44: 25:55 - StorageLive(_30); // scope 4 at $DIR/early_otherwise_branch_68867.rs:25:44: 25:47 - _30 = _27; // scope 4 at $DIR/early_otherwise_branch_68867.rs:25:44: 25:47 @@ -290,10 +312,24 @@ - StorageDead(_29); // scope 4 at $DIR/early_otherwise_branch_68867.rs:25:55: 25:56 - StorageDead(_28); // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:55: 25:56 - StorageDead(_27); // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:55: 25:56 -- goto -> bb10; // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:55: 25:56 -- } -- -- bb10: { ++ nop; // scope 4 at $DIR/early_otherwise_branch_68867.rs:25:44: 25:55 ++ nop; // scope 4 at $DIR/early_otherwise_branch_68867.rs:25:44: 25:47 ++ nop; // scope 4 at $DIR/early_otherwise_branch_68867.rs:25:44: 25:47 ++ nop; // scope 4 at $DIR/early_otherwise_branch_68867.rs:25:50: 25:55 ++ nop; // scope 4 at $DIR/early_otherwise_branch_68867.rs:25:50: 25:55 ++ ((((_0 as Ok).0: ViewportPercentageLength) as Vmax).0: f32) = Add(move _30, move _31); // scope 4 at $DIR/early_otherwise_branch_68867.rs:25:44: 25:55 ++ nop; // scope 4 at $DIR/early_otherwise_branch_68867.rs:25:54: 25:55 ++ nop; // scope 4 at $DIR/early_otherwise_branch_68867.rs:25:54: 25:55 ++ Deinit(((_0 as Ok).0: ViewportPercentageLength)); // scope 4 at $DIR/early_otherwise_branch_68867.rs:25:39: 25:56 ++ nop; // scope 4 at $DIR/early_otherwise_branch_68867.rs:25:39: 25:56 ++ discriminant(((_0 as Ok).0: ViewportPercentageLength)) = 3; // scope 4 at $DIR/early_otherwise_branch_68867.rs:25:39: 25:56 ++ nop; // scope 4 at $DIR/early_otherwise_branch_68867.rs:25:55: 25:56 ++ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:55: 25:56 ++ nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:55: 25:56 + goto -> bb10; // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:55: 25:56 + } + + bb10: { Deinit(_0); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:5: 27:7 - ((_0 as Ok).0: ViewportPercentageLength) = move _3; // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:5: 27:7 + nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:5: 27:7 @@ -304,12 +340,5 @@ + nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:28:1: 28:2 return; // scope 0 at $DIR/early_otherwise_branch_68867.rs:28:2: 28:2 } - -- bb11: { -- unreachable; // scope 0 at $DIR/early_otherwise_branch_68867.rs:28:2: 28:2 -+ bb7: { -+ StorageDead(_35); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:8: 21:24 -+ switchInt(_11) -> [0_isize: bb2, 1_isize: bb3, 2_isize: bb4, 3_isize: bb5, otherwise: bb1]; // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:8: 21:24 - } } diff --git a/src/test/mir-opt/early_otherwise_branch_68867.try_sum.EarlyOtherwiseBranch.diff b/src/test/mir-opt/early_otherwise_branch_68867.try_sum.EarlyOtherwiseBranch.diff index 4cd34ba38ba..c2b00f915a4 100644 --- a/src/test/mir-opt/early_otherwise_branch_68867.try_sum.EarlyOtherwiseBranch.diff +++ b/src/test/mir-opt/early_otherwise_branch_68867.try_sum.EarlyOtherwiseBranch.diff @@ -36,8 +36,19 @@ let mut _31: f32; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:25:50: 25:55 let mut _32: !; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:26:14: 26:28 let mut _33: (); // in scope 0 at $DIR/early_otherwise_branch_68867.rs:26:25: 26:27 -+ let mut _34: isize; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:21:8: 21:24 -+ let mut _35: bool; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:21:8: 21:24 + let mut _34: &ViewportPercentageLength; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24 + let mut _35: &ViewportPercentageLength; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24 + let mut _36: &ViewportPercentageLength; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24 + let mut _37: &ViewportPercentageLength; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24 + let mut _38: &ViewportPercentageLength; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24 + let mut _39: &ViewportPercentageLength; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24 + let mut _40: &ViewportPercentageLength; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24 + let mut _41: &ViewportPercentageLength; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24 + let mut _42: &ViewportPercentageLength; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24 + let mut _43: &ViewportPercentageLength; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24 + let mut _44: &ViewportPercentageLength; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24 + let mut _45: &ViewportPercentageLength; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24 + let mut _46: &ViewportPercentageLength; // in scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24 scope 1 { debug one => _12; // in scope 1 at $DIR/early_otherwise_branch_68867.rs:22:14: 22:17 debug other => _13; // in scope 1 at $DIR/early_otherwise_branch_68867.rs:22:24: 22:29 @@ -67,27 +78,26 @@ (_4.1: &ViewportPercentageLength) = move _6; // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24 StorageDead(_6); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:23: 21:24 StorageDead(_5); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:23: 21:24 - _11 = discriminant((*(_4.0: &ViewportPercentageLength))); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24 -- switchInt(move _11) -> [0_isize: bb1, 1_isize: bb3, 2_isize: bb4, 3_isize: bb5, otherwise: bb11]; // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:8: 21:24 -+ StorageLive(_34); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:8: 21:24 -+ _34 = discriminant((*(_4.1: &ViewportPercentageLength))); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:8: 21:24 -+ StorageLive(_35); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:8: 21:24 -+ _35 = Ne(_11, move _34); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:8: 21:24 -+ StorageDead(_34); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:8: 21:24 -+ switchInt(move _35) -> [false: bb7, otherwise: bb1]; // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:8: 21:24 + StorageLive(_34); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24 + _34 = move (_4.0: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24 + _11 = discriminant((*_34)); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24 + StorageDead(_34); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:8: 21:24 + switchInt(move _11) -> [0_isize: bb1, 1_isize: bb3, 2_isize: bb4, 3_isize: bb5, otherwise: bb2]; // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:8: 21:24 } bb1: { -- _7 = discriminant((*(_4.1: &ViewportPercentageLength))); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24 -- switchInt(move _7) -> [0_isize: bb6, otherwise: bb2]; // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:8: 21:24 -- } -- -- bb2: { -+ StorageDead(_35); // scope 0 at $DIR/early_otherwise_branch_68867.rs:26:25: 26:27 + StorageLive(_35); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24 + _35 = move (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24 + _7 = discriminant((*_35)); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24 + StorageDead(_35); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:8: 21:24 + switchInt(move _7) -> [0_isize: bb6, otherwise: bb2]; // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:8: 21:24 + } + + bb2: { StorageLive(_33); // scope 0 at $DIR/early_otherwise_branch_68867.rs:26:25: 26:27 -- nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:26:25: 26:27 + nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:26:25: 26:27 Deinit(_0); // scope 0 at $DIR/early_otherwise_branch_68867.rs:26:21: 26:28 -- nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:26:21: 26:28 + nop; // scope 0 at $DIR/early_otherwise_branch_68867.rs:26:21: 26:28 discriminant(_0) = 1; // scope 0 at $DIR/early_otherwise_branch_68867.rs:26:21: 26:28 StorageDead(_33); // scope 0 at $DIR/early_otherwise_branch_68867.rs:26:27: 26:28 StorageDead(_3); // scope 0 at $DIR/early_otherwise_branch_68867.rs:27:6: 27:7 @@ -95,27 +105,41 @@ return; // scope 0 at $DIR/early_otherwise_branch_68867.rs:28:2: 28:2 } -- bb3: { -- _8 = discriminant((*(_4.1: &ViewportPercentageLength))); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24 -- switchInt(move _8) -> [1_isize: bb7, otherwise: bb2]; // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:8: 21:24 -- } -- -- bb4: { -- _9 = discriminant((*(_4.1: &ViewportPercentageLength))); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24 -- switchInt(move _9) -> [2_isize: bb8, otherwise: bb2]; // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:8: 21:24 -- } -- -- bb5: { -- _10 = discriminant((*(_4.1: &ViewportPercentageLength))); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24 -- switchInt(move _10) -> [3_isize: bb9, otherwise: bb2]; // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:8: 21:24 -- } -- -- bb6: { -+ bb2: { + bb3: { + StorageLive(_36); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24 + _36 = move (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24 + _8 = discriminant((*_36)); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24 + StorageDead(_36); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:8: 21:24 + switchInt(move _8) -> [1_isize: bb7, otherwise: bb2]; // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:8: 21:24 + } + + bb4: { + StorageLive(_37); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24 + _37 = move (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24 + _9 = discriminant((*_37)); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24 + StorageDead(_37); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:8: 21:24 + switchInt(move _9) -> [2_isize: bb8, otherwise: bb2]; // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:8: 21:24 + } + + bb5: { + StorageLive(_38); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24 + _38 = move (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24 + _10 = discriminant((*_38)); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:14: 21:24 + StorageDead(_38); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:8: 21:24 + switchInt(move _10) -> [3_isize: bb9, otherwise: bb2]; // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:8: 21:24 + } + + bb6: { StorageLive(_12); // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:14: 22:17 - _12 = (((*(_4.0: &ViewportPercentageLength)) as Vw).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:14: 22:17 + StorageLive(_39); // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:14: 22:17 + _39 = move (_4.0: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:14: 22:17 + _12 = (((*_39) as Vw).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:14: 22:17 + StorageDead(_39); // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:24: 22:29 StorageLive(_13); // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:24: 22:29 - _13 = (((*(_4.1: &ViewportPercentageLength)) as Vw).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:24: 22:29 + StorageLive(_40); // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:24: 22:29 + _40 = move (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:24: 22:29 + _13 = (((*_40) as Vw).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:24: 22:29 + StorageDead(_40); // scope 1 at $DIR/early_otherwise_branch_68867.rs:22:38: 22:49 StorageLive(_14); // scope 1 at $DIR/early_otherwise_branch_68867.rs:22:38: 22:49 StorageLive(_15); // scope 1 at $DIR/early_otherwise_branch_68867.rs:22:38: 22:41 _15 = _12; // scope 1 at $DIR/early_otherwise_branch_68867.rs:22:38: 22:41 @@ -130,16 +154,20 @@ StorageDead(_14); // scope 1 at $DIR/early_otherwise_branch_68867.rs:22:49: 22:50 StorageDead(_13); // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:49: 22:50 StorageDead(_12); // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:49: 22:50 -- goto -> bb10; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:49: 22:50 -+ goto -> bb6; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:49: 22:50 + goto -> bb10; // scope 0 at $DIR/early_otherwise_branch_68867.rs:22:49: 22:50 } -- bb7: { -+ bb3: { + bb7: { StorageLive(_17); // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:14: 23:17 - _17 = (((*(_4.0: &ViewportPercentageLength)) as Vh).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:14: 23:17 + StorageLive(_41); // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:14: 23:17 + _41 = move (_4.0: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:14: 23:17 + _17 = (((*_41) as Vh).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:14: 23:17 + StorageDead(_41); // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:24: 23:29 StorageLive(_18); // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:24: 23:29 - _18 = (((*(_4.1: &ViewportPercentageLength)) as Vh).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:24: 23:29 + StorageLive(_42); // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:24: 23:29 + _42 = move (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:24: 23:29 + _18 = (((*_42) as Vh).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:24: 23:29 + StorageDead(_42); // scope 2 at $DIR/early_otherwise_branch_68867.rs:23:38: 23:49 StorageLive(_19); // scope 2 at $DIR/early_otherwise_branch_68867.rs:23:38: 23:49 StorageLive(_20); // scope 2 at $DIR/early_otherwise_branch_68867.rs:23:38: 23:41 _20 = _17; // scope 2 at $DIR/early_otherwise_branch_68867.rs:23:38: 23:41 @@ -154,16 +182,20 @@ StorageDead(_19); // scope 2 at $DIR/early_otherwise_branch_68867.rs:23:49: 23:50 StorageDead(_18); // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:49: 23:50 StorageDead(_17); // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:49: 23:50 -- goto -> bb10; // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:49: 23:50 -+ goto -> bb6; // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:49: 23:50 + goto -> bb10; // scope 0 at $DIR/early_otherwise_branch_68867.rs:23:49: 23:50 } -- bb8: { -+ bb4: { + bb8: { StorageLive(_22); // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:16: 24:19 - _22 = (((*(_4.0: &ViewportPercentageLength)) as Vmin).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:16: 24:19 + StorageLive(_43); // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:16: 24:19 + _43 = move (_4.0: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:16: 24:19 + _22 = (((*_43) as Vmin).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:16: 24:19 + StorageDead(_43); // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:28: 24:33 StorageLive(_23); // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:28: 24:33 - _23 = (((*(_4.1: &ViewportPercentageLength)) as Vmin).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:28: 24:33 + StorageLive(_44); // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:28: 24:33 + _44 = move (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:28: 24:33 + _23 = (((*_44) as Vmin).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:28: 24:33 + StorageDead(_44); // scope 3 at $DIR/early_otherwise_branch_68867.rs:24:44: 24:55 StorageLive(_24); // scope 3 at $DIR/early_otherwise_branch_68867.rs:24:44: 24:55 StorageLive(_25); // scope 3 at $DIR/early_otherwise_branch_68867.rs:24:44: 24:47 _25 = _22; // scope 3 at $DIR/early_otherwise_branch_68867.rs:24:44: 24:47 @@ -178,16 +210,20 @@ StorageDead(_24); // scope 3 at $DIR/early_otherwise_branch_68867.rs:24:55: 24:56 StorageDead(_23); // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:55: 24:56 StorageDead(_22); // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:55: 24:56 -- goto -> bb10; // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:55: 24:56 -+ goto -> bb6; // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:55: 24:56 + goto -> bb10; // scope 0 at $DIR/early_otherwise_branch_68867.rs:24:55: 24:56 } -- bb9: { -+ bb5: { + bb9: { StorageLive(_27); // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:16: 25:19 - _27 = (((*(_4.0: &ViewportPercentageLength)) as Vmax).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:16: 25:19 + StorageLive(_45); // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:16: 25:19 + _45 = move (_4.0: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:16: 25:19 + _27 = (((*_45) as Vmax).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:16: 25:19 + StorageDead(_45); // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:28: 25:33 StorageLive(_28); // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:28: 25:33 - _28 = (((*(_4.1: &ViewportPercentageLength)) as Vmax).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:28: 25:33 + StorageLive(_46); // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:28: 25:33 + _46 = move (_4.1: &ViewportPercentageLength); // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:28: 25:33 + _28 = (((*_46) as Vmax).0: f32); // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:28: 25:33 + StorageDead(_46); // scope 4 at $DIR/early_otherwise_branch_68867.rs:25:44: 25:55 StorageLive(_29); // scope 4 at $DIR/early_otherwise_branch_68867.rs:25:44: 25:55 StorageLive(_30); // scope 4 at $DIR/early_otherwise_branch_68867.rs:25:44: 25:47 _30 = _27; // scope 4 at $DIR/early_otherwise_branch_68867.rs:25:44: 25:47 @@ -202,12 +238,10 @@ StorageDead(_29); // scope 4 at $DIR/early_otherwise_branch_68867.rs:25:55: 25:56 StorageDead(_28); // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:55: 25:56 StorageDead(_27); // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:55: 25:56 -- goto -> bb10; // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:55: 25:56 -+ goto -> bb6; // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:55: 25:56 + goto -> bb10; // scope 0 at $DIR/early_otherwise_branch_68867.rs:25:55: 25:56 } -- bb10: { -+ bb6: { + bb10: { Deinit(_0); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:5: 27:7 ((_0 as Ok).0: ViewportPercentageLength) = move _3; // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:5: 27:7 discriminant(_0) = 0; // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:5: 27:7 @@ -215,12 +249,5 @@ StorageDead(_4); // scope 0 at $DIR/early_otherwise_branch_68867.rs:28:1: 28:2 return; // scope 0 at $DIR/early_otherwise_branch_68867.rs:28:2: 28:2 } - -- bb11: { -- unreachable; // scope 0 at $DIR/early_otherwise_branch_68867.rs:28:2: 28:2 -+ bb7: { -+ StorageDead(_35); // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:8: 21:24 -+ switchInt(_11) -> [0_isize: bb2, 1_isize: bb3, 2_isize: bb4, 3_isize: bb5, otherwise: bb1]; // scope 0 at $DIR/early_otherwise_branch_68867.rs:21:8: 21:24 - } } diff --git a/src/test/mir-opt/early_otherwise_branch_noopt.noopt1.EarlyOtherwiseBranch.diff b/src/test/mir-opt/early_otherwise_branch_noopt.noopt1.EarlyOtherwiseBranch.diff index 6adc5194aec..848f2feb321 100644 --- a/src/test/mir-opt/early_otherwise_branch_noopt.noopt1.EarlyOtherwiseBranch.diff +++ b/src/test/mir-opt/early_otherwise_branch_noopt.noopt1.EarlyOtherwiseBranch.diff @@ -38,25 +38,29 @@ StorageDead(_5); // scope 0 at $DIR/early_otherwise_branch_noopt.rs:8:16: 8:17 StorageDead(_4); // scope 0 at $DIR/early_otherwise_branch_noopt.rs:8:16: 8:17 _8 = discriminant((_3.0: std::option::Option<u32>)); // scope 0 at $DIR/early_otherwise_branch_noopt.rs:8:11: 8:17 - switchInt(move _8) -> [0_isize: bb1, otherwise: bb3]; // scope 0 at $DIR/early_otherwise_branch_noopt.rs:8:5: 8:17 + switchInt(move _8) -> [0_isize: bb1, 1_isize: bb4, otherwise: bb3]; // scope 0 at $DIR/early_otherwise_branch_noopt.rs:8:5: 8:17 } bb1: { _6 = discriminant((_3.1: std::option::Option<u32>)); // scope 0 at $DIR/early_otherwise_branch_noopt.rs:8:11: 8:17 - switchInt(move _6) -> [0_isize: bb2, otherwise: bb6]; // scope 0 at $DIR/early_otherwise_branch_noopt.rs:8:5: 8:17 + switchInt(move _6) -> [0_isize: bb2, 1_isize: bb7, otherwise: bb3]; // scope 0 at $DIR/early_otherwise_branch_noopt.rs:8:5: 8:17 } bb2: { _0 = const 3_u32; // scope 0 at $DIR/early_otherwise_branch_noopt.rs:12:25: 12:26 - goto -> bb7; // scope 0 at $DIR/early_otherwise_branch_noopt.rs:12:25: 12:26 + goto -> bb8; // scope 0 at $DIR/early_otherwise_branch_noopt.rs:12:25: 12:26 } bb3: { - _7 = discriminant((_3.1: std::option::Option<u32>)); // scope 0 at $DIR/early_otherwise_branch_noopt.rs:8:11: 8:17 - switchInt(move _7) -> [0_isize: bb5, otherwise: bb4]; // scope 0 at $DIR/early_otherwise_branch_noopt.rs:8:5: 8:17 + unreachable; // scope 0 at $DIR/early_otherwise_branch_noopt.rs:8:11: 8:17 } bb4: { + _7 = discriminant((_3.1: std::option::Option<u32>)); // scope 0 at $DIR/early_otherwise_branch_noopt.rs:8:11: 8:17 + switchInt(move _7) -> [0_isize: bb6, 1_isize: bb5, otherwise: bb3]; // scope 0 at $DIR/early_otherwise_branch_noopt.rs:8:5: 8:17 + } + + bb5: { StorageLive(_9); // scope 0 at $DIR/early_otherwise_branch_noopt.rs:9:15: 9:16 _9 = (((_3.0: std::option::Option<u32>) as Some).0: u32); // scope 0 at $DIR/early_otherwise_branch_noopt.rs:9:15: 9:16 StorageLive(_10); // scope 0 at $DIR/early_otherwise_branch_noopt.rs:9:24: 9:25 @@ -64,26 +68,26 @@ _0 = const 0_u32; // scope 1 at $DIR/early_otherwise_branch_noopt.rs:9:31: 9:32 StorageDead(_10); // scope 0 at $DIR/early_otherwise_branch_noopt.rs:9:31: 9:32 StorageDead(_9); // scope 0 at $DIR/early_otherwise_branch_noopt.rs:9:31: 9:32 - goto -> bb7; // scope 0 at $DIR/early_otherwise_branch_noopt.rs:9:31: 9:32 + goto -> bb8; // scope 0 at $DIR/early_otherwise_branch_noopt.rs:9:31: 9:32 } - bb5: { + bb6: { StorageLive(_11); // scope 0 at $DIR/early_otherwise_branch_noopt.rs:10:15: 10:16 _11 = (((_3.0: std::option::Option<u32>) as Some).0: u32); // scope 0 at $DIR/early_otherwise_branch_noopt.rs:10:15: 10:16 _0 = const 1_u32; // scope 2 at $DIR/early_otherwise_branch_noopt.rs:10:28: 10:29 StorageDead(_11); // scope 0 at $DIR/early_otherwise_branch_noopt.rs:10:28: 10:29 - goto -> bb7; // scope 0 at $DIR/early_otherwise_branch_noopt.rs:10:28: 10:29 + goto -> bb8; // scope 0 at $DIR/early_otherwise_branch_noopt.rs:10:28: 10:29 } - bb6: { + bb7: { StorageLive(_12); // scope 0 at $DIR/early_otherwise_branch_noopt.rs:11:21: 11:22 _12 = (((_3.1: std::option::Option<u32>) as Some).0: u32); // scope 0 at $DIR/early_otherwise_branch_noopt.rs:11:21: 11:22 _0 = const 2_u32; // scope 3 at $DIR/early_otherwise_branch_noopt.rs:11:28: 11:29 StorageDead(_12); // scope 0 at $DIR/early_otherwise_branch_noopt.rs:11:28: 11:29 - goto -> bb7; // scope 0 at $DIR/early_otherwise_branch_noopt.rs:11:28: 11:29 + goto -> bb8; // scope 0 at $DIR/early_otherwise_branch_noopt.rs:11:28: 11:29 } - bb7: { + bb8: { StorageDead(_3); // scope 0 at $DIR/early_otherwise_branch_noopt.rs:14:1: 14:2 return; // scope 0 at $DIR/early_otherwise_branch_noopt.rs:14:2: 14:2 } diff --git a/src/test/mir-opt/early_otherwise_branch_noopt.rs b/src/test/mir-opt/early_otherwise_branch_noopt.rs index 1f8c59df35f..ef766bbd4a6 100644 --- a/src/test/mir-opt/early_otherwise_branch_noopt.rs +++ b/src/test/mir-opt/early_otherwise_branch_noopt.rs @@ -1,4 +1,4 @@ -// compile-flags: -Z mir-opt-level=4 -Zunsound-mir-opts +// unit-test: EarlyOtherwiseBranch // must not optimize as it does not follow the pattern of // left and right hand side being the same variant diff --git a/src/test/mir-opt/early_otherwise_branch_soundness.no_deref_ptr.EarlyOtherwiseBranch.diff b/src/test/mir-opt/early_otherwise_branch_soundness.no_deref_ptr.EarlyOtherwiseBranch.diff index a2722660662..7d42c772f16 100644 --- a/src/test/mir-opt/early_otherwise_branch_soundness.no_deref_ptr.EarlyOtherwiseBranch.diff +++ b/src/test/mir-opt/early_otherwise_branch_soundness.no_deref_ptr.EarlyOtherwiseBranch.diff @@ -19,7 +19,7 @@ bb1: { _0 = const 0_i32; // scope 0 at $DIR/early_otherwise_branch_soundness.rs:25:14: 25:15 - return; // scope 0 at $DIR/early_otherwise_branch_soundness.rs:25:14: 25:15 + goto -> bb5; // scope 0 at $DIR/early_otherwise_branch_soundness.rs:25:14: 25:15 } bb2: { @@ -29,7 +29,7 @@ bb3: { _0 = const 0_i32; // scope 0 at $DIR/early_otherwise_branch_soundness.rs:23:18: 23:19 - return; // scope 0 at $DIR/early_otherwise_branch_soundness.rs:23:18: 23:19 + goto -> bb5; // scope 0 at $DIR/early_otherwise_branch_soundness.rs:23:18: 23:19 } bb4: { @@ -37,7 +37,11 @@ _5 = (((*_2) as Some).0: i32); // scope 0 at $DIR/early_otherwise_branch_soundness.rs:22:18: 22:19 _0 = _5; // scope 1 at $DIR/early_otherwise_branch_soundness.rs:22:24: 22:25 StorageDead(_5); // scope 0 at $DIR/early_otherwise_branch_soundness.rs:22:24: 22:25 - return; // scope 0 at $DIR/early_otherwise_branch_soundness.rs:22:24: 22:25 + goto -> bb5; // scope 0 at $DIR/early_otherwise_branch_soundness.rs:22:24: 22:25 + } + + bb5: { + return; // scope 0 at $DIR/early_otherwise_branch_soundness.rs:27:2: 27:2 } } diff --git a/src/test/mir-opt/early_otherwise_branch_soundness.no_downcast.EarlyOtherwiseBranch.diff b/src/test/mir-opt/early_otherwise_branch_soundness.no_downcast.EarlyOtherwiseBranch.diff index 56b7c9a2db4..1efaba044ec 100644 --- a/src/test/mir-opt/early_otherwise_branch_soundness.no_downcast.EarlyOtherwiseBranch.diff +++ b/src/test/mir-opt/early_otherwise_branch_soundness.no_downcast.EarlyOtherwiseBranch.diff @@ -6,6 +6,7 @@ let mut _0: u32; // return place in scope 0 at $DIR/early_otherwise_branch_soundness.rs:12:26: 12:29 let mut _2: isize; // in scope 0 at $DIR/early_otherwise_branch_soundness.rs:13:20: 13:30 let mut _3: isize; // in scope 0 at $DIR/early_otherwise_branch_soundness.rs:13:12: 13:31 + let mut _4: &E; // in scope 0 at $DIR/early_otherwise_branch_soundness.rs:12:16: 12:17 bb0: { _3 = discriminant((*_1)); // scope 0 at $DIR/early_otherwise_branch_soundness.rs:13:12: 13:31 @@ -13,18 +14,25 @@ } bb1: { - _2 = discriminant((*(((*_1) as Some).0: &E))); // scope 0 at $DIR/early_otherwise_branch_soundness.rs:13:12: 13:31 + StorageLive(_4); // scope 0 at $DIR/early_otherwise_branch_soundness.rs:13:12: 13:31 + _4 = move (((*_1) as Some).0: &E); // scope 0 at $DIR/early_otherwise_branch_soundness.rs:13:12: 13:31 + _2 = discriminant((*_4)); // scope 0 at $DIR/early_otherwise_branch_soundness.rs:13:12: 13:31 + StorageDead(_4); // scope 0 at $DIR/early_otherwise_branch_soundness.rs:13:12: 13:31 switchInt(move _2) -> [1_isize: bb2, otherwise: bb3]; // scope 0 at $DIR/early_otherwise_branch_soundness.rs:13:12: 13:31 } bb2: { _0 = const 1_u32; // scope 0 at $DIR/early_otherwise_branch_soundness.rs:13:38: 13:39 - return; // scope 0 at $DIR/early_otherwise_branch_soundness.rs:13:5: 13:52 + goto -> bb4; // scope 0 at $DIR/early_otherwise_branch_soundness.rs:13:5: 13:52 } bb3: { _0 = const 2_u32; // scope 0 at $DIR/early_otherwise_branch_soundness.rs:13:49: 13:50 - return; // scope 0 at $DIR/early_otherwise_branch_soundness.rs:13:5: 13:52 + goto -> bb4; // scope 0 at $DIR/early_otherwise_branch_soundness.rs:13:5: 13:52 + } + + bb4: { + return; // scope 0 at $DIR/early_otherwise_branch_soundness.rs:14:2: 14:2 } } diff --git a/src/test/mir-opt/early_otherwise_branch_soundness.rs b/src/test/mir-opt/early_otherwise_branch_soundness.rs index d2513213d79..cd458923245 100644 --- a/src/test/mir-opt/early_otherwise_branch_soundness.rs +++ b/src/test/mir-opt/early_otherwise_branch_soundness.rs @@ -1,4 +1,4 @@ -// compile-flags: -Z mir-opt-level=4 -Zunsound-mir-opts +// unit-test: EarlyOtherwiseBranch // Tests various cases that the `early_otherwise_branch` opt should *not* optimize diff --git a/src/test/mir-opt/if-condition-int.rs b/src/test/mir-opt/if-condition-int.rs index b34389a0ab5..398311e6bb8 100644 --- a/src/test/mir-opt/if-condition-int.rs +++ b/src/test/mir-opt/if-condition-int.rs @@ -1,4 +1,4 @@ -// compile-flags: -O +// unit-test: SimplifyComparisonIntegral // EMIT_MIR if_condition_int.opt_u32.SimplifyComparisonIntegral.diff // EMIT_MIR if_condition_int.opt_negative.SimplifyComparisonIntegral.diff // EMIT_MIR if_condition_int.opt_char.SimplifyComparisonIntegral.diff diff --git a/src/test/mir-opt/inline/inline_closure_captures.foo.Inline.after.mir b/src/test/mir-opt/inline/inline_closure_captures.foo.Inline.after.mir index 337f0871843..75e37092ff3 100644 --- a/src/test/mir-opt/inline/inline_closure_captures.foo.Inline.after.mir +++ b/src/test/mir-opt/inline/inline_closure_captures.foo.Inline.after.mir @@ -19,6 +19,8 @@ fn foo(_1: T, _2: i32) -> (i32, T) { debug t => (*((*_6).1: &T)); // in scope 2 at $DIR/inline-closure-captures.rs:10:17: 10:18 let mut _10: i32; // in scope 2 at $DIR/inline-closure-captures.rs:11:19: 11:20 let mut _11: T; // in scope 2 at $DIR/inline-closure-captures.rs:11:22: 11:23 + let mut _12: &i32; // in scope 2 at $DIR/inline-closure-captures.rs:11:13: 11:24 + let mut _13: &T; // in scope 2 at $DIR/inline-closure-captures.rs:11:13: 11:24 } } @@ -43,9 +45,15 @@ fn foo(_1: T, _2: i32) -> (i32, T) { StorageLive(_9); // scope 1 at $DIR/inline-closure-captures.rs:12:5: 12:9 _9 = move (_7.0: i32); // scope 1 at $DIR/inline-closure-captures.rs:12:5: 12:9 StorageLive(_10); // scope 2 at $DIR/inline-closure-captures.rs:11:19: 11:20 - _10 = (*((*_6).0: &i32)); // scope 2 at $DIR/inline-closure-captures.rs:11:19: 11:20 + StorageLive(_12); // scope 2 at $DIR/inline-closure-captures.rs:11:19: 11:20 + _12 = move ((*_6).0: &i32); // scope 2 at $DIR/inline-closure-captures.rs:11:19: 11:20 + _10 = (*_12); // scope 2 at $DIR/inline-closure-captures.rs:11:19: 11:20 + StorageDead(_12); // scope 2 at $DIR/inline-closure-captures.rs:11:22: 11:23 StorageLive(_11); // scope 2 at $DIR/inline-closure-captures.rs:11:22: 11:23 - _11 = (*((*_6).1: &T)); // scope 2 at $DIR/inline-closure-captures.rs:11:22: 11:23 + StorageLive(_13); // scope 2 at $DIR/inline-closure-captures.rs:11:22: 11:23 + _13 = move ((*_6).1: &T); // scope 2 at $DIR/inline-closure-captures.rs:11:22: 11:23 + _11 = (*_13); // scope 2 at $DIR/inline-closure-captures.rs:11:22: 11:23 + StorageDead(_13); // scope 2 at $DIR/inline-closure-captures.rs:11:18: 11:24 Deinit(_0); // scope 2 at $DIR/inline-closure-captures.rs:11:18: 11:24 (_0.0: i32) = move _10; // scope 2 at $DIR/inline-closure-captures.rs:11:18: 11:24 (_0.1: T) = move _11; // scope 2 at $DIR/inline-closure-captures.rs:11:18: 11:24 diff --git a/src/test/mir-opt/inline/inline_diverging.h.Inline.diff b/src/test/mir-opt/inline/inline_diverging.h.Inline.diff index bea33073366..3b890e4be2e 100644 --- a/src/test/mir-opt/inline/inline_diverging.h.Inline.diff +++ b/src/test/mir-opt/inline/inline_diverging.h.Inline.diff @@ -4,21 +4,22 @@ fn h() -> () { let mut _0: (); // return place in scope 0 at $DIR/inline-diverging.rs:21:12: 21:12 let _1: (!, !); // in scope 0 at $DIR/inline-diverging.rs:22:5: 22:22 -+ let mut _2: fn() -> ! {sleep}; // in scope 0 at $DIR/inline-diverging.rs:22:5: 22:22 -+ let mut _9: (); // in scope 0 at $DIR/inline-diverging.rs:27:13: 27:16 -+ let mut _10: (); // in scope 0 at $DIR/inline-diverging.rs:28:13: 28:16 ++ let mut _2: (!, !); // in scope 0 at $DIR/inline-diverging.rs:22:5: 22:22 ++ let mut _3: fn() -> ! {sleep}; // in scope 0 at $DIR/inline-diverging.rs:22:5: 22:22 ++ let mut _10: (); // in scope 0 at $DIR/inline-diverging.rs:27:13: 27:16 ++ let mut _11: (); // in scope 0 at $DIR/inline-diverging.rs:28:13: 28:16 + scope 1 (inlined call_twice::<!, fn() -> ! {sleep}>) { // at $DIR/inline-diverging.rs:22:5: 22:22 -+ debug f => _2; // in scope 1 at $DIR/inline-diverging.rs:26:36: 26:37 -+ let _3: !; // in scope 1 at $DIR/inline-diverging.rs:27:9: 27:10 -+ let mut _4: &fn() -> ! {sleep}; // in scope 1 at $DIR/inline-diverging.rs:27:13: 27:14 -+ let mut _6: &fn() -> ! {sleep}; // in scope 1 at $DIR/inline-diverging.rs:28:13: 28:14 -+ let mut _7: !; // in scope 1 at $DIR/inline-diverging.rs:29:6: 29:7 -+ let mut _8: !; // in scope 1 at $DIR/inline-diverging.rs:29:9: 29:10 ++ debug f => _3; // in scope 1 at $DIR/inline-diverging.rs:26:36: 26:37 ++ let _4: !; // in scope 1 at $DIR/inline-diverging.rs:27:9: 27:10 ++ let mut _5: &fn() -> ! {sleep}; // in scope 1 at $DIR/inline-diverging.rs:27:13: 27:14 ++ let mut _7: &fn() -> ! {sleep}; // in scope 1 at $DIR/inline-diverging.rs:28:13: 28:14 ++ let mut _8: !; // in scope 1 at $DIR/inline-diverging.rs:29:6: 29:7 ++ let mut _9: !; // in scope 1 at $DIR/inline-diverging.rs:29:9: 29:10 + scope 2 { -+ debug a => _3; // in scope 2 at $DIR/inline-diverging.rs:27:9: 27:10 -+ let _5: !; // in scope 2 at $DIR/inline-diverging.rs:28:9: 28:10 ++ debug a => _4; // in scope 2 at $DIR/inline-diverging.rs:27:9: 27:10 ++ let _6: !; // in scope 2 at $DIR/inline-diverging.rs:28:9: 28:10 + scope 3 { -+ debug b => _5; // in scope 3 at $DIR/inline-diverging.rs:28:9: 28:10 ++ debug b => _6; // in scope 3 at $DIR/inline-diverging.rs:28:9: 28:10 + } + scope 6 (inlined <fn() -> ! {sleep} as Fn<()>>::call - shim(fn() -> ! {sleep})) { // at $DIR/inline-diverging.rs:28:13: 28:16 + scope 7 (inlined sleep) { // at $SRC_DIR/core/src/ops/function.rs:LL:COL @@ -33,27 +34,25 @@ bb0: { StorageLive(_1); // scope 0 at $DIR/inline-diverging.rs:22:5: 22:22 -- _1 = call_twice::<!, fn() -> ! {sleep}>(sleep) -> bb1; // scope 0 at $DIR/inline-diverging.rs:22:5: 22:22 +- call_twice::<!, fn() -> ! {sleep}>(sleep); // scope 0 at $DIR/inline-diverging.rs:22:5: 22:22 + StorageLive(_2); // scope 0 at $DIR/inline-diverging.rs:22:5: 22:22 -+ _2 = sleep; // scope 0 at $DIR/inline-diverging.rs:22:5: 22:22 ++ StorageLive(_3); // scope 0 at $DIR/inline-diverging.rs:22:5: 22:22 ++ _3 = sleep; // scope 0 at $DIR/inline-diverging.rs:22:5: 22:22 // mir::Constant - // + span: $DIR/inline-diverging.rs:22:5: 22:15 - // + literal: Const { ty: fn(fn() -> ! {sleep}) -> (!, !) {call_twice::<!, fn() -> ! {sleep}>}, val: Value(Scalar(<ZST>)) } - // mir::Constant // + span: $DIR/inline-diverging.rs:22:16: 22:21 // + literal: Const { ty: fn() -> ! {sleep}, val: Value(Scalar(<ZST>)) } -+ StorageLive(_3); // scope 1 at $DIR/inline-diverging.rs:27:9: 27:10 -+ StorageLive(_4); // scope 1 at $DIR/inline-diverging.rs:27:13: 27:14 -+ _4 = &_2; // scope 1 at $DIR/inline-diverging.rs:27:13: 27:14 -+ StorageLive(_9); // scope 1 at $DIR/inline-diverging.rs:27:13: 27:16 -+ _9 = const (); // scope 1 at $DIR/inline-diverging.rs:27:13: 27:16 ++ StorageLive(_4); // scope 1 at $DIR/inline-diverging.rs:27:9: 27:10 ++ StorageLive(_5); // scope 1 at $DIR/inline-diverging.rs:27:13: 27:14 ++ _5 = &_3; // scope 1 at $DIR/inline-diverging.rs:27:13: 27:14 ++ StorageLive(_10); // scope 1 at $DIR/inline-diverging.rs:27:13: 27:16 ++ _10 = const (); // scope 1 at $DIR/inline-diverging.rs:27:13: 27:16 + goto -> bb1; // scope 5 at $DIR/inline-diverging.rs:39:5: 39:12 - } - - bb1: { -- StorageDead(_1); // scope 0 at $DIR/inline-diverging.rs:22:22: 22:23 -- _0 = const (); // scope 0 at $DIR/inline-diverging.rs:21:12: 23:2 -- return; // scope 0 at $DIR/inline-diverging.rs:23:2: 23:2 ++ } ++ ++ bb1: { + goto -> bb1; // scope 5 at $DIR/inline-diverging.rs:39:5: 39:12 } } diff --git a/src/test/mir-opt/issue_72181_1.main.mir_map.0.mir b/src/test/mir-opt/issue_72181_1.main.mir_map.0.mir index 5fb57c285be..4aff4445158 100644 --- a/src/test/mir-opt/issue_72181_1.main.mir_map.0.mir +++ b/src/test/mir-opt/issue_72181_1.main.mir_map.0.mir @@ -21,7 +21,7 @@ fn main() -> () { StorageLive(_2); // scope 0 at $DIR/issue-72181-1.rs:16:9: 16:10 StorageLive(_3); // scope 2 at $DIR/issue-72181-1.rs:17:41: 17:43 _3 = (); // scope 2 at $DIR/issue-72181-1.rs:17:41: 17:43 - _2 = transmute::<(), Void>(move _3) -> [return: bb1, unwind: bb4]; // scope 2 at $DIR/issue-72181-1.rs:17:9: 17:44 + transmute::<(), Void>(move _3) -> bb4; // scope 2 at $DIR/issue-72181-1.rs:17:9: 17:44 // mir::Constant // + span: $DIR/issue-72181-1.rs:17:9: 17:40 // + literal: Const { ty: unsafe extern "rust-intrinsic" fn(()) -> Void {transmute::<(), Void>}, val: Value(Scalar(<ZST>)) } diff --git a/src/test/mir-opt/lower_array_len.array_bound.NormalizeArrayLen.diff b/src/test/mir-opt/lower_array_len.array_bound.NormalizeArrayLen.diff index 2e034670186..d6c1c92cd91 100644 --- a/src/test/mir-opt/lower_array_len.array_bound.NormalizeArrayLen.diff +++ b/src/test/mir-opt/lower_array_len.array_bound.NormalizeArrayLen.diff @@ -64,9 +64,5 @@ StorageDead(_3); // scope 0 at $DIR/lower_array_len.rs:11:5: 11:6 return; // scope 0 at $DIR/lower_array_len.rs:12:2: 12:2 } - - bb6 (cleanup): { - resume; // scope 0 at $DIR/lower_array_len.rs:6:1: 12:2 - } } diff --git a/src/test/mir-opt/lower_array_len.array_bound_mut.NormalizeArrayLen.diff b/src/test/mir-opt/lower_array_len.array_bound_mut.NormalizeArrayLen.diff index 6aa77a9ed60..11fc20aa693 100644 --- a/src/test/mir-opt/lower_array_len.array_bound_mut.NormalizeArrayLen.diff +++ b/src/test/mir-opt/lower_array_len.array_bound_mut.NormalizeArrayLen.diff @@ -77,9 +77,5 @@ StorageDead(_3); // scope 0 at $DIR/lower_array_len.rs:24:5: 24:6 return; // scope 0 at $DIR/lower_array_len.rs:25:2: 25:2 } - - bb7 (cleanup): { - resume; // scope 0 at $DIR/lower_array_len.rs:17:1: 25:2 - } } diff --git a/src/test/mir-opt/lower_array_len.array_len.NormalizeArrayLen.diff b/src/test/mir-opt/lower_array_len.array_len.NormalizeArrayLen.diff index b41582477c6..892fdda818e 100644 --- a/src/test/mir-opt/lower_array_len.array_len.NormalizeArrayLen.diff +++ b/src/test/mir-opt/lower_array_len.array_len.NormalizeArrayLen.diff @@ -26,9 +26,5 @@ StorageDead(_2); // scope 0 at $DIR/lower_array_len.rs:31:13: 31:14 return; // scope 0 at $DIR/lower_array_len.rs:32:2: 32:2 } - - bb2 (cleanup): { - resume; // scope 0 at $DIR/lower_array_len.rs:30:1: 32:2 - } } diff --git a/src/test/mir-opt/lower_array_len.array_len_by_value.NormalizeArrayLen.diff b/src/test/mir-opt/lower_array_len.array_len_by_value.NormalizeArrayLen.diff index 92ec7a3633e..201fffbf0d4 100644 --- a/src/test/mir-opt/lower_array_len.array_len_by_value.NormalizeArrayLen.diff +++ b/src/test/mir-opt/lower_array_len.array_len_by_value.NormalizeArrayLen.diff @@ -26,9 +26,5 @@ StorageDead(_2); // scope 0 at $DIR/lower_array_len.rs:38:13: 38:14 return; // scope 0 at $DIR/lower_array_len.rs:39:2: 39:2 } - - bb2 (cleanup): { - resume; // scope 0 at $DIR/lower_array_len.rs:37:1: 39:2 - } } diff --git a/src/test/mir-opt/lower_slice_len.bound.LowerSliceLenCalls.diff b/src/test/mir-opt/lower_slice_len.bound.LowerSliceLenCalls.diff index 2210ad54e8d..13241d882f2 100644 --- a/src/test/mir-opt/lower_slice_len.bound.LowerSliceLenCalls.diff +++ b/src/test/mir-opt/lower_slice_len.bound.LowerSliceLenCalls.diff @@ -59,9 +59,5 @@ StorageDead(_3); // scope 0 at $DIR/lower_slice_len.rs:9:5: 9:6 return; // scope 0 at $DIR/lower_slice_len.rs:10:2: 10:2 } - - bb6 (cleanup): { - resume; // scope 0 at $DIR/lower_slice_len.rs:4:1: 10:2 - } } diff --git a/src/test/mir-opt/lower_slice_len.rs b/src/test/mir-opt/lower_slice_len.rs index f2438e69749..12955aed1fb 100644 --- a/src/test/mir-opt/lower_slice_len.rs +++ b/src/test/mir-opt/lower_slice_len.rs @@ -1,4 +1,4 @@ -// compile-flags: -Z mir-opt-level=3 +// unit-test: LowerSliceLenCalls // EMIT_MIR lower_slice_len.bound.LowerSliceLenCalls.diff pub fn bound(index: usize, slice: &[u8]) -> u8 { diff --git a/src/test/mir-opt/nll/named_lifetimes_basic.use_x.nll.0.mir b/src/test/mir-opt/nll/named_lifetimes_basic.use_x.nll.0.mir index 9f235248ca5..8423128123a 100644 --- a/src/test/mir-opt/nll/named_lifetimes_basic.use_x.nll.0.mir +++ b/src/test/mir-opt/nll/named_lifetimes_basic.use_x.nll.0.mir @@ -25,14 +25,14 @@ | '_#2r live at {bb0[0..=1]} | '_#3r live at {bb0[0..=1]} | '_#4r live at {bb0[0..=1]} -| '_#1r: '_#6r due to BoringNoLocation at All($DIR/named-lifetimes-basic.rs:12:26: 12:27) -| '_#1r: '_#8r due to BoringNoLocation at All($DIR/named-lifetimes-basic.rs:12:54: 12:55) -| '_#2r: '_#7r due to BoringNoLocation at All($DIR/named-lifetimes-basic.rs:12:42: 12:43) -| '_#3r: '_#9r due to BoringNoLocation at All($DIR/named-lifetimes-basic.rs:12:66: 12:67) -| '_#6r: '_#1r due to BoringNoLocation at All($DIR/named-lifetimes-basic.rs:12:26: 12:27) -| '_#7r: '_#2r due to BoringNoLocation at All($DIR/named-lifetimes-basic.rs:12:42: 12:43) -| '_#8r: '_#1r due to BoringNoLocation at All($DIR/named-lifetimes-basic.rs:12:54: 12:55) -| '_#9r: '_#3r due to BoringNoLocation at All($DIR/named-lifetimes-basic.rs:12:66: 12:67) +| '_#1r: '_#6r due to BoringNoLocation at All($DIR/named-lifetimes-basic.rs:12:26: 12:27) ($DIR/named-lifetimes-basic.rs:12:26: 12:27 (#0) +| '_#1r: '_#8r due to BoringNoLocation at All($DIR/named-lifetimes-basic.rs:12:54: 12:55) ($DIR/named-lifetimes-basic.rs:12:54: 12:55 (#0) +| '_#2r: '_#7r due to BoringNoLocation at All($DIR/named-lifetimes-basic.rs:12:42: 12:43) ($DIR/named-lifetimes-basic.rs:12:42: 12:43 (#0) +| '_#3r: '_#9r due to BoringNoLocation at All($DIR/named-lifetimes-basic.rs:12:66: 12:67) ($DIR/named-lifetimes-basic.rs:12:66: 12:67 (#0) +| '_#6r: '_#1r due to BoringNoLocation at All($DIR/named-lifetimes-basic.rs:12:26: 12:27) ($DIR/named-lifetimes-basic.rs:12:26: 12:27 (#0) +| '_#7r: '_#2r due to BoringNoLocation at All($DIR/named-lifetimes-basic.rs:12:42: 12:43) ($DIR/named-lifetimes-basic.rs:12:42: 12:43 (#0) +| '_#8r: '_#1r due to BoringNoLocation at All($DIR/named-lifetimes-basic.rs:12:54: 12:55) ($DIR/named-lifetimes-basic.rs:12:54: 12:55 (#0) +| '_#9r: '_#3r due to BoringNoLocation at All($DIR/named-lifetimes-basic.rs:12:66: 12:67) ($DIR/named-lifetimes-basic.rs:12:66: 12:67 (#0) | fn use_x(_1: &'_#6r mut i32, _2: &'_#7r u32, _3: &'_#8r u32, _4: &'_#9r u32) -> bool { debug w => _1; // in scope 0 at $DIR/named-lifetimes-basic.rs:12:26: 12:27 diff --git a/src/test/mir-opt/nll/region_subtyping_basic.main.nll.0.32bit.mir b/src/test/mir-opt/nll/region_subtyping_basic.main.nll.0.32bit.mir index ed94a1ecf00..f79e2705ad2 100644 --- a/src/test/mir-opt/nll/region_subtyping_basic.main.nll.0.32bit.mir +++ b/src/test/mir-opt/nll/region_subtyping_basic.main.nll.0.32bit.mir @@ -18,8 +18,8 @@ | '_#3r live at {bb1[0]} | '_#4r live at {bb1[1..=3]} | '_#5r live at {bb1[4..=7], bb2[0..=2]} -| '_#3r: '_#4r due to Assignment at Single(bb1[0]) -| '_#4r: '_#5r due to Assignment at Single(bb1[3]) +| '_#3r: '_#4r due to Assignment at Single(bb1[0]) ($DIR/region-subtyping-basic.rs:18:13: 18:18 (#0) +| '_#4r: '_#5r due to Assignment at Single(bb1[3]) ($DIR/region-subtyping-basic.rs:19:13: 19:14 (#0) | fn main() -> () { let mut _0: (); // return place in scope 0 at $DIR/region-subtyping-basic.rs:16:11: 16:11 diff --git a/src/test/mir-opt/nll/region_subtyping_basic.main.nll.0.64bit.mir b/src/test/mir-opt/nll/region_subtyping_basic.main.nll.0.64bit.mir index 95997b20701..162cacef8a5 100644 --- a/src/test/mir-opt/nll/region_subtyping_basic.main.nll.0.64bit.mir +++ b/src/test/mir-opt/nll/region_subtyping_basic.main.nll.0.64bit.mir @@ -18,8 +18,8 @@ | '_#3r live at {bb1[0]} | '_#4r live at {bb1[1..=3]} | '_#5r live at {bb1[4..=7], bb2[0..=2]} -| '_#3r: '_#4r due to Assignment at Single(bb1[0]) -| '_#4r: '_#5r due to Assignment at Single(bb1[3]) +| '_#3r: '_#4r due to Assignment at Single(bb1[0]) ($DIR/region-subtyping-basic.rs:18:13: 18:18 (#0) +| '_#4r: '_#5r due to Assignment at Single(bb1[3]) ($DIR/region-subtyping-basic.rs:19:13: 19:14 (#0) | fn main() -> () { let mut _0: (); // return place in scope 0 at $DIR/region-subtyping-basic.rs:16:11: 16:11 diff --git a/src/test/mir-opt/nrvo-simple.rs b/src/test/mir-opt/nrvo-simple.rs index ab46d7b94c7..5786ae62127 100644 --- a/src/test/mir-opt/nrvo-simple.rs +++ b/src/test/mir-opt/nrvo-simple.rs @@ -1,4 +1,4 @@ -// compile-flags: -Zmir-opt-level=1 +// unit-test: RenameReturnPlace // EMIT_MIR nrvo_simple.nrvo.RenameReturnPlace.diff fn nrvo(init: fn(&mut [u8; 1024])) -> [u8; 1024] { diff --git a/src/test/mir-opt/storage_ranges.main.nll.0.mir b/src/test/mir-opt/storage_ranges.main.nll.0.mir index e02580135af..b383c5ec9dc 100644 --- a/src/test/mir-opt/storage_ranges.main.nll.0.mir +++ b/src/test/mir-opt/storage_ranges.main.nll.0.mir @@ -16,7 +16,7 @@ | '_#1r live at {bb0[0..=22]} | '_#3r live at {bb0[10]} | '_#4r live at {bb0[11]} -| '_#3r: '_#4r due to Assignment at Single(bb0[10]) +| '_#3r: '_#4r due to Assignment at Single(bb0[10]) ($DIR/storage_ranges.rs:6:17: 6:25 (#0) | fn main() -> () { let mut _0: (); // return place in scope 0 at $DIR/storage_ranges.rs:3:11: 3:11 diff --git a/src/test/mir-opt/uninhabited_fallthrough_elimination.eliminate_fallthrough.UninhabitedEnumBranching.diff b/src/test/mir-opt/uninhabited_fallthrough_elimination.eliminate_fallthrough.UninhabitedEnumBranching.diff index 868eeb6367e..7e843b65e88 100644 --- a/src/test/mir-opt/uninhabited_fallthrough_elimination.eliminate_fallthrough.UninhabitedEnumBranching.diff +++ b/src/test/mir-opt/uninhabited_fallthrough_elimination.eliminate_fallthrough.UninhabitedEnumBranching.diff @@ -9,7 +9,7 @@ bb0: { _2 = discriminant(_1); // scope 0 at $DIR/uninhabited_fallthrough_elimination.rs:22:11: 22:12 - switchInt(move _2) -> [1_isize: bb3, 2_isize: bb2, otherwise: bb1]; // scope 0 at $DIR/uninhabited_fallthrough_elimination.rs:22:5: 22:12 -+ switchInt(move _2) -> [1_isize: bb3, 2_isize: bb2, otherwise: bb6]; // scope 0 at $DIR/uninhabited_fallthrough_elimination.rs:22:5: 22:12 ++ switchInt(move _2) -> [1_isize: bb3, 2_isize: bb2, otherwise: bb5]; // scope 0 at $DIR/uninhabited_fallthrough_elimination.rs:22:5: 22:12 } bb1: { @@ -29,13 +29,9 @@ bb4: { return; // scope 0 at $DIR/uninhabited_fallthrough_elimination.rs:27:2: 27:2 - } - - bb5 (cleanup): { - resume; // scope 0 at $DIR/uninhabited_fallthrough_elimination.rs:21:1: 27:2 + } + -+ bb6: { ++ bb5: { + unreachable; // scope 0 at $DIR/uninhabited_fallthrough_elimination.rs:25:14: 25:15 } } diff --git a/src/test/mir-opt/uninhabited_fallthrough_elimination.keep_fallthrough.UninhabitedEnumBranching.diff b/src/test/mir-opt/uninhabited_fallthrough_elimination.keep_fallthrough.UninhabitedEnumBranching.diff index 33c1458dc0c..5da011d427a 100644 --- a/src/test/mir-opt/uninhabited_fallthrough_elimination.keep_fallthrough.UninhabitedEnumBranching.diff +++ b/src/test/mir-opt/uninhabited_fallthrough_elimination.keep_fallthrough.UninhabitedEnumBranching.diff @@ -30,9 +30,5 @@ bb4: { return; // scope 0 at $DIR/uninhabited_fallthrough_elimination.rs:18:2: 18:2 } - - bb5 (cleanup): { - resume; // scope 0 at $DIR/uninhabited_fallthrough_elimination.rs:12:1: 18:2 - } } diff --git a/src/test/mir-opt/unreachable.main.UnreachablePropagation.diff b/src/test/mir-opt/unreachable.main.UnreachablePropagation.diff index 380844f8861..08312bde20f 100644 --- a/src/test/mir-opt/unreachable.main.UnreachablePropagation.diff +++ b/src/test/mir-opt/unreachable.main.UnreachablePropagation.diff @@ -64,10 +64,6 @@ _0 = const (); // scope 0 at $DIR/unreachable.rs:19:6: 19:6 StorageDead(_1); // scope 0 at $DIR/unreachable.rs:20:1: 20:2 return; // scope 0 at $DIR/unreachable.rs:20:2: 20:2 -- } -- -- bb7 (cleanup): { -- resume; // scope 0 at $DIR/unreachable.rs:8:1: 20:2 } } diff --git a/src/test/mir-opt/unreachable_diverging.main.UnreachablePropagation.diff b/src/test/mir-opt/unreachable_diverging.main.UnreachablePropagation.diff index e26990b1def..e5867ccfc5c 100644 --- a/src/test/mir-opt/unreachable_diverging.main.UnreachablePropagation.diff +++ b/src/test/mir-opt/unreachable_diverging.main.UnreachablePropagation.diff @@ -69,10 +69,6 @@ StorageDead(_1); // scope 0 at $DIR/unreachable_diverging.rs:20:1: 20:2 StorageDead(_2); // scope 0 at $DIR/unreachable_diverging.rs:20:1: 20:2 return; // scope 0 at $DIR/unreachable_diverging.rs:20:2: 20:2 -- } -- -- bb7 (cleanup): { -- resume; // scope 0 at $DIR/unreachable_diverging.rs:12:1: 20:2 } } diff --git a/src/test/pretty/dollar-crate.pp b/src/test/pretty/dollar-crate.pp index 0c96fb593e6..3af37955f23 100644 --- a/src/test/pretty/dollar-crate.pp +++ b/src/test/pretty/dollar-crate.pp @@ -9,5 +9,5 @@ extern crate std; // pp-exact:dollar-crate.pp fn main() { - ::std::io::_print(::core::fmt::Arguments::new_v1(&["rust\n"], &[])); + { ::std::io::_print(::core::fmt::Arguments::new_v1(&["rust\n"], &[])); }; } diff --git a/src/test/pretty/hir-pretty-loop.pp b/src/test/pretty/hir-pretty-loop.pp index 9b10fd86c47..a59a3002c7f 100644 --- a/src/test/pretty/hir-pretty-loop.pp +++ b/src/test/pretty/hir-pretty-loop.pp @@ -6,4 +6,4 @@ extern crate std; // pretty-mode:hir // pp-exact:hir-pretty-loop.pp -pub fn foo() { loop { break; } } +fn foo() { loop { break; } } diff --git a/src/test/pretty/issue-4264.pp b/src/test/pretty/issue-4264.pp index ea74a267be8..752c36a0fbc 100644 --- a/src/test/pretty/issue-4264.pp +++ b/src/test/pretty/issue-4264.pp @@ -8,9 +8,9 @@ extern crate std; // #4264 fixed-length vector types -pub fn foo(_: [i32; (3 as usize)]) ({ } as ()) +fn foo(_: [i32; (3 as usize)]) ({ } as ()) -pub fn bar() ({ +fn bar() ({ const FOO: usize = ((5 as usize) - (4 as usize) as usize); let _: [(); (FOO as usize)] = ([(() as ())] as [(); 1]); @@ -41,14 +41,14 @@ pub fn bar() ({ (res as String) } as String); } as ()) -pub type Foo = [i32; (3 as usize)]; -pub struct Bar { - pub x: [i32; (3 as usize)], +type Foo = [i32; (3 as usize)]; +struct Bar { + x: [i32; (3 as usize)], } -pub struct TupleBar([i32; (4 as usize)]); -pub enum Baz { BazVariant([i32; (5 as usize)]), } -pub fn id<T>(x: T) -> T ({ (x as T) } as T) -pub fn use_id() ({ +struct TupleBar([i32; (4 as usize)]); +enum Baz { BazVariant([i32; (5 as usize)]), } +fn id<T>(x: T) -> T ({ (x as T) } as T) +fn use_id() ({ let _ = ((id::<[i32; (3 as usize)]> as fn([i32; 3]) -> [i32; 3] {id::<[i32; 3]>})(([(1 as i32), diff --git a/src/test/pretty/yeet-expr.rs b/src/test/pretty/yeet-expr.rs new file mode 100644 index 00000000000..c899f11b724 --- /dev/null +++ b/src/test/pretty/yeet-expr.rs @@ -0,0 +1,12 @@ +// pp-exact +#![feature(yeet_expr)] + +fn yeet_no_expr() -> Option<String> { do yeet } + +fn yeet_no_expr_with_semicolon() -> Option<String> { do yeet; } + +fn yeet_with_expr() -> Result<String, i32> { do yeet 1 + 2 } + +fn yeet_with_expr_with_semicolon() -> Result<String, i32> { do yeet 1 + 2; } + +fn main() {} diff --git a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.closure.txt b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.closure.txt index 8bf9c97fdda..e463099a5ee 100644 --- a/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.closure.txt +++ b/src/test/run-make-fulldeps/coverage-reports/expected_show_coverage.closure.txt @@ -116,8 +116,8 @@ 116| 1| 117| 1| let 118| 1| _unused_closure - 119| 1| = - 120| 1| | + 119| | = + 120| | | 121| | mut countdown 122| | | 123| 0| { @@ -173,7 +173,7 @@ 169| | ; 170| | 171| 1| let short_used_not_covered_closure_line_break_no_block_embedded_branch = - 172| 1| | _unused_arg: u8 | + 172| | | _unused_arg: u8 | 173| 0| println!( 174| 0| "not called: {}", 175| 0| if is_true { "check" } else { "me" } @@ -191,7 +191,7 @@ 187| | ; 188| | 189| 1| let short_used_covered_closure_line_break_no_block_embedded_branch = - 190| | | _unused_arg: u8 | + 190| 1| | _unused_arg: u8 | 191| 1| println!( 192| 1| "not called: {}", 193| 1| if is_true { "check" } else { "me" } diff --git a/src/test/run-make-fulldeps/reproducible-build/linker.rs b/src/test/run-make-fulldeps/reproducible-build/linker.rs index 998d1f32859..3dda6f190e4 100644 --- a/src/test/run-make-fulldeps/reproducible-build/linker.rs +++ b/src/test/run-make-fulldeps/reproducible-build/linker.rs @@ -25,6 +25,12 @@ fn main() { let mut contents = Vec::new(); File::open(path).unwrap().read_to_end(&mut contents).unwrap(); + // This file is produced during linking in a temporary directory. + let arg = if arg.ends_with("/symbols.o") || arg.ends_with("\\symbols.o") { + "symbols.o" + } else { + &*arg + }; out.push_str(&format!("{}: {}\n", arg, hash(&contents))); } diff --git a/src/test/run-make-fulldeps/symbol-visibility/Makefile b/src/test/run-make-fulldeps/symbol-visibility/Makefile index dc55c947d89..4bb35f33ad3 100644 --- a/src/test/run-make-fulldeps/symbol-visibility/Makefile +++ b/src/test/run-make-fulldeps/symbol-visibility/Makefile @@ -54,9 +54,12 @@ all: # Check that a Rust dylib does not export generics if -Zshare-generics=no [ "$$($(NM) $(TMPDIR)/$(RDYLIB_NAME) | grep -v __imp_ | grep -c public_generic_function_from_rlib)" -eq "0" ] +# FIXME(nbdd0121): This is broken in MinGW, see https://github.com/rust-lang/rust/pull/95604#issuecomment-1101564032 +ifndef IS_WINDOWS # Check that an executable does not export any dynamic symbols [ "$$($(NM) $(TMPDIR)/$(EXE_NAME) | grep -v __imp_ | grep -c public_c_function_from_rlib)" -eq "0" ] [ "$$($(NM) $(TMPDIR)/$(EXE_NAME) | grep -v __imp_ | grep -c public_rust_function_from_exe)" -eq "0" ] +endif # Check the combined case, where we generate a cdylib and an rlib in the same @@ -91,6 +94,8 @@ all: [ "$$($(NM) $(TMPDIR)/$(RDYLIB_NAME) | grep -v __imp_ | grep -c public_rust_function_from_rlib)" -eq "1" ] [ "$$($(NM) $(TMPDIR)/$(RDYLIB_NAME) | grep -v __imp_ | grep -c public_generic_function_from_rlib)" -eq "1" ] +ifndef IS_WINDOWS # Check that an executable does not export any dynamic symbols [ "$$($(NM) $(TMPDIR)/$(EXE_NAME) | grep -v __imp_ | grep -c public_c_function_from_rlib)" -eq "0" ] [ "$$($(NM) $(TMPDIR)/$(EXE_NAME) | grep -v __imp_ | grep -c public_rust_function_from_exe)" -eq "0" ] +endif diff --git a/src/test/run-make/const_fn_mir/dump.mir b/src/test/run-make/const_fn_mir/dump.mir index 4e8936905c4..f02bccc4b2d 100644 --- a/src/test/run-make/const_fn_mir/dump.mir +++ b/src/test/run-make/const_fn_mir/dump.mir @@ -23,10 +23,6 @@ fn foo() -> i32 { _0 = move (_1.0: i32); // scope 0 at main.rs:5:5: 5:10 return; // scope 0 at main.rs:6:2: 6:2 } - - bb2 (cleanup): { - resume; // scope 0 at main.rs:4:1: 6:2 - } } fn main() -> () { diff --git a/src/test/run-make/emit-shared-files/Makefile b/src/test/run-make/emit-shared-files/Makefile index d89b526d430..9f46883beaa 100644 --- a/src/test/run-make/emit-shared-files/Makefile +++ b/src/test/run-make/emit-shared-files/Makefile @@ -14,7 +14,7 @@ invocation-only: [ -e $(INVOCATION_ONLY)/x/index.html ] [ -e $(INVOCATION_ONLY)/theme-xxx.css ] # generated from z.css ! [ -e $(INVOCATION_ONLY)/storage-xxx.js ] - ! [ -e $(INVOCATION_ONLY)/SourceSerif4-It.ttf.woff ] + ! [ -e $(INVOCATION_ONLY)/SourceSerif4-It.ttf.woff2 ] # FIXME: this probably shouldn't have a suffix [ -e $(INVOCATION_ONLY)/y-xxx.css ] @@ -24,7 +24,7 @@ invocation-only: toolchain-only: $(RUSTDOC) -Z unstable-options --emit=toolchain-shared-resources --output $(TOOLCHAIN_ONLY) --resource-suffix=-xxx --extend-css z.css x.rs [ -e $(TOOLCHAIN_ONLY)/storage-xxx.js ] - ! [ -e $(TOOLCHAIN_ONLY)/SourceSerif4-It.ttf.woff ] + ! [ -e $(TOOLCHAIN_ONLY)/SourceSerif4-It.ttf.woff2 ] ! [ -e $(TOOLCHAIN_ONLY)/search-index-xxx.js ] ! [ -e $(TOOLCHAIN_ONLY)/x/index.html ] ! [ -e $(TOOLCHAIN_ONLY)/theme.css ] @@ -35,7 +35,7 @@ toolchain-only: all-shared: $(RUSTDOC) -Z unstable-options --emit=toolchain-shared-resources,unversioned-shared-resources --output $(ALL_SHARED) --resource-suffix=-xxx --extend-css z.css x.rs [ -e $(ALL_SHARED)/storage-xxx.js ] - [ -e $(ALL_SHARED)/SourceSerif4-It.ttf.woff ] + [ -e $(ALL_SHARED)/SourceSerif4-It.ttf.woff2 ] ! [ -e $(ALL_SHARED)/search-index-xxx.js ] ! [ -e $(ALL_SHARED)/settings.html ] ! [ -e $(ALL_SHARED)/x ] diff --git a/src/test/run-make/issue-47384/Makefile b/src/test/run-make/issue-47384/Makefile new file mode 100644 index 00000000000..f10365f8c88 --- /dev/null +++ b/src/test/run-make/issue-47384/Makefile @@ -0,0 +1,12 @@ +-include ../../run-make-fulldeps/tools.mk + +# only-linux +# ignore-cross-compile + +all: main.rs + $(RUSTC) --crate-type lib lib.rs + $(RUSTC) --crate-type cdylib -Clink-args="-Tlinker.ld" main.rs + # Ensure `#[used]` and `KEEP`-ed section is there + objdump -s -j".static" $(TMPDIR)/libmain.so + # Ensure `#[no_mangle]` symbol is there + nm $(TMPDIR)/libmain.so | $(CGREP) bar diff --git a/src/test/run-make/issue-47384/lib.rs b/src/test/run-make/issue-47384/lib.rs new file mode 100644 index 00000000000..99508bcdaf3 --- /dev/null +++ b/src/test/run-make/issue-47384/lib.rs @@ -0,0 +1,12 @@ +mod foo { + #[link_section = ".rodata.STATIC"] + #[used] + static STATIC: [u32; 10] = [1; 10]; +} + +mod bar { + #[no_mangle] + extern "C" fn bar() -> i32 { + 0 + } +} diff --git a/src/test/run-make/issue-47384/linker.ld b/src/test/run-make/issue-47384/linker.ld new file mode 100644 index 00000000000..2e70acab3f4 --- /dev/null +++ b/src/test/run-make/issue-47384/linker.ld @@ -0,0 +1,7 @@ +SECTIONS +{ + .static : ALIGN(4) + { + KEEP(*(.rodata.STATIC)); + } +} diff --git a/src/test/run-make/issue-47384/main.rs b/src/test/run-make/issue-47384/main.rs new file mode 100644 index 00000000000..02572632517 --- /dev/null +++ b/src/test/run-make/issue-47384/main.rs @@ -0,0 +1 @@ +extern crate lib; diff --git a/src/test/run-make/issue-96498/Makefile b/src/test/run-make/issue-96498/Makefile new file mode 100644 index 00000000000..eae6400aee4 --- /dev/null +++ b/src/test/run-make/issue-96498/Makefile @@ -0,0 +1,8 @@ +# only-windows +# needs-rust-lld + +-include ../../run-make-fulldeps/tools.mk + +# Ensure that LLD can link +all: + $(RUSTC) -C linker=rust-lld foo.rs diff --git a/src/test/run-make/issue-96498/foo.rs b/src/test/run-make/issue-96498/foo.rs new file mode 100644 index 00000000000..93ac3641b09 --- /dev/null +++ b/src/test/run-make/issue-96498/foo.rs @@ -0,0 +1,4 @@ +#![crate_type = "cdylib"] + +#[no_mangle] +extern "C" fn foo() {} diff --git a/src/test/rustdoc-js-std/filter-crate.js b/src/test/rustdoc-js-std/filter-crate.js index 2e0330c4497..b47a1fefa41 100644 --- a/src/test/rustdoc-js-std/filter-crate.js +++ b/src/test/rustdoc-js-std/filter-crate.js @@ -1,6 +1,6 @@ // exact-check -const QUERY = 'hashmap'; +const QUERY = '"hashmap"'; const FILTER_CRATE = 'core'; const EXPECTED = { diff --git a/src/test/rustdoc-js-std/parser-errors.js b/src/test/rustdoc-js-std/parser-errors.js new file mode 100644 index 00000000000..dc42031e05f --- /dev/null +++ b/src/test/rustdoc-js-std/parser-errors.js @@ -0,0 +1,385 @@ +const QUERY = [ + '<P>', + '-> <P>', + 'a<"P">', + '"P" "P"', + 'P "P"', + '"p" p', + '"const": p', + "a<:a>", + "a<::a>", + "((a))", + "(p -> p", + "::a::b", + "a::::b", + "a::b::", + ":a", + "a b:", + "a (b:", + "_:", + "a-bb", + "a>bb", + "ab'", + "a->", + '"p" <a>', + '"p" a<a>', + "a,<", + "aaaaa<>b", + "fn:aaaaa<>b", + "->a<>b", + "a<->", + "a:: a", + "a ::a", + "a<a>:", + "a<>:", + "a,:", + " a<> :", + "mod : :", + "a!a", + "a!!", +]; + +const PARSED = [ + { + elems: [], + foundElems: 0, + original: "<P>", + returned: [], + typeFilter: -1, + userQuery: "<p>", + error: "Found generics without a path", + }, + { + elems: [], + foundElems: 0, + original: "-> <P>", + returned: [], + typeFilter: -1, + userQuery: "-> <p>", + error: "Found generics without a path", + }, + { + elems: [], + foundElems: 0, + original: "a<\"P\">", + returned: [], + typeFilter: -1, + userQuery: "a<\"p\">", + error: "`\"` cannot be used in generics", + }, + { + elems: [], + foundElems: 0, + original: "\"P\" \"P\"", + returned: [], + typeFilter: -1, + userQuery: "\"p\" \"p\"", + error: "Cannot have more than one literal search element", + }, + { + elems: [], + foundElems: 0, + original: "P \"P\"", + returned: [], + typeFilter: -1, + userQuery: "p \"p\"", + error: "Cannot use literal search when there is more than one element", + }, + { + elems: [], + foundElems: 0, + original: "\"p\" p", + returned: [], + typeFilter: -1, + userQuery: "\"p\" p", + error: "You cannot have more than one element if you use quotes", + }, + { + elems: [], + foundElems: 0, + original: "\"const\": p", + returned: [], + typeFilter: -1, + userQuery: "\"const\": p", + error: "You cannot use quotes on type filter", + }, + { + elems: [], + foundElems: 0, + original: "a<:a>", + returned: [], + typeFilter: -1, + userQuery: "a<:a>", + error: "Unexpected `:` after `<`", + }, + { + elems: [], + foundElems: 0, + original: "a<::a>", + returned: [], + typeFilter: -1, + userQuery: "a<::a>", + error: "Unexpected `::`: paths cannot start with `::`", + }, + { + elems: [], + foundElems: 0, + original: "((a))", + returned: [], + typeFilter: -1, + userQuery: "((a))", + error: "Unexpected `(`", + }, + { + elems: [], + foundElems: 0, + original: "(p -> p", + returned: [], + typeFilter: -1, + userQuery: "(p -> p", + error: "Unexpected `(`", + }, + { + elems: [], + foundElems: 0, + original: "::a::b", + returned: [], + typeFilter: -1, + userQuery: "::a::b", + error: "Paths cannot start with `::`", + }, + { + elems: [], + foundElems: 0, + original: "a::::b", + returned: [], + typeFilter: -1, + userQuery: "a::::b", + error: "Unexpected `::::`", + }, + { + elems: [], + foundElems: 0, + original: "a::b::", + returned: [], + typeFilter: -1, + userQuery: "a::b::", + error: "Paths cannot end with `::`", + }, + { + elems: [], + foundElems: 0, + original: ":a", + returned: [], + typeFilter: -1, + userQuery: ":a", + error: "Expected type filter before `:`", + }, + { + elems: [], + foundElems: 0, + original: "a b:", + returned: [], + typeFilter: -1, + userQuery: "a b:", + error: "Unexpected `:`", + }, + { + elems: [], + foundElems: 0, + original: "a (b:", + returned: [], + typeFilter: -1, + userQuery: "a (b:", + error: "Unexpected `(`", + }, + { + elems: [], + foundElems: 0, + original: "_:", + returned: [], + typeFilter: -1, + userQuery: "_:", + error: "Unknown type filter `_`", + }, + { + elems: [], + foundElems: 0, + original: "a-bb", + returned: [], + typeFilter: -1, + userQuery: "a-bb", + error: "Unexpected `-` (did you mean `->`?)", + }, + { + elems: [], + foundElems: 0, + original: "a>bb", + returned: [], + typeFilter: -1, + userQuery: "a>bb", + error: "Unexpected `>` (did you mean `->`?)", + }, + { + elems: [], + foundElems: 0, + original: "ab'", + returned: [], + typeFilter: -1, + userQuery: "ab'", + error: "Unexpected `'`", + }, + { + elems: [], + foundElems: 0, + original: "a->", + returned: [], + typeFilter: -1, + userQuery: "a->", + error: "Expected at least one item after `->`", + }, + { + elems: [], + foundElems: 0, + original: '"p" <a>', + returned: [], + typeFilter: -1, + userQuery: '"p" <a>', + error: "Found generics without a path", + }, + { + elems: [], + foundElems: 0, + original: '"p" a<a>', + returned: [], + typeFilter: -1, + userQuery: '"p" a<a>', + error: "You cannot have more than one element if you use quotes", + }, + { + elems: [], + foundElems: 0, + original: 'a,<', + returned: [], + typeFilter: -1, + userQuery: 'a,<', + error: 'Found generics without a path', + }, + { + elems: [], + foundElems: 0, + original: 'aaaaa<>b', + returned: [], + typeFilter: -1, + userQuery: 'aaaaa<>b', + error: 'Expected `,`, ` `, `:` or `->`, found `b`', + }, + { + elems: [], + foundElems: 0, + original: 'fn:aaaaa<>b', + returned: [], + typeFilter: -1, + userQuery: 'fn:aaaaa<>b', + error: 'Expected `,`, ` ` or `->`, found `b`', + }, + { + elems: [], + foundElems: 0, + original: '->a<>b', + returned: [], + typeFilter: -1, + userQuery: '->a<>b', + error: 'Expected `,` or ` `, found `b`', + }, + { + elems: [], + foundElems: 0, + original: 'a<->', + returned: [], + typeFilter: -1, + userQuery: 'a<->', + error: 'Unexpected `-` after `<`', + }, + { + elems: [], + foundElems: 0, + original: 'a:: a', + returned: [], + typeFilter: -1, + userQuery: 'a:: a', + error: 'Paths cannot end with `::`', + }, + { + elems: [], + foundElems: 0, + original: 'a ::a', + returned: [], + typeFilter: -1, + userQuery: 'a ::a', + error: 'Paths cannot start with `::`', + }, + { + elems: [], + foundElems: 0, + original: "a<a>:", + returned: [], + typeFilter: -1, + userQuery: "a<a>:", + error: 'Unexpected `:`', + }, + { + elems: [], + foundElems: 0, + original: "a<>:", + returned: [], + typeFilter: -1, + userQuery: "a<>:", + error: 'Unexpected `<` in type filter', + }, + { + elems: [], + foundElems: 0, + original: "a,:", + returned: [], + typeFilter: -1, + userQuery: "a,:", + error: 'Unexpected `,` in type filter', + }, + { + elems: [], + foundElems: 0, + original: "a<> :", + returned: [], + typeFilter: -1, + userQuery: "a<> :", + error: 'Unexpected `<` in type filter', + }, + { + elems: [], + foundElems: 0, + original: "mod : :", + returned: [], + typeFilter: -1, + userQuery: "mod : :", + error: 'Unexpected `:`', + }, + { + elems: [], + foundElems: 0, + original: "a!a", + returned: [], + typeFilter: -1, + userQuery: "a!a", + error: '`!` can only be at the end of an ident', + }, + { + elems: [], + foundElems: 0, + original: "a!!", + returned: [], + typeFilter: -1, + userQuery: "a!!", + error: 'Cannot have more than one `!` in an ident', + }, +]; diff --git a/src/test/rustdoc-js-std/parser-filter.js b/src/test/rustdoc-js-std/parser-filter.js new file mode 100644 index 00000000000..e5a87a415ac --- /dev/null +++ b/src/test/rustdoc-js-std/parser-filter.js @@ -0,0 +1,43 @@ +const QUERY = ['fn:foo', 'enum : foo', 'macro<f>:foo']; + +const PARSED = [ + { + elems: [{ + name: "foo", + fullPath: ["foo"], + pathWithoutLast: [], + pathLast: "foo", + generics: [], + }], + foundElems: 1, + original: "fn:foo", + returned: [], + typeFilter: 5, + userQuery: "fn:foo", + error: null, + }, + { + elems: [{ + name: "foo", + fullPath: ["foo"], + pathWithoutLast: [], + pathLast: "foo", + generics: [], + }], + foundElems: 1, + original: "enum : foo", + returned: [], + typeFilter: 4, + userQuery: "enum : foo", + error: null, + }, + { + elems: [], + foundElems: 0, + original: "macro<f>:foo", + returned: [], + typeFilter: -1, + userQuery: "macro<f>:foo", + error: "Unexpected `:`", + }, +]; diff --git a/src/test/rustdoc-js-std/parser-generics.js b/src/test/rustdoc-js-std/parser-generics.js new file mode 100644 index 00000000000..0cf7f5019aa --- /dev/null +++ b/src/test/rustdoc-js-std/parser-generics.js @@ -0,0 +1,62 @@ +const QUERY = ['A<B<C<D>, E>', 'p<> u8', '"p"<a>']; + +const PARSED = [ + { + elems: [], + foundElems: 0, + original: 'A<B<C<D>, E>', + returned: [], + typeFilter: -1, + userQuery: 'a<b<c<d>, e>', + error: 'Unexpected `<` after `<`', + }, + { + elems: [ + { + name: "p", + fullPath: ["p"], + pathWithoutLast: [], + pathLast: "p", + generics: [], + }, + { + name: "u8", + fullPath: ["u8"], + pathWithoutLast: [], + pathLast: "u8", + generics: [], + }, + ], + foundElems: 2, + original: "p<> u8", + returned: [], + typeFilter: -1, + userQuery: "p<> u8", + error: null, + }, + { + elems: [ + { + name: "p", + fullPath: ["p"], + pathWithoutLast: [], + pathLast: "p", + generics: [ + { + name: "a", + fullPath: ["a"], + pathWithoutLast: [], + pathLast: "a", + generics: [], + }, + ], + }, + ], + foundElems: 1, + original: '"p"<a>', + returned: [], + typeFilter: -1, + userQuery: '"p"<a>', + error: null, + }, +]; diff --git a/src/test/rustdoc-js-std/parser-ident.js b/src/test/rustdoc-js-std/parser-ident.js new file mode 100644 index 00000000000..4b5ab01ac76 --- /dev/null +++ b/src/test/rustdoc-js-std/parser-ident.js @@ -0,0 +1,93 @@ +const QUERY = [ + "R<!>", + "!", + "a!", + "a!::b", + "a!::b!", +]; + +const PARSED = [ + { + elems: [{ + name: "r", + fullPath: ["r"], + pathWithoutLast: [], + pathLast: "r", + generics: [ + { + name: "!", + fullPath: ["!"], + pathWithoutLast: [], + pathLast: "!", + generics: [], + }, + ], + }], + foundElems: 1, + original: "R<!>", + returned: [], + typeFilter: -1, + userQuery: "r<!>", + error: null, + }, + { + elems: [{ + name: "!", + fullPath: ["!"], + pathWithoutLast: [], + pathLast: "!", + generics: [], + }], + foundElems: 1, + original: "!", + returned: [], + typeFilter: -1, + userQuery: "!", + error: null, + }, + { + elems: [{ + name: "a!", + fullPath: ["a!"], + pathWithoutLast: [], + pathLast: "a!", + generics: [], + }], + foundElems: 1, + original: "a!", + returned: [], + typeFilter: -1, + userQuery: "a!", + error: null, + }, + { + elems: [{ + name: "a!::b", + fullPath: ["a!", "b"], + pathWithoutLast: ["a!"], + pathLast: "b", + generics: [], + }], + foundElems: 1, + original: "a!::b", + returned: [], + typeFilter: -1, + userQuery: "a!::b", + error: null, + }, + { + elems: [{ + name: "a!::b!", + fullPath: ["a!", "b!"], + pathWithoutLast: ["a!"], + pathLast: "b!", + generics: [], + }], + foundElems: 1, + original: "a!::b!", + returned: [], + typeFilter: -1, + userQuery: "a!::b!", + error: null, + }, +]; diff --git a/src/test/rustdoc-js-std/parser-literal.js b/src/test/rustdoc-js-std/parser-literal.js new file mode 100644 index 00000000000..87b3baff1e2 --- /dev/null +++ b/src/test/rustdoc-js-std/parser-literal.js @@ -0,0 +1,27 @@ +const QUERY = ['R<P>']; + +const PARSED = [ + { + elems: [{ + name: "r", + fullPath: ["r"], + pathWithoutLast: [], + pathLast: "r", + generics: [ + { + name: "p", + fullPath: ["p"], + pathWithoutLast: [], + pathLast: "p", + generics: [], + }, + ], + }], + foundElems: 1, + original: "R<P>", + returned: [], + typeFilter: -1, + userQuery: "r<p>", + error: null, + } +]; diff --git a/src/test/rustdoc-js-std/parser-paths.js b/src/test/rustdoc-js-std/parser-paths.js new file mode 100644 index 00000000000..9f823f9336a --- /dev/null +++ b/src/test/rustdoc-js-std/parser-paths.js @@ -0,0 +1,90 @@ +const QUERY = ['A::B', 'A::B,C', 'A::B<f>,C', 'mod::a']; + +const PARSED = [ + { + elems: [{ + name: "a::b", + fullPath: ["a", "b"], + pathWithoutLast: ["a"], + pathLast: "b", + generics: [], + }], + foundElems: 1, + original: "A::B", + returned: [], + typeFilter: -1, + userQuery: "a::b", + error: null, + }, + { + elems: [ + { + name: "a::b", + fullPath: ["a", "b"], + pathWithoutLast: ["a"], + pathLast: "b", + generics: [], + }, + { + name: "c", + fullPath: ["c"], + pathWithoutLast: [], + pathLast: "c", + generics: [], + }, + ], + foundElems: 2, + original: 'A::B,C', + returned: [], + typeFilter: -1, + userQuery: 'a::b,c', + error: null, + }, + { + elems: [ + { + name: "a::b", + fullPath: ["a", "b"], + pathWithoutLast: ["a"], + pathLast: "b", + generics: [ + { + name: "f", + fullPath: ["f"], + pathWithoutLast: [], + pathLast: "f", + generics: [], + }, + ], + }, + { + name: "c", + fullPath: ["c"], + pathWithoutLast: [], + pathLast: "c", + generics: [], + }, + ], + foundElems: 2, + original: 'A::B<f>,C', + returned: [], + typeFilter: -1, + userQuery: 'a::b<f>,c', + error: null, + }, + { + elems: [{ + name: "mod::a", + fullPath: ["mod", "a"], + pathWithoutLast: ["mod"], + pathLast: "a", + generics: [], + }], + foundElems: 1, + original: "mod::a", + returned: [], + typeFilter: -1, + userQuery: "mod::a", + error: null, + }, +]; diff --git a/src/test/rustdoc-js-std/parser-quote.js b/src/test/rustdoc-js-std/parser-quote.js new file mode 100644 index 00000000000..1e16c90de5e --- /dev/null +++ b/src/test/rustdoc-js-std/parser-quote.js @@ -0,0 +1,87 @@ +const QUERY = [ + '-> "p"', + '"p",', + '"p" -> a', + '"a" -> "p"', + '->"-"', + '"a', + '""', +]; + +const PARSED = [ + { + elems: [], + foundElems: 1, + original: '-> "p"', + returned: [{ + name: "p", + fullPath: ["p"], + pathWithoutLast: [], + pathLast: "p", + generics: [], + }], + typeFilter: -1, + userQuery: '-> "p"', + error: null, + }, + { + elems: [{ + name: "p", + fullPath: ["p"], + pathWithoutLast: [], + pathLast: "p", + generics: [], + }], + foundElems: 1, + original: '"p",', + returned: [], + typeFilter: -1, + userQuery: '"p",', + error: null, + }, + { + elems: [], + foundElems: 0, + original: '"p" -> a', + returned: [], + typeFilter: -1, + userQuery: '"p" -> a', + error: "You cannot have more than one element if you use quotes", + }, + { + elems: [], + foundElems: 0, + original: '"a" -> "p"', + returned: [], + typeFilter: -1, + userQuery: '"a" -> "p"', + error: "Cannot have more than one literal search element", + }, + { + elems: [], + foundElems: 0, + original: '->"-"', + returned: [], + typeFilter: -1, + userQuery: '->"-"', + error: 'Unexpected `-` in a string element', + }, + { + elems: [], + foundElems: 0, + original: '"a', + returned: [], + typeFilter: -1, + userQuery: '"a', + error: 'Unclosed `"`', + }, + { + elems: [], + foundElems: 0, + original: '""', + returned: [], + typeFilter: -1, + userQuery: '""', + error: 'Cannot have empty string element', + }, +]; diff --git a/src/test/rustdoc-js-std/parser-returned.js b/src/test/rustdoc-js-std/parser-returned.js new file mode 100644 index 00000000000..6fce17dcabd --- /dev/null +++ b/src/test/rustdoc-js-std/parser-returned.js @@ -0,0 +1,99 @@ +const QUERY = [ + "-> F<P>", + "-> P", + "->,a", + "aaaaa->a", + "-> !", +]; + +const PARSED = [ + { + elems: [], + foundElems: 1, + original: "-> F<P>", + returned: [{ + name: "f", + fullPath: ["f"], + pathWithoutLast: [], + pathLast: "f", + generics: [ + { + name: "p", + fullPath: ["p"], + pathWithoutLast: [], + pathLast: "p", + generics: [], + }, + ], + }], + typeFilter: -1, + userQuery: "-> f<p>", + error: null, + }, + { + elems: [], + foundElems: 1, + original: "-> P", + returned: [{ + name: "p", + fullPath: ["p"], + pathWithoutLast: [], + pathLast: "p", + generics: [], + }], + typeFilter: -1, + userQuery: "-> p", + error: null, + }, + { + elems: [], + foundElems: 1, + original: "->,a", + returned: [{ + name: "a", + fullPath: ["a"], + pathWithoutLast: [], + pathLast: "a", + generics: [], + }], + typeFilter: -1, + userQuery: "->,a", + error: null, + }, + { + elems: [{ + name: "aaaaa", + fullPath: ["aaaaa"], + pathWithoutLast: [], + pathLast: "aaaaa", + generics: [], + }], + foundElems: 2, + original: "aaaaa->a", + returned: [{ + name: "a", + fullPath: ["a"], + pathWithoutLast: [], + pathLast: "a", + generics: [], + }], + typeFilter: -1, + userQuery: "aaaaa->a", + error: null, + }, + { + elems: [], + foundElems: 1, + original: "-> !", + returned: [{ + name: "!", + fullPath: ["!"], + pathWithoutLast: [], + pathLast: "!", + generics: [], + }], + typeFilter: -1, + userQuery: "-> !", + error: null, + }, +]; diff --git a/src/test/rustdoc-js-std/parser-separators.js b/src/test/rustdoc-js-std/parser-separators.js new file mode 100644 index 00000000000..5b7abdfa8d6 --- /dev/null +++ b/src/test/rustdoc-js-std/parser-separators.js @@ -0,0 +1,206 @@ +// ignore-tidy-tab + +const QUERY = [ + 'aaaaaa b', + 'a b', + 'a,b', + 'a\tb', + 'a<b c>', + 'a<b,c>', + 'a<b\tc>', +]; + +const PARSED = [ + { + elems: [ + { + name: 'aaaaaa', + fullPath: ['aaaaaa'], + pathWithoutLast: [], + pathLast: 'aaaaaa', + generics: [], + }, + { + name: 'b', + fullPath: ['b'], + pathWithoutLast: [], + pathLast: 'b', + generics: [], + }, + ], + foundElems: 2, + original: "aaaaaa b", + returned: [], + typeFilter: -1, + userQuery: "aaaaaa b", + error: null, + }, + { + elems: [ + { + name: 'a', + fullPath: ['a'], + pathWithoutLast: [], + pathLast: 'a', + generics: [], + }, + { + name: 'b', + fullPath: ['b'], + pathWithoutLast: [], + pathLast: 'b', + generics: [], + }, + ], + foundElems: 2, + original: "a b", + returned: [], + typeFilter: -1, + userQuery: "a b", + error: null, + }, + { + elems: [ + { + name: 'a', + fullPath: ['a'], + pathWithoutLast: [], + pathLast: 'a', + generics: [], + }, + { + name: 'b', + fullPath: ['b'], + pathWithoutLast: [], + pathLast: 'b', + generics: [], + }, + ], + foundElems: 2, + original: "a,b", + returned: [], + typeFilter: -1, + userQuery: "a,b", + error: null, + }, + { + elems: [ + { + name: 'a', + fullPath: ['a'], + pathWithoutLast: [], + pathLast: 'a', + generics: [], + }, + { + name: 'b', + fullPath: ['b'], + pathWithoutLast: [], + pathLast: 'b', + generics: [], + }, + ], + foundElems: 2, + original: "a\tb", + returned: [], + typeFilter: -1, + userQuery: "a\tb", + error: null, + }, + { + elems: [ + { + name: 'a', + fullPath: ['a'], + pathWithoutLast: [], + pathLast: 'a', + generics: [ + { + name: 'b', + fullPath: ['b'], + pathWithoutLast: [], + pathLast: 'b', + generics: [], + }, + { + name: 'c', + fullPath: ['c'], + pathWithoutLast: [], + pathLast: 'c', + generics: [], + }, + ], + }, + ], + foundElems: 1, + original: "a<b c>", + returned: [], + typeFilter: -1, + userQuery: "a<b c>", + error: null, + }, + { + elems: [ + { + name: 'a', + fullPath: ['a'], + pathWithoutLast: [], + pathLast: 'a', + generics: [ + { + name: 'b', + fullPath: ['b'], + pathWithoutLast: [], + pathLast: 'b', + generics: [], + }, + { + name: 'c', + fullPath: ['c'], + pathWithoutLast: [], + pathLast: 'c', + generics: [], + }, + ], + }, + ], + foundElems: 1, + original: "a<b,c>", + returned: [], + typeFilter: -1, + userQuery: "a<b,c>", + error: null, + }, + { + elems: [ + { + name: 'a', + fullPath: ['a'], + pathWithoutLast: [], + pathLast: 'a', + generics: [ + { + name: 'b', + fullPath: ['b'], + pathWithoutLast: [], + pathLast: 'b', + generics: [], + }, + { + name: 'c', + fullPath: ['c'], + pathWithoutLast: [], + pathLast: 'c', + generics: [], + }, + ], + }, + ], + foundElems: 1, + original: "a<b\tc>", + returned: [], + typeFilter: -1, + userQuery: "a<b\tc>", + error: null, + }, +]; diff --git a/src/test/rustdoc-js-std/parser-weird-queries.js b/src/test/rustdoc-js-std/parser-weird-queries.js new file mode 100644 index 00000000000..a3d85aeca5e --- /dev/null +++ b/src/test/rustdoc-js-std/parser-weird-queries.js @@ -0,0 +1,123 @@ +// This test is mostly to check that the parser still kinda outputs something +// (and doesn't enter an infinite loop!) even though the query is completely +// invalid. +const QUERY = [ + 'a b', + 'a b', + 'a,b(c)', + 'aaa,a', + ',,,,', + 'mod :', + 'mod\t:', +]; + +const PARSED = [ + { + elems: [ + { + name: "a", + fullPath: ["a"], + pathWithoutLast: [], + pathLast: "a", + generics: [], + }, + { + name: "b", + fullPath: ["b"], + pathWithoutLast: [], + pathLast: "b", + generics: [], + }, + ], + foundElems: 2, + original: "a b", + returned: [], + typeFilter: -1, + userQuery: "a b", + error: null, + }, + { + elems: [ + { + name: "a", + fullPath: ["a"], + pathWithoutLast: [], + pathLast: "a", + generics: [], + }, + { + name: "b", + fullPath: ["b"], + pathWithoutLast: [], + pathLast: "b", + generics: [], + }, + ], + foundElems: 2, + original: "a b", + returned: [], + typeFilter: -1, + userQuery: "a b", + error: null, + }, + { + elems: [], + foundElems: 0, + original: "a,b(c)", + returned: [], + typeFilter: -1, + userQuery: "a,b(c)", + error: "Unexpected `(`", + }, + { + elems: [ + { + name: "aaa", + fullPath: ["aaa"], + pathWithoutLast: [], + pathLast: "aaa", + generics: [], + }, + { + name: "a", + fullPath: ["a"], + pathWithoutLast: [], + pathLast: "a", + generics: [], + }, + ], + foundElems: 2, + original: "aaa,a", + returned: [], + typeFilter: -1, + userQuery: "aaa,a", + error: null, + }, + { + elems: [], + foundElems: 0, + original: ",,,,", + returned: [], + typeFilter: -1, + userQuery: ",,,,", + error: null, + }, + { + elems: [], + foundElems: 0, + original: 'mod :', + returned: [], + typeFilter: 0, + userQuery: 'mod :', + error: null, + }, + { + elems: [], + foundElems: 0, + original: 'mod\t:', + returned: [], + typeFilter: 0, + userQuery: 'mod\t:', + error: null, + }, +]; diff --git a/src/test/rustdoc-js-std/quoted.js b/src/test/rustdoc-js-std/quoted.js index 924129f86c8..aec8484a41f 100644 --- a/src/test/rustdoc-js-std/quoted.js +++ b/src/test/rustdoc-js-std/quoted.js @@ -1,4 +1,7 @@ +// ignore-order + const QUERY = '"error"'; +const FILTER_CRATE = 'std'; const EXPECTED = { 'others': [ @@ -6,7 +9,12 @@ const EXPECTED = { { 'path': 'std::fmt', 'name': 'Error' }, { 'path': 'std::io', 'name': 'Error' }, ], - 'in_args': [], + 'in_args': [ + { 'path': 'std::fmt::Error', 'name': 'eq' }, + { 'path': 'std::fmt::Error', 'name': 'cmp' }, + { 'path': 'std::fmt::Error', 'name': 'partial_cmp' }, + + ], 'returned': [ { 'path': 'std::fmt::LowerExp', 'name': 'fmt' }, ], diff --git a/src/test/rustdoc-js-std/struct-vec.js b/src/test/rustdoc-js-std/struct-vec.js index 2c808143bae..29609904b19 100644 --- a/src/test/rustdoc-js-std/struct-vec.js +++ b/src/test/rustdoc-js-std/struct-vec.js @@ -1,8 +1,8 @@ -const QUERY = 'struct:Vec'; +const QUERY = 'struct:VecD'; const EXPECTED = { 'others': [ - { 'path': 'std::vec', 'name': 'Vec' }, { 'path': 'std::collections', 'name': 'VecDeque' }, + { 'path': 'std::vec', 'name': 'Vec' }, ], }; diff --git a/src/test/rustdoc-js-std/typed-query.js b/src/test/rustdoc-js-std/typed-query.js index 3915ee7dc5d..25efbad2695 100644 --- a/src/test/rustdoc-js-std/typed-query.js +++ b/src/test/rustdoc-js-std/typed-query.js @@ -1,6 +1,7 @@ // exact-check const QUERY = 'macro:print'; +const FILTER_CRATE = 'std'; const EXPECTED = { 'others': [ @@ -9,6 +10,8 @@ const EXPECTED = { { 'path': 'std', 'name': 'println' }, { 'path': 'std', 'name': 'eprintln' }, { 'path': 'std::pin', 'name': 'pin' }, - { 'path': 'core::pin', 'name': 'pin' }, + { 'path': 'std::future', 'name': 'join' }, + { 'path': 'std', 'name': 'line' }, + { 'path': 'std', 'name': 'write' }, ], }; diff --git a/src/test/rustdoc-js-std/vec-new.js b/src/test/rustdoc-js-std/vec-new.js index e1a3256876b..cd0e8e7b4a9 100644 --- a/src/test/rustdoc-js-std/vec-new.js +++ b/src/test/rustdoc-js-std/vec-new.js @@ -4,6 +4,6 @@ const EXPECTED = { 'others': [ { 'path': 'std::vec::Vec', 'name': 'new' }, { 'path': 'std::vec::Vec', 'name': 'ne' }, - { 'path': 'std::rc::Rc', 'name': 'ne' }, + { 'path': 'alloc::vec::Vec', 'name': 'ne' }, ], }; diff --git a/src/test/rustdoc-js/doc-alias-filter.js b/src/test/rustdoc-js/doc-alias-filter.js index 4b1e2e29704..e06047ba760 100644 --- a/src/test/rustdoc-js/doc-alias-filter.js +++ b/src/test/rustdoc-js/doc-alias-filter.js @@ -1,6 +1,6 @@ // exact-check -const QUERY = 'true'; +const QUERY = '"true"'; const FILTER_CRATE = 'doc_alias_filter'; diff --git a/src/test/rustdoc-js/doc-alias.js b/src/test/rustdoc-js/doc-alias.js index ff188d51458..7bb0cbe388f 100644 --- a/src/test/rustdoc-js/doc-alias.js +++ b/src/test/rustdoc-js/doc-alias.js @@ -27,6 +27,7 @@ const QUERY = [ const EXPECTED = [ { + // StructItem 'others': [ { 'path': 'doc_alias', @@ -38,6 +39,7 @@ const EXPECTED = [ ], }, { + // StructFieldItem 'others': [ { 'path': 'doc_alias::Struct', @@ -49,6 +51,7 @@ const EXPECTED = [ ], }, { + // StructMethodItem 'others': [ { 'path': 'doc_alias::Struct', @@ -76,6 +79,7 @@ const EXPECTED = [ ], }, { + // ImplTraitFunction 'others': [ { 'path': 'doc_alias::Struct', @@ -87,6 +91,7 @@ const EXPECTED = [ ], }, { + // EnumItem 'others': [ { 'path': 'doc_alias', @@ -98,6 +103,7 @@ const EXPECTED = [ ], }, { + // VariantItem 'others': [ { 'path': 'doc_alias::Enum', @@ -109,6 +115,7 @@ const EXPECTED = [ ], }, { + // EnumMethodItem 'others': [ { 'path': 'doc_alias::Enum', @@ -120,6 +127,7 @@ const EXPECTED = [ ], }, { + // TypedefItem 'others': [ { 'path': 'doc_alias', @@ -131,6 +139,7 @@ const EXPECTED = [ ], }, { + // TraitItem 'others': [ { 'path': 'doc_alias', @@ -142,6 +151,7 @@ const EXPECTED = [ ], }, { + // TraitTypeItem 'others': [ { 'path': 'doc_alias::Trait', @@ -153,6 +163,7 @@ const EXPECTED = [ ], }, { + // AssociatedConstItem 'others': [ { 'path': 'doc_alias::Trait', @@ -164,6 +175,7 @@ const EXPECTED = [ ], }, { + // TraitFunctionItem 'others': [ { 'path': 'doc_alias::Trait', @@ -175,6 +187,7 @@ const EXPECTED = [ ], }, { + // FunctionItem 'others': [ { 'path': 'doc_alias', @@ -186,6 +199,7 @@ const EXPECTED = [ ], }, { + // ModuleItem 'others': [ { 'path': 'doc_alias', @@ -197,6 +211,7 @@ const EXPECTED = [ ], }, { + // ConstItem 'others': [ { 'path': 'doc_alias', @@ -212,6 +227,7 @@ const EXPECTED = [ ], }, { + // StaticItem 'others': [ { 'path': 'doc_alias', @@ -223,6 +239,7 @@ const EXPECTED = [ ], }, { + // UnionItem 'others': [ { 'path': 'doc_alias', @@ -240,6 +257,7 @@ const EXPECTED = [ ], }, { + // UnionFieldItem 'others': [ { 'path': 'doc_alias::Union', @@ -251,6 +269,7 @@ const EXPECTED = [ ], }, { + // UnionMethodItem 'others': [ { 'path': 'doc_alias::Union', @@ -262,6 +281,7 @@ const EXPECTED = [ ], }, { + // MacroItem 'others': [ { 'path': 'doc_alias', diff --git a/src/test/rustdoc-js/generics.js b/src/test/rustdoc-js/generics.js index 63a9ad53812..5e5ba7cd9ac 100644 --- a/src/test/rustdoc-js/generics.js +++ b/src/test/rustdoc-js/generics.js @@ -1,16 +1,18 @@ // exact-check const QUERY = [ - '"R<P>"', + 'R<P>', '"P"', 'P', - '"ExtraCreditStructMulti<ExtraCreditInnerMulti, ExtraCreditInnerMulti>"', + 'ExtraCreditStructMulti<ExtraCreditInnerMulti, ExtraCreditInnerMulti>', 'TraitCat', 'TraitDog', + 'Result<String>', ]; const EXPECTED = [ { + // R<P> 'returned': [ { 'path': 'generics', 'name': 'alef' }, ], @@ -19,6 +21,7 @@ const EXPECTED = [ ], }, { + // "P" 'others': [ { 'path': 'generics', 'name': 'P' }, ], @@ -30,29 +33,41 @@ const EXPECTED = [ ], }, { + // P 'returned': [ { 'path': 'generics', 'name': 'alef' }, - { 'path': 'generics', 'name': 'bet' }, ], 'in_args': [ { 'path': 'generics', 'name': 'alpha' }, - { 'path': 'generics', 'name': 'beta' }, ], }, { + // "ExtraCreditStructMulti"<ExtraCreditInnerMulti, ExtraCreditInnerMulti> 'in_args': [ { 'path': 'generics', 'name': 'extracreditlabhomework' }, ], 'returned': [], }, { + // TraitCat 'in_args': [ { 'path': 'generics', 'name': 'gamma' }, ], }, { + // TraitDog 'in_args': [ { 'path': 'generics', 'name': 'gamma' }, ], }, + { + // Result<String> + 'others': [], + 'returned': [ + { 'path': 'generics', 'name': 'super_soup' }, + ], + 'in_args': [ + { 'path': 'generics', 'name': 'super_soup' }, + ], + }, ]; diff --git a/src/test/rustdoc-js/generics.rs b/src/test/rustdoc-js/generics.rs index 5e11a6d6018..055c51c7ec5 100644 --- a/src/test/rustdoc-js/generics.rs +++ b/src/test/rustdoc-js/generics.rs @@ -24,3 +24,5 @@ pub trait TraitCat {} pub trait TraitDog {} pub fn gamma<T: TraitCat + TraitDog>(t: T) {} + +pub fn super_soup(s: Result<String, i32>) -> Result<String, i32> { s } diff --git a/src/test/rustdoc-ui/intra-doc/email-address-localhost.rs b/src/test/rustdoc-ui/intra-doc/email-address-localhost.rs index 9465e8e7ab9..7a5156e81c4 100644 --- a/src/test/rustdoc-ui/intra-doc/email-address-localhost.rs +++ b/src/test/rustdoc-ui/intra-doc/email-address-localhost.rs @@ -1,7 +1,7 @@ // normalize-stderr-test: "nightly|beta|1\.[0-9][0-9]\.[0-9]" -> "$$CHANNEL" +// check-pass #![deny(warnings)] //! Email me at <hello@localhost>. -//~^ ERROR unknown disambiguator `hello` //! This should *not* warn: <hello@example.com>. diff --git a/src/test/rustdoc-ui/intra-doc/email-address-localhost.stderr b/src/test/rustdoc-ui/intra-doc/email-address-localhost.stderr deleted file mode 100644 index 1b07828fc6e..00000000000 --- a/src/test/rustdoc-ui/intra-doc/email-address-localhost.stderr +++ /dev/null @@ -1,16 +0,0 @@ -error: unknown disambiguator `hello` - --> $DIR/email-address-localhost.rs:4:18 - | -LL | //! Email me at <hello@localhost>. - | ^^^^^ - | -note: the lint level is defined here - --> $DIR/email-address-localhost.rs:2:9 - | -LL | #![deny(warnings)] - | ^^^^^^^^ - = note: `#[deny(rustdoc::broken_intra_doc_links)]` implied by `#[deny(warnings)]` - = note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators - -error: aborting due to previous error - diff --git a/src/test/rustdoc-ui/intra-doc/macro-rules-error.rs b/src/test/rustdoc-ui/intra-doc/macro-rules-error.rs new file mode 100644 index 00000000000..84d63c20aa8 --- /dev/null +++ b/src/test/rustdoc-ui/intra-doc/macro-rules-error.rs @@ -0,0 +1,27 @@ +// `macro_rules` scopes are respected during doc link resolution. + +// compile-flags: --document-private-items + +#![deny(rustdoc::broken_intra_doc_links)] + +mod no_escape { + macro_rules! before_but_limited_to_module { + () => {}; + } +} + +/// [before_but_limited_to_module] FIXME: This error should be reported +// ERROR unresolved link to `before_but_limited_to_module` +/// [after] FIXME: This error should be reported +// ERROR unresolved link to `after` +/// [str] FIXME: This error shouldn not be reported +//~^ ERROR `str` is both a builtin type and a macro +fn check() {} + +macro_rules! after { + () => {}; +} + +macro_rules! str { + () => {}; +} diff --git a/src/test/rustdoc-ui/intra-doc/macro-rules-error.stderr b/src/test/rustdoc-ui/intra-doc/macro-rules-error.stderr new file mode 100644 index 00000000000..4b984f4f6c0 --- /dev/null +++ b/src/test/rustdoc-ui/intra-doc/macro-rules-error.stderr @@ -0,0 +1,22 @@ +error: `str` is both a builtin type and a macro + --> $DIR/macro-rules-error.rs:17:6 + | +LL | /// [str] FIXME: This error shouldn not be reported + | ^^^ ambiguous link + | +note: the lint level is defined here + --> $DIR/macro-rules-error.rs:5:9 + | +LL | #![deny(rustdoc::broken_intra_doc_links)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: to link to the builtin type, prefix with `prim@` + | +LL | /// [prim@str] FIXME: This error shouldn not be reported + | +++++ +help: to link to the macro, add an exclamation mark + | +LL | /// [str!] FIXME: This error shouldn not be reported + | + + +error: aborting due to previous error + diff --git a/src/test/rustdoc-ui/intra-doc/macro-rules.rs b/src/test/rustdoc-ui/intra-doc/macro-rules.rs index a14e4bdf1d7..3aeb370ef6d 100644 --- a/src/test/rustdoc-ui/intra-doc/macro-rules.rs +++ b/src/test/rustdoc-ui/intra-doc/macro-rules.rs @@ -7,3 +7,18 @@ macro_rules! foo { /// [foo!] pub fn baz() {} + +#[macro_use] +mod macros { + macro_rules! escaping { + () => {}; + } +} + +pub mod inner { + /// [foo!] + /// [escaping] + pub fn baz() { + foo!(); + } +} diff --git a/src/test/rustdoc-ui/issue-91713.stdout b/src/test/rustdoc-ui/issue-91713.stdout index d0372d4945f..a19e452b459 100644 --- a/src/test/rustdoc-ui/issue-91713.stdout +++ b/src/test/rustdoc-ui/issue-91713.stdout @@ -1,7 +1,6 @@ Available passes for running rustdoc: check_doc_test_visibility - run various visibility-related lints on doctests strip-hidden - strips all `#[doc(hidden)]` items from the output - unindent-comments - removes excess indentation on comments in order for markdown to like it strip-private - strips all private items from a crate which cannot be seen externally, implies strip-priv-imports strip-priv-imports - strips all private import statements (`use`, `extern crate`) from a crate propagate-doc-cfg - propagates `#[doc(cfg(...))]` to child items @@ -14,7 +13,6 @@ check-invalid-html-tags - detects invalid HTML tags in doc comments Default passes for rustdoc: collect-trait-impls - unindent-comments check_doc_test_visibility strip-hidden (when not --document-hidden-items) strip-private (when not --document-private-items) diff --git a/src/test/rustdoc/deref-slice-core.rs b/src/test/rustdoc/deref-slice-core.rs new file mode 100644 index 00000000000..cccf273a820 --- /dev/null +++ b/src/test/rustdoc/deref-slice-core.rs @@ -0,0 +1,22 @@ +// https://github.com/rust-lang/rust/issues/95325 +// +// Show methods reachable from Deref of primitive. +#![no_std] + +use core::ops::Deref; + +// @has 'deref_slice_core/struct.MyArray.html' +// @has '-' '//*[@id="deref-methods-%5BT%5D"]' 'Methods from Deref<Target = [T]>' +// @has '-' '//*[@class="impl-items"]//*[@id="method.len"]' 'pub fn len(&self)' + +pub struct MyArray<T> { + array: [T; 10], +} + +impl<T> Deref for MyArray<T> { + type Target = [T]; + + fn deref(&self) -> &Self::Target { + &self.array + } +} diff --git a/src/test/rustdoc/early-unindent.rs b/src/test/rustdoc/early-unindent.rs new file mode 100644 index 00000000000..791a452c957 --- /dev/null +++ b/src/test/rustdoc/early-unindent.rs @@ -0,0 +1,26 @@ +// This is a regression for https://github.com/rust-lang/rust/issues/96079. + +#![crate_name = "foo"] + +pub mod app { + pub struct S; + + impl S { + // @has 'foo/app/struct.S.html' + // @has - '//a[@href="../enums/enum.Foo.html#method.by_name"]' 'Foo::by_name' + /** + Doc comment hello! [`Foo::by_name`](`crate::enums::Foo::by_name`). + */ + pub fn whatever(&self) {} + } +} + +pub mod enums { + pub enum Foo { + Bar, + } + + impl Foo { + pub fn by_name(&self) {} + } +} diff --git a/src/test/rustdoc/issue-95873.rs b/src/test/rustdoc/issue-95873.rs new file mode 100644 index 00000000000..ff33fb63a0b --- /dev/null +++ b/src/test/rustdoc/issue-95873.rs @@ -0,0 +1,2 @@ +// @has issue_95873/index.html "//*[@class='item-left import-item']" "pub use ::std as x;" +pub use ::std as x; diff --git a/src/test/rustdoc/issue-96381.rs b/src/test/rustdoc/issue-96381.rs new file mode 100644 index 00000000000..f0f123f85a0 --- /dev/null +++ b/src/test/rustdoc/issue-96381.rs @@ -0,0 +1,16 @@ +// should-fail + +#![allow(unused)] + +trait Foo<T>: Sized { + fn bar(i: i32, t: T, s: &Self) -> (T, i32); +} + +impl Foo<usize> for () { + fn bar(i: _, t: _, s: _) -> _ { + //~^ ERROR the placeholder `_` is not allowed within types on item signatures for functions + (1, 2) + } +} + +fn main() {} diff --git a/src/test/rustdoc/where.SWhere_Simd_item-decl.html b/src/test/rustdoc/where.SWhere_Simd_item-decl.html new file mode 100644 index 00000000000..0133bcaeb66 --- /dev/null +++ b/src/test/rustdoc/where.SWhere_Simd_item-decl.html @@ -0,0 +1 @@ +<div class="docblock item-decl"><pre class="rust struct"><code>pub struct Simd<T>(_) <br /><span class="where">where<br />    T: <a class="trait" href="trait.MyTrait.html" title="trait foo::MyTrait">MyTrait</a></span>;</code></pre></div> \ No newline at end of file diff --git a/src/test/rustdoc/where.SWhere_TraitWhere_item-decl.html b/src/test/rustdoc/where.SWhere_TraitWhere_item-decl.html new file mode 100644 index 00000000000..54026ff034e --- /dev/null +++ b/src/test/rustdoc/where.SWhere_TraitWhere_item-decl.html @@ -0,0 +1,3 @@ +<div class="docblock item-decl"><pre class="rust trait"><code>pub trait TraitWhere { + type <a href="#associatedtype.Item" class="associatedtype">Item</a><'a><br />    <span class="where">where<br />        Self: 'a</span>; +}</code></pre></div> \ No newline at end of file diff --git a/src/test/rustdoc/where.rs b/src/test/rustdoc/where.rs index 549cfff96cb..50a5722fbaf 100644 --- a/src/test/rustdoc/where.rs +++ b/src/test/rustdoc/where.rs @@ -1,3 +1,4 @@ +#![feature(generic_associated_types)] #![crate_name = "foo"] pub trait MyTrait { fn dummy(&self) { } } @@ -19,6 +20,18 @@ impl<D> Delta<D> where D: MyTrait { pub struct Echo<E>(E); +// @has 'foo/struct.Simd.html' +// @snapshot SWhere_Simd_item-decl - '//div[@class="docblock item-decl"]' +pub struct Simd<T>([T; 1]) +where + T: MyTrait; + +// @has 'foo/trait.TraitWhere.html' +// @snapshot SWhere_TraitWhere_item-decl - '//div[@class="docblock item-decl"]' +pub trait TraitWhere { + type Item<'a> where Self: 'a; +} + // @has foo/struct.Echo.html '//*[@class="impl has-srclink"]//h3[@class="code-header in-band"]' \ // "impl<E> MyTrait for Echo<E> where E: MyTrait" // @has foo/trait.MyTrait.html '//*[@id="implementors-list"]//h3[@class="code-header in-band"]' \ diff --git a/src/test/ui-fulldeps/issue-15149.rs b/src/test/ui-fulldeps/issue-15149.rs index c7ef5ad70a1..064472f5785 100644 --- a/src/test/ui-fulldeps/issue-15149.rs +++ b/src/test/ui-fulldeps/issue-15149.rs @@ -5,10 +5,11 @@ // ignore-cross-compile use std::env; +use std::ffi::OsStr; use std::fs; +use std::path::PathBuf; use std::process; use std::str; -use std::path::PathBuf; fn main() { // If we're the child, make sure we were invoked correctly @@ -18,8 +19,8 @@ fn main() { // checking that it ends_with the executable name. This // is needed because of Windows, which has a different behavior. // See #15149 for more info. - return assert!(args[0].ends_with(&format!("mytest{}", - env::consts::EXE_SUFFIX))); + let my_path = env::current_exe().unwrap(); + return assert_eq!(my_path.file_stem(), Some(OsStr::new("mytest"))); } test(); @@ -28,14 +29,13 @@ fn main() { fn test() { // If we're the parent, copy our own binary to a new directory. let my_path = env::current_exe().unwrap(); - let my_dir = my_path.parent().unwrap(); + let my_dir = my_path.parent().unwrap(); let child_dir = PathBuf::from(env::var_os("RUST_TEST_TMPDIR").unwrap()); let child_dir = child_dir.join("issue-15140-child"); fs::create_dir_all(&child_dir).unwrap(); - let child_path = child_dir.join(&format!("mytest{}", - env::consts::EXE_SUFFIX)); + let child_path = child_dir.join(&format!("mytest{}", env::consts::EXE_SUFFIX)); fs::copy(&my_path, &child_path).unwrap(); // Append the new directory to our own PATH. @@ -45,12 +45,13 @@ fn test() { env::join_paths(paths).unwrap() }; - let child_output = process::Command::new("mytest").env("PATH", &path) - .arg("child") - .output().unwrap(); + let child_output = + process::Command::new("mytest").env("PATH", &path).arg("child").output().unwrap(); - assert!(child_output.status.success(), - "child assertion failed\n child stdout:\n {}\n child stderr:\n {}", - str::from_utf8(&child_output.stdout).unwrap(), - str::from_utf8(&child_output.stderr).unwrap()); + assert!( + child_output.status.success(), + "child assertion failed\n child stdout:\n {}\n child stderr:\n {}", + str::from_utf8(&child_output.stdout).unwrap(), + str::from_utf8(&child_output.stderr).unwrap() + ); } diff --git a/src/test/ui-fulldeps/session-derive-errors.rs b/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.rs index adec548b390..efbf78ac87d 100644 --- a/src/test/ui-fulldeps/session-derive-errors.rs +++ b/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.rs @@ -15,7 +15,7 @@ use rustc_span::symbol::Ident; use rustc_span::Span; extern crate rustc_macros; -use rustc_macros::SessionDiagnostic; +use rustc_macros::{SessionDiagnostic, SessionSubdiagnostic}; extern crate rustc_middle; use rustc_middle::ty::Ty; @@ -44,67 +44,74 @@ enum SessionDiagnosticOnEnum { #[derive(SessionDiagnostic)] #[error(code = "E0123", slug = "foo")] #[error = "E0123"] -//~^ ERROR `#[error = ...]` is not a valid `SessionDiagnostic` struct attribute +//~^ ERROR `#[error = ...]` is not a valid attribute struct WrongStructAttrStyle {} #[derive(SessionDiagnostic)] #[nonsense(code = "E0123", slug = "foo")] -//~^ ERROR `#[nonsense(...)]` is not a valid `SessionDiagnostic` struct attribute +//~^ ERROR `#[nonsense(...)]` is not a valid attribute //~^^ ERROR diagnostic kind not specified //~^^^ ERROR cannot find attribute `nonsense` in this scope struct InvalidStructAttr {} #[derive(SessionDiagnostic)] #[error("E0123")] -//~^ ERROR `#[error("...")]` is not a valid `SessionDiagnostic` struct attribute +//~^ ERROR `#[error("...")]` is not a valid attribute //~^^ ERROR `slug` not specified struct InvalidLitNestedAttr {} #[derive(SessionDiagnostic)] #[error(nonsense, code = "E0123", slug = "foo")] -//~^ ERROR `#[error(nonsense)]` is not a valid `SessionDiagnostic` struct attribute +//~^ ERROR `#[error(nonsense)]` is not a valid attribute struct InvalidNestedStructAttr {} #[derive(SessionDiagnostic)] #[error(nonsense("foo"), code = "E0123", slug = "foo")] -//~^ ERROR `#[error(nonsense(...))]` is not a valid `SessionDiagnostic` struct attribute +//~^ ERROR `#[error(nonsense(...))]` is not a valid attribute struct InvalidNestedStructAttr1 {} #[derive(SessionDiagnostic)] #[error(nonsense = "...", code = "E0123", slug = "foo")] -//~^ ERROR `#[error(nonsense = ...)]` is not a valid `SessionDiagnostic` struct attribute +//~^ ERROR `#[error(nonsense = ...)]` is not a valid attribute struct InvalidNestedStructAttr2 {} #[derive(SessionDiagnostic)] #[error(nonsense = 4, code = "E0123", slug = "foo")] -//~^ ERROR `#[error(nonsense = ...)]` is not a valid `SessionDiagnostic` struct attribute +//~^ ERROR `#[error(nonsense = ...)]` is not a valid attribute struct InvalidNestedStructAttr3 {} #[derive(SessionDiagnostic)] #[error(code = "E0123", slug = "foo")] struct WrongPlaceField { #[suggestion = "bar"] - //~^ ERROR `#[suggestion = ...]` is not a valid `SessionDiagnostic` field attribute + //~^ ERROR `#[suggestion = ...]` is not a valid attribute sp: Span, } #[derive(SessionDiagnostic)] #[error(code = "E0123", slug = "foo")] -#[error(code = "E0456", slug = "bar")] //~ ERROR `error` specified multiple times +#[error(code = "E0456", slug = "bar")] +//~^ ERROR specified multiple times +//~^^ ERROR specified multiple times +//~^^^ ERROR specified multiple times struct ErrorSpecifiedTwice {} #[derive(SessionDiagnostic)] #[error(code = "E0123", slug = "foo")] #[warning(code = "E0293", slug = "bar")] -//~^ ERROR `warning` specified when `error` was already specified +//~^ ERROR specified multiple times +//~^^ ERROR specified multiple times +//~^^^ ERROR specified multiple times struct WarnSpecifiedAfterError {} #[derive(SessionDiagnostic)] -#[error(code = "E0456", code = "E0457", slug = "bar")] //~ ERROR `code` specified multiple times +#[error(code = "E0456", code = "E0457", slug = "bar")] +//~^ ERROR specified multiple times struct CodeSpecifiedTwice {} #[derive(SessionDiagnostic)] -#[error(code = "E0456", slug = "foo", slug = "bar")] //~ ERROR `slug` specified multiple times +#[error(code = "E0456", slug = "foo", slug = "bar")] +//~^ ERROR specified multiple times struct SlugSpecifiedTwice {} #[derive(SessionDiagnostic)] @@ -130,7 +137,7 @@ struct MessageWrongType { #[error(code = "E0123", slug = "foo")] struct InvalidPathFieldAttr { #[nonsense] - //~^ ERROR `#[nonsense]` is not a valid `SessionDiagnostic` field attribute + //~^ ERROR `#[nonsense]` is not a valid attribute //~^^ ERROR cannot find attribute `nonsense` in this scope foo: String, } @@ -215,7 +222,7 @@ struct SuggestWithoutCode { #[error(code = "E0123", slug = "foo")] struct SuggestWithBadKey { #[suggestion(nonsense = "bar")] - //~^ ERROR `#[suggestion(nonsense = ...)]` is not a valid `SessionDiagnostic` field attribute + //~^ ERROR `#[suggestion(nonsense = ...)]` is not a valid attribute suggestion: (Span, Applicability), } @@ -223,7 +230,7 @@ struct SuggestWithBadKey { #[error(code = "E0123", slug = "foo")] struct SuggestWithShorthandMsg { #[suggestion(msg = "bar")] - //~^ ERROR `#[suggestion(msg = ...)]` is not a valid `SessionDiagnostic` field attribute + //~^ ERROR `#[suggestion(msg = ...)]` is not a valid attribute suggestion: (Span, Applicability), } @@ -276,7 +283,7 @@ struct SuggestWithDuplicateApplicabilityAndSpan { #[error(code = "E0123", slug = "foo")] struct WrongKindOfAnnotation { #[label("bar")] - //~^ ERROR `#[label(...)]` is not a valid `SessionDiagnostic` field attribute + //~^ ERROR `#[label(...)]` is not a valid attribute z: Span, } @@ -426,3 +433,44 @@ struct ErrorWithNoteWrongOrder { struct ErrorWithNoteCustomWrongOrder { val: String, } + +#[derive(SessionDiagnostic)] +#[error(code = "E0123", slug = "foo")] +struct ApplicabilityInBoth { + #[suggestion(message = "bar", code = "...", applicability = "maybe-incorrect")] + //~^ ERROR applicability cannot be set in both the field and attribute + suggestion: (Span, Applicability), +} + +#[derive(SessionDiagnostic)] +#[error(code = "E0123", slug = "foo")] +struct InvalidApplicability { + #[suggestion(message = "bar", code = "...", applicability = "batman")] + //~^ ERROR invalid applicability + suggestion: Span, +} + +#[derive(SessionDiagnostic)] +#[error(code = "E0123", slug = "foo")] +struct ValidApplicability { + #[suggestion(message = "bar", code = "...", applicability = "maybe-incorrect")] + suggestion: Span, +} + +#[derive(SessionDiagnostic)] +#[error(code = "E0123", slug = "foo")] +struct NoApplicability { + #[suggestion(message = "bar", code = "...")] + suggestion: Span, +} + +#[derive(SessionSubdiagnostic)] +#[note(slug = "note")] +struct Note; + +#[derive(SessionDiagnostic)] +#[error(slug = "subdiagnostic")] +struct Subdiagnostic { + #[subdiagnostic] + note: Note, +} diff --git a/src/test/ui-fulldeps/session-derive-errors.stderr b/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr index a528ae1607f..b1738b60bc0 100644 --- a/src/test/ui-fulldeps/session-derive-errors.stderr +++ b/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr @@ -1,5 +1,5 @@ error: `#[derive(SessionDiagnostic)]` can only be used on structs - --> $DIR/session-derive-errors.rs:37:1 + --> $DIR/diagnostic-derive.rs:37:1 | LL | / #[error(code = "E0123", slug = "foo")] LL | | @@ -9,20 +9,22 @@ LL | | Bar, LL | | } | |_^ -error: `#[error = ...]` is not a valid `SessionDiagnostic` struct attribute - --> $DIR/session-derive-errors.rs:46:1 +error: `#[error = ...]` is not a valid attribute + --> $DIR/diagnostic-derive.rs:46:1 | LL | #[error = "E0123"] | ^^^^^^^^^^^^^^^^^^ -error: `#[nonsense(...)]` is not a valid `SessionDiagnostic` struct attribute - --> $DIR/session-derive-errors.rs:51:1 +error: `#[nonsense(...)]` is not a valid attribute + --> $DIR/diagnostic-derive.rs:51:1 | LL | #[nonsense(code = "E0123", slug = "foo")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: only `error` and `warning` are valid attributes error: diagnostic kind not specified - --> $DIR/session-derive-errors.rs:51:1 + --> $DIR/diagnostic-derive.rs:51:1 | LL | / #[nonsense(code = "E0123", slug = "foo")] LL | | @@ -33,14 +35,14 @@ LL | | struct InvalidStructAttr {} | = help: use the `#[error(...)]` attribute to create an error -error: `#[error("...")]` is not a valid `SessionDiagnostic` struct attribute - --> $DIR/session-derive-errors.rs:58:9 +error: `#[error("...")]` is not a valid attribute + --> $DIR/diagnostic-derive.rs:58:9 | LL | #[error("E0123")] | ^^^^^^^ error: `slug` not specified - --> $DIR/session-derive-errors.rs:58:1 + --> $DIR/diagnostic-derive.rs:58:1 | LL | / #[error("E0123")] LL | | @@ -50,88 +52,138 @@ LL | | struct InvalidLitNestedAttr {} | = help: use the `#[error(slug = "...")]` attribute to set this diagnostic's slug -error: `#[error(nonsense)]` is not a valid `SessionDiagnostic` struct attribute - --> $DIR/session-derive-errors.rs:64:9 +error: `#[error(nonsense)]` is not a valid attribute + --> $DIR/diagnostic-derive.rs:64:9 | LL | #[error(nonsense, code = "E0123", slug = "foo")] | ^^^^^^^^ -error: `#[error(nonsense(...))]` is not a valid `SessionDiagnostic` struct attribute - --> $DIR/session-derive-errors.rs:69:9 +error: `#[error(nonsense(...))]` is not a valid attribute + --> $DIR/diagnostic-derive.rs:69:9 | LL | #[error(nonsense("foo"), code = "E0123", slug = "foo")] | ^^^^^^^^^^^^^^^ -error: `#[error(nonsense = ...)]` is not a valid `SessionDiagnostic` struct attribute - --> $DIR/session-derive-errors.rs:74:9 +error: `#[error(nonsense = ...)]` is not a valid attribute + --> $DIR/diagnostic-derive.rs:74:9 | LL | #[error(nonsense = "...", code = "E0123", slug = "foo")] | ^^^^^^^^^^^^^^^^ + | + = help: only `slug` and `code` are valid nested attributes -error: `#[error(nonsense = ...)]` is not a valid `SessionDiagnostic` struct attribute - --> $DIR/session-derive-errors.rs:79:9 +error: `#[error(nonsense = ...)]` is not a valid attribute + --> $DIR/diagnostic-derive.rs:79:9 | LL | #[error(nonsense = 4, code = "E0123", slug = "foo")] | ^^^^^^^^^^^^ - | - = help: value must be a string -error: `#[suggestion = ...]` is not a valid `SessionDiagnostic` field attribute - --> $DIR/session-derive-errors.rs:86:5 +error: `#[suggestion = ...]` is not a valid attribute + --> $DIR/diagnostic-derive.rs:86:5 | LL | #[suggestion = "bar"] | ^^^^^^^^^^^^^^^^^^^^^ + | + = help: only `label`, `note` and `help` are valid field attributes -error: `error` specified multiple times - --> $DIR/session-derive-errors.rs:93:1 +error: specified multiple times + --> $DIR/diagnostic-derive.rs:93:1 | LL | #[error(code = "E0456", slug = "bar")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: previously specified here - --> $DIR/session-derive-errors.rs:92:1 + --> $DIR/diagnostic-derive.rs:92:1 | LL | #[error(code = "E0123", slug = "foo")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: `warning` specified when `error` was already specified - --> $DIR/session-derive-errors.rs:98:1 +error: specified multiple times + --> $DIR/diagnostic-derive.rs:93:16 + | +LL | #[error(code = "E0456", slug = "bar")] + | ^^^^^^^ + | +note: previously specified here + --> $DIR/diagnostic-derive.rs:92:16 + | +LL | #[error(code = "E0123", slug = "foo")] + | ^^^^^^^ + +error: specified multiple times + --> $DIR/diagnostic-derive.rs:93:32 + | +LL | #[error(code = "E0456", slug = "bar")] + | ^^^^^ + | +note: previously specified here + --> $DIR/diagnostic-derive.rs:92:32 + | +LL | #[error(code = "E0123", slug = "foo")] + | ^^^^^ + +error: specified multiple times + --> $DIR/diagnostic-derive.rs:101:1 | LL | #[warning(code = "E0293", slug = "bar")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: previously specified here - --> $DIR/session-derive-errors.rs:97:1 + --> $DIR/diagnostic-derive.rs:100:1 | LL | #[error(code = "E0123", slug = "foo")] | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: `code` specified multiple times - --> $DIR/session-derive-errors.rs:103:32 +error: specified multiple times + --> $DIR/diagnostic-derive.rs:101:18 + | +LL | #[warning(code = "E0293", slug = "bar")] + | ^^^^^^^ + | +note: previously specified here + --> $DIR/diagnostic-derive.rs:100:16 + | +LL | #[error(code = "E0123", slug = "foo")] + | ^^^^^^^ + +error: specified multiple times + --> $DIR/diagnostic-derive.rs:101:34 + | +LL | #[warning(code = "E0293", slug = "bar")] + | ^^^^^ + | +note: previously specified here + --> $DIR/diagnostic-derive.rs:100:32 + | +LL | #[error(code = "E0123", slug = "foo")] + | ^^^^^ + +error: specified multiple times + --> $DIR/diagnostic-derive.rs:108:32 | LL | #[error(code = "E0456", code = "E0457", slug = "bar")] | ^^^^^^^ | note: previously specified here - --> $DIR/session-derive-errors.rs:103:16 + --> $DIR/diagnostic-derive.rs:108:16 | LL | #[error(code = "E0456", code = "E0457", slug = "bar")] | ^^^^^^^ -error: `slug` specified multiple times - --> $DIR/session-derive-errors.rs:107:46 +error: specified multiple times + --> $DIR/diagnostic-derive.rs:113:46 | LL | #[error(code = "E0456", slug = "foo", slug = "bar")] | ^^^^^ | note: previously specified here - --> $DIR/session-derive-errors.rs:107:32 + --> $DIR/diagnostic-derive.rs:113:32 | LL | #[error(code = "E0456", slug = "foo", slug = "bar")] | ^^^^^ error: diagnostic kind not specified - --> $DIR/session-derive-errors.rs:111:1 + --> $DIR/diagnostic-derive.rs:118:1 | LL | struct KindNotProvided {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -139,7 +191,7 @@ LL | struct KindNotProvided {} = help: use the `#[error(...)]` attribute to create an error error: `slug` not specified - --> $DIR/session-derive-errors.rs:114:1 + --> $DIR/diagnostic-derive.rs:121:1 | LL | / #[error(code = "E0456")] LL | | struct SlugNotProvided {} @@ -148,31 +200,33 @@ LL | | struct SlugNotProvided {} = help: use the `#[error(slug = "...")]` attribute to set this diagnostic's slug error: the `#[primary_span]` attribute can only be applied to fields of type `Span` - --> $DIR/session-derive-errors.rs:124:5 + --> $DIR/diagnostic-derive.rs:131:5 | LL | #[primary_span] | ^^^^^^^^^^^^^^^ -error: `#[nonsense]` is not a valid `SessionDiagnostic` field attribute - --> $DIR/session-derive-errors.rs:132:5 +error: `#[nonsense]` is not a valid attribute + --> $DIR/diagnostic-derive.rs:139:5 | LL | #[nonsense] | ^^^^^^^^^^^ + | + = help: only `skip_arg`, `primary_span`, `label`, `note`, `help` and `subdiagnostic` are valid field attributes error: the `#[label = ...]` attribute can only be applied to fields of type `Span` - --> $DIR/session-derive-errors.rs:149:5 + --> $DIR/diagnostic-derive.rs:156:5 | LL | #[label = "bar"] | ^^^^^^^^^^^^^^^^ error: `name` doesn't refer to a field on this type - --> $DIR/session-derive-errors.rs:157:42 + --> $DIR/diagnostic-derive.rs:164:42 | LL | #[suggestion(message = "bar", code = "{name}")] | ^^^^^^^^ error: invalid format string: expected `'}'` but string was terminated - --> $DIR/session-derive-errors.rs:162:16 + --> $DIR/diagnostic-derive.rs:169:16 | LL | #[derive(SessionDiagnostic)] | - ^ expected `'}'` in format string @@ -183,7 +237,7 @@ LL | #[derive(SessionDiagnostic)] = note: this error originates in the derive macro `SessionDiagnostic` (in Nightly builds, run with -Z macro-backtrace for more info) error: invalid format string: unmatched `}` found - --> $DIR/session-derive-errors.rs:172:15 + --> $DIR/diagnostic-derive.rs:179:15 | LL | #[derive(SessionDiagnostic)] | ^ unmatched `}` in format string @@ -192,25 +246,29 @@ LL | #[derive(SessionDiagnostic)] = note: this error originates in the derive macro `SessionDiagnostic` (in Nightly builds, run with -Z macro-backtrace for more info) error: the `#[label = ...]` attribute can only be applied to fields of type `Span` - --> $DIR/session-derive-errors.rs:192:5 + --> $DIR/diagnostic-derive.rs:199:5 | LL | #[label = "bar"] | ^^^^^^^^^^^^^^^^ -error: `#[suggestion(nonsense = ...)]` is not a valid `SessionDiagnostic` field attribute - --> $DIR/session-derive-errors.rs:217:18 +error: `#[suggestion(nonsense = ...)]` is not a valid attribute + --> $DIR/diagnostic-derive.rs:224:18 | LL | #[suggestion(nonsense = "bar")] | ^^^^^^^^^^^^^^^^ + | + = help: only `message`, `code` and `applicability` are valid field attributes -error: `#[suggestion(msg = ...)]` is not a valid `SessionDiagnostic` field attribute - --> $DIR/session-derive-errors.rs:225:18 +error: `#[suggestion(msg = ...)]` is not a valid attribute + --> $DIR/diagnostic-derive.rs:232:18 | LL | #[suggestion(msg = "bar")] | ^^^^^^^^^^^ + | + = help: only `message`, `code` and `applicability` are valid field attributes error: wrong field type for suggestion - --> $DIR/session-derive-errors.rs:247:5 + --> $DIR/diagnostic-derive.rs:254:5 | LL | / #[suggestion(message = "bar", code = "This is suggested code")] LL | | @@ -220,7 +278,7 @@ LL | | suggestion: Applicability, = help: `#[suggestion(...)]` should be applied to fields of type `Span` or `(Span, Applicability)` error: type of field annotated with `#[suggestion(...)]` contains more than one `Span` - --> $DIR/session-derive-errors.rs:262:5 + --> $DIR/diagnostic-derive.rs:269:5 | LL | / #[suggestion(message = "bar", code = "This is suggested code")] LL | | @@ -228,57 +286,71 @@ LL | | suggestion: (Span, Span, Applicability), | |___________________________________________^ error: type of field annotated with `#[suggestion(...)]` contains more than one Applicability - --> $DIR/session-derive-errors.rs:270:5 + --> $DIR/diagnostic-derive.rs:277:5 | LL | / #[suggestion(message = "bar", code = "This is suggested code")] LL | | LL | | suggestion: (Applicability, Applicability, Span), | |____________________________________________________^ -error: `#[label(...)]` is not a valid `SessionDiagnostic` field attribute - --> $DIR/session-derive-errors.rs:278:5 +error: `#[label(...)]` is not a valid attribute + --> $DIR/diagnostic-derive.rs:285:5 | LL | #[label("bar")] | ^^^^^^^^^^^^^^^ + | + = help: only `suggestion{,_short,_hidden,_verbose}` are valid field attributes error: `#[help]` must come after `#[error(..)]` or `#[warn(..)]` - --> $DIR/session-derive-errors.rs:399:1 + --> $DIR/diagnostic-derive.rs:406:1 | LL | #[help] | ^^^^^^^ error: `#[help = ...]` must come after `#[error(..)]` or `#[warn(..)]` - --> $DIR/session-derive-errors.rs:407:1 + --> $DIR/diagnostic-derive.rs:414:1 | LL | #[help = "bar"] | ^^^^^^^^^^^^^^^ error: `#[note]` must come after `#[error(..)]` or `#[warn(..)]` - --> $DIR/session-derive-errors.rs:415:1 + --> $DIR/diagnostic-derive.rs:422:1 | LL | #[note] | ^^^^^^^ error: `#[note = ...]` must come after `#[error(..)]` or `#[warn(..)]` - --> $DIR/session-derive-errors.rs:423:1 + --> $DIR/diagnostic-derive.rs:430:1 | LL | #[note = "bar"] | ^^^^^^^^^^^^^^^ +error: applicability cannot be set in both the field and attribute + --> $DIR/diagnostic-derive.rs:440:49 + | +LL | #[suggestion(message = "bar", code = "...", applicability = "maybe-incorrect")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: invalid applicability + --> $DIR/diagnostic-derive.rs:448:49 + | +LL | #[suggestion(message = "bar", code = "...", applicability = "batman")] + | ^^^^^^^^^^^^^^^^^^^^^^^^ + error: cannot find attribute `nonsense` in this scope - --> $DIR/session-derive-errors.rs:51:3 + --> $DIR/diagnostic-derive.rs:51:3 | LL | #[nonsense(code = "E0123", slug = "foo")] | ^^^^^^^^ error: cannot find attribute `nonsense` in this scope - --> $DIR/session-derive-errors.rs:132:7 + --> $DIR/diagnostic-derive.rs:139:7 | LL | #[nonsense] | ^^^^^^^^ error[E0599]: no method named `into_diagnostic_arg` found for struct `Hello` in the current scope - --> $DIR/session-derive-errors.rs:322:10 + --> $DIR/diagnostic-derive.rs:329:10 | LL | struct Hello {} | ------------ method `into_diagnostic_arg` not found for this @@ -288,6 +360,6 @@ LL | #[derive(SessionDiagnostic)] | = note: this error originates in the derive macro `SessionDiagnostic` (in Nightly builds, run with -Z macro-backtrace for more info) -error: aborting due to 37 previous errors +error: aborting due to 43 previous errors For more information about this error, try `rustc --explain E0599`. diff --git a/src/test/ui-fulldeps/session-diagnostic/subdiagnostic-derive.rs b/src/test/ui-fulldeps/session-diagnostic/subdiagnostic-derive.rs new file mode 100644 index 00000000000..bb406c35c0e --- /dev/null +++ b/src/test/ui-fulldeps/session-diagnostic/subdiagnostic-derive.rs @@ -0,0 +1,501 @@ +// check-fail +// Tests error conditions for specifying subdiagnostics using #[derive(SessionSubdiagnostic)] + +// The proc_macro2 crate handles spans differently when on beta/stable release rather than nightly, +// changing the output of this test. Since SessionSubdiagnostic is strictly internal to the compiler +// the test is just ignored on stable and beta: +// ignore-beta +// ignore-stable + +#![feature(rustc_private)] +#![crate_type = "lib"] + +extern crate rustc_errors; +extern crate rustc_session; +extern crate rustc_span; +extern crate rustc_macros; + +use rustc_errors::Applicability; +use rustc_span::Span; +use rustc_macros::SessionSubdiagnostic; + +#[derive(SessionSubdiagnostic)] +#[label(slug = "label-a")] +struct A { + #[primary_span] + span: Span, + var: String, +} + +#[derive(SessionSubdiagnostic)] +enum B { + #[label(slug = "label-b-a")] + A { + #[primary_span] + span: Span, + var: String, + }, + #[label(slug = "label-b-b")] + B { + #[primary_span] + span: Span, + var: String, + } +} + +#[derive(SessionSubdiagnostic)] +#[label(slug = "label-c")] +//~^ ERROR label without `#[primary_span]` field +struct C { + var: String, +} + +#[derive(SessionSubdiagnostic)] +#[label] +//~^ ERROR `#[label]` is not a valid attribute +struct D { + #[primary_span] + span: Span, + var: String, +} + +#[derive(SessionSubdiagnostic)] +#[foo] +//~^ ERROR `#[foo]` is not a valid attribute +//~^^ ERROR cannot find attribute `foo` in this scope +struct E { + #[primary_span] + span: Span, + var: String, +} + +#[derive(SessionSubdiagnostic)] +#[label = "..."] +//~^ ERROR `#[label = ...]` is not a valid attribute +struct F { + #[primary_span] + span: Span, + var: String, +} + +#[derive(SessionSubdiagnostic)] +#[label(bug = "...")] +//~^ ERROR `#[label(bug = ...)]` is not a valid attribute +struct G { + #[primary_span] + span: Span, + var: String, +} + +#[derive(SessionSubdiagnostic)] +#[label("...")] +//~^ ERROR `#[label("...")]` is not a valid attribute +struct H { + #[primary_span] + span: Span, + var: String, +} + +#[derive(SessionSubdiagnostic)] +#[label(slug = 4)] +//~^ ERROR `#[label(slug = ...)]` is not a valid attribute +struct J { + #[primary_span] + span: Span, + var: String, +} + +#[derive(SessionSubdiagnostic)] +#[label(slug("..."))] +//~^ ERROR `#[label(slug(...))]` is not a valid attribute +struct K { + #[primary_span] + span: Span, + var: String, +} + +#[derive(SessionSubdiagnostic)] +#[label(slug)] +//~^ ERROR `#[label(slug)]` is not a valid attribute +struct L { + #[primary_span] + span: Span, + var: String, +} + +#[derive(SessionSubdiagnostic)] +#[label()] +//~^ ERROR `slug` must be set in a `#[label(...)]` attribute +struct M { + #[primary_span] + span: Span, + var: String, +} + +#[derive(SessionSubdiagnostic)] +#[label(code = "...")] +//~^ ERROR `code` is not a valid nested attribute of a `label` attribute +struct N { + #[primary_span] + span: Span, + var: String, +} + +#[derive(SessionSubdiagnostic)] +#[foo] +//~^ ERROR cannot find attribute `foo` in this scope +//~^^ ERROR unsupported type attribute for subdiagnostic enum +enum O { + #[label(slug = "...")] + A { + #[primary_span] + span: Span, + var: String, + } +} + +#[derive(SessionSubdiagnostic)] +enum P { + #[bar] +//~^ ERROR `#[bar]` is not a valid attribute +//~^^ ERROR cannot find attribute `bar` in this scope + A { + #[primary_span] + span: Span, + var: String, + } +} + +#[derive(SessionSubdiagnostic)] +enum Q { + #[bar = "..."] +//~^ ERROR `#[bar = ...]` is not a valid attribute +//~^^ ERROR cannot find attribute `bar` in this scope + A { + #[primary_span] + span: Span, + var: String, + } +} + +#[derive(SessionSubdiagnostic)] +enum R { + #[bar = 4] +//~^ ERROR `#[bar = ...]` is not a valid attribute +//~^^ ERROR cannot find attribute `bar` in this scope + A { + #[primary_span] + span: Span, + var: String, + } +} + +#[derive(SessionSubdiagnostic)] +enum S { + #[bar("...")] +//~^ ERROR `#[bar("...")]` is not a valid attribute +//~^^ ERROR cannot find attribute `bar` in this scope + A { + #[primary_span] + span: Span, + var: String, + } +} + +#[derive(SessionSubdiagnostic)] +enum T { + #[label(code = "...")] +//~^ ERROR `code` is not a valid nested attribute of a `label` + A { + #[primary_span] + span: Span, + var: String, + } +} + +#[derive(SessionSubdiagnostic)] +enum U { + #[label(slug = "label-u")] + A { + #[primary_span] + span: Span, + var: String, + }, + B { +//~^ ERROR subdiagnostic kind not specified + #[primary_span] + span: Span, + var: String, + } +} + +#[derive(SessionSubdiagnostic)] +#[label(slug = "...")] +//~^ ERROR label without `#[primary_span]` field +struct V { + #[primary_span] + //~^ ERROR the `#[primary_span]` attribute can only be applied to fields of type `Span` + span: String, +} + +#[derive(SessionSubdiagnostic)] +#[label(slug = "...")] +struct W { + #[primary_span] + span: Span, + #[applicability] + //~^ ERROR `#[applicability]` is only valid on suggestions + applicability: Applicability, +} + +#[derive(SessionSubdiagnostic)] +#[label(slug = "...")] +struct X { + #[primary_span] + span: Span, + #[bar] + //~^ ERROR `#[bar]` is not a valid attribute + //~^^ ERROR cannot find attribute `bar` in this scope + bar: String, +} + +#[derive(SessionSubdiagnostic)] +#[label(slug = "...")] +struct Y { + #[primary_span] + span: Span, + #[bar = "..."] + //~^ ERROR `#[bar = ...]` is not a valid attribute + //~^^ ERROR cannot find attribute `bar` in this scope + bar: String, +} + +#[derive(SessionSubdiagnostic)] +#[label(slug = "...")] +struct Z { + #[primary_span] + span: Span, + #[bar("...")] + //~^ ERROR `#[bar(...)]` is not a valid attribute + //~^^ ERROR cannot find attribute `bar` in this scope + bar: String, +} + +#[derive(SessionSubdiagnostic)] +#[label(slug = "label-aa")] +struct AA { + #[primary_span] + span: Span, + #[skip_arg] + z: Z +} + +#[derive(SessionSubdiagnostic)] +union AB { +//~^ ERROR unexpected unsupported untagged union + span: u32, + b: u64 +} + +#[derive(SessionSubdiagnostic)] +#[label(slug = "label-ac-1")] +//~^ NOTE previously specified here +//~^^ NOTE previously specified here +#[label(slug = "label-ac-2")] +//~^ ERROR specified multiple times +//~^^ ERROR specified multiple times +struct AC { + #[primary_span] + span: Span, +} + +#[derive(SessionSubdiagnostic)] +#[label(slug = "label-ad-1", slug = "label-ad-2")] +//~^ ERROR specified multiple times +//~^^ NOTE previously specified here +struct AD { + #[primary_span] + span: Span, +} + +#[derive(SessionSubdiagnostic)] +#[label(slug = "label-ad-1")] +struct AE { + #[primary_span] +//~^ NOTE previously specified here + span_a: Span, + #[primary_span] +//~^ ERROR specified multiple times + span_b: Span, +} + +#[derive(SessionSubdiagnostic)] +struct AF { +//~^ ERROR subdiagnostic kind not specified + #[primary_span] + span: Span, +} + +#[derive(SessionSubdiagnostic)] +#[suggestion(slug = "suggestion-af", code = "...")] +struct AG { + #[primary_span] + span: Span, + #[applicability] + applicability: Applicability, + var: String, +} + +#[derive(SessionSubdiagnostic)] +enum AH { + #[suggestion(slug = "suggestion-ag-a", code = "...")] + A { + #[primary_span] + span: Span, + #[applicability] + applicability: Applicability, + var: String, + }, + #[suggestion(slug = "suggestion-ag-b", code = "...")] + B { + #[primary_span] + span: Span, + #[applicability] + applicability: Applicability, + var: String, + } +} + +#[derive(SessionSubdiagnostic)] +#[suggestion(slug = "...", code = "...", code = "...")] +//~^ ERROR specified multiple times +//~^^ NOTE previously specified here +struct AI { + #[primary_span] + span: Span, + #[applicability] + applicability: Applicability, +} + +#[derive(SessionSubdiagnostic)] +#[suggestion(slug = "...", code = "...")] +struct AJ { + #[primary_span] + span: Span, + #[applicability] +//~^ NOTE previously specified here + applicability_a: Applicability, + #[applicability] +//~^ ERROR specified multiple times + applicability_b: Applicability, +} + +#[derive(SessionSubdiagnostic)] +#[suggestion(slug = "...", code = "...")] +//~^ ERROR suggestion without `applicability` +struct AK { + #[primary_span] + span: Span, + #[applicability] +//~^ ERROR the `#[applicability]` attribute can only be applied to fields of type `Applicability` + applicability: Span, +} + +#[derive(SessionSubdiagnostic)] +#[suggestion(slug = "...", code = "...")] +//~^ ERROR suggestion without `applicability` +struct AL { + #[primary_span] + span: Span, +} + +#[derive(SessionSubdiagnostic)] +#[suggestion(slug = "...")] +//~^ ERROR suggestion without `code = "..."` +struct AM { + #[primary_span] + span: Span, + #[applicability] + applicability: Applicability, +} + +#[derive(SessionSubdiagnostic)] +#[suggestion(slug = "...", code ="...", applicability = "foo")] +//~^ ERROR invalid applicability +struct AN { + #[primary_span] + span: Span, +} + +#[derive(SessionSubdiagnostic)] +#[help(slug = "label-am")] +struct AO { + var: String +} + +#[derive(SessionSubdiagnostic)] +#[note(slug = "label-an")] +struct AP; + +#[derive(SessionSubdiagnostic)] +#[suggestion(slug = "...", code = "...")] +//~^ ERROR suggestion without `applicability` +//~^^ ERROR suggestion without `#[primary_span]` field +struct AQ { + var: String, +} + +#[derive(SessionSubdiagnostic)] +#[suggestion(slug = "...", code ="...", applicability = "machine-applicable")] +struct AR { + #[primary_span] + span: Span, +} + +#[derive(SessionSubdiagnostic)] +#[label] +//~^ ERROR unsupported type attribute for subdiagnostic enum +enum AS { + #[label(slug = "...")] + A { + #[primary_span] + span: Span, + var: String, + } +} + +#[derive(SessionSubdiagnostic)] +#[suggestion(slug = "...", code ="{var}", applicability = "machine-applicable")] +struct AT { + #[primary_span] + span: Span, + var: String, +} + +#[derive(SessionSubdiagnostic)] +#[suggestion(slug = "...", code ="{var}", applicability = "machine-applicable")] +//~^ ERROR `var` doesn't refer to a field on this type +struct AU { + #[primary_span] + span: Span, +} + +#[derive(SessionSubdiagnostic)] +enum AV { + #[suggestion(slug = "...", code ="{var}", applicability = "machine-applicable")] + A { + #[primary_span] + span: Span, + var: String, + } +} + +#[derive(SessionSubdiagnostic)] +enum AW { + #[suggestion(slug = "...", code ="{var}", applicability = "machine-applicable")] +//~^ ERROR `var` doesn't refer to a field on this type + A { + #[primary_span] + span: Span, + } +} diff --git a/src/test/ui-fulldeps/session-diagnostic/subdiagnostic-derive.stderr b/src/test/ui-fulldeps/session-diagnostic/subdiagnostic-derive.stderr new file mode 100644 index 00000000000..4984cc4b318 --- /dev/null +++ b/src/test/ui-fulldeps/session-diagnostic/subdiagnostic-derive.stderr @@ -0,0 +1,389 @@ +error: label without `#[primary_span]` field + --> $DIR/subdiagnostic-derive.rs:47:1 + | +LL | / #[label(slug = "label-c")] +LL | | +LL | | struct C { +LL | | var: String, +LL | | } + | |_^ + +error: `#[label]` is not a valid attribute + --> $DIR/subdiagnostic-derive.rs:54:1 + | +LL | #[label] + | ^^^^^^^^ + +error: `#[foo]` is not a valid attribute + --> $DIR/subdiagnostic-derive.rs:63:1 + | +LL | #[foo] + | ^^^^^^ + +error: `#[label = ...]` is not a valid attribute + --> $DIR/subdiagnostic-derive.rs:73:1 + | +LL | #[label = "..."] + | ^^^^^^^^^^^^^^^^ + +error: `#[label(bug = ...)]` is not a valid attribute + --> $DIR/subdiagnostic-derive.rs:82:9 + | +LL | #[label(bug = "...")] + | ^^^^^^^^^^^ + | + = help: only `code`, `slug` and `applicability` are valid nested attributes + +error: `#[label("...")]` is not a valid attribute + --> $DIR/subdiagnostic-derive.rs:91:9 + | +LL | #[label("...")] + | ^^^^^ + +error: `#[label(slug = ...)]` is not a valid attribute + --> $DIR/subdiagnostic-derive.rs:100:9 + | +LL | #[label(slug = 4)] + | ^^^^^^^^ + +error: `#[label(slug(...))]` is not a valid attribute + --> $DIR/subdiagnostic-derive.rs:109:9 + | +LL | #[label(slug("..."))] + | ^^^^^^^^^^^ + +error: `#[label(slug)]` is not a valid attribute + --> $DIR/subdiagnostic-derive.rs:118:9 + | +LL | #[label(slug)] + | ^^^^ + +error: `slug` must be set in a `#[label(...)]` attribute + --> $DIR/subdiagnostic-derive.rs:127:1 + | +LL | #[label()] + | ^^^^^^^^^^ + +error: `code` is not a valid nested attribute of a `label` attribute + --> $DIR/subdiagnostic-derive.rs:136:1 + | +LL | #[label(code = "...")] + | ^^^^^^^^^^^^^^^^^^^^^^ + +error: unsupported type attribute for subdiagnostic enum + --> $DIR/subdiagnostic-derive.rs:145:1 + | +LL | #[foo] + | ^^^^^^ + +error: `#[bar]` is not a valid attribute + --> $DIR/subdiagnostic-derive.rs:159:5 + | +LL | #[bar] + | ^^^^^^ + +error: `#[bar = ...]` is not a valid attribute + --> $DIR/subdiagnostic-derive.rs:171:5 + | +LL | #[bar = "..."] + | ^^^^^^^^^^^^^^ + +error: `#[bar = ...]` is not a valid attribute + --> $DIR/subdiagnostic-derive.rs:183:5 + | +LL | #[bar = 4] + | ^^^^^^^^^^ + +error: `#[bar("...")]` is not a valid attribute + --> $DIR/subdiagnostic-derive.rs:195:11 + | +LL | #[bar("...")] + | ^^^^^ + +error: `code` is not a valid nested attribute of a `label` attribute + --> $DIR/subdiagnostic-derive.rs:207:5 + | +LL | #[label(code = "...")] + | ^^^^^^^^^^^^^^^^^^^^^^ + +error: subdiagnostic kind not specified + --> $DIR/subdiagnostic-derive.rs:224:5 + | +LL | B { + | ^ + +error: the `#[primary_span]` attribute can only be applied to fields of type `Span` + --> $DIR/subdiagnostic-derive.rs:236:5 + | +LL | #[primary_span] + | ^^^^^^^^^^^^^^^ + +error: label without `#[primary_span]` field + --> $DIR/subdiagnostic-derive.rs:233:1 + | +LL | / #[label(slug = "...")] +LL | | +LL | | struct V { +LL | | #[primary_span] +LL | | +LL | | span: String, +LL | | } + | |_^ + +error: `#[applicability]` is only valid on suggestions + --> $DIR/subdiagnostic-derive.rs:246:5 + | +LL | #[applicability] + | ^^^^^^^^^^^^^^^^ + +error: `#[bar]` is not a valid attribute + --> $DIR/subdiagnostic-derive.rs:256:5 + | +LL | #[bar] + | ^^^^^^ + | + = help: only `primary_span`, `applicability` and `skip_arg` are valid field attributes + +error: `#[bar = ...]` is not a valid attribute + --> $DIR/subdiagnostic-derive.rs:267:5 + | +LL | #[bar = "..."] + | ^^^^^^^^^^^^^^ + +error: `#[bar(...)]` is not a valid attribute + --> $DIR/subdiagnostic-derive.rs:278:5 + | +LL | #[bar("...")] + | ^^^^^^^^^^^^^ + +error: unexpected unsupported untagged union + --> $DIR/subdiagnostic-derive.rs:294:1 + | +LL | / union AB { +LL | | +LL | | span: u32, +LL | | b: u64 +LL | | } + | |_^ + +error: specified multiple times + --> $DIR/subdiagnostic-derive.rs:304:9 + | +LL | #[label(slug = "label-ac-2")] + | ^^^^^^^^^^^^^^^^^^^ + | +note: previously specified here + --> $DIR/subdiagnostic-derive.rs:301:9 + | +LL | #[label(slug = "label-ac-1")] + | ^^^^^^^^^^^^^^^^^^^ + +error: specified multiple times + --> $DIR/subdiagnostic-derive.rs:304:1 + | +LL | #[label(slug = "label-ac-2")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: previously specified here + --> $DIR/subdiagnostic-derive.rs:301:1 + | +LL | #[label(slug = "label-ac-1")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: specified multiple times + --> $DIR/subdiagnostic-derive.rs:313:30 + | +LL | #[label(slug = "label-ad-1", slug = "label-ad-2")] + | ^^^^^^^^^^^^^^^^^^^ + | +note: previously specified here + --> $DIR/subdiagnostic-derive.rs:313:9 + | +LL | #[label(slug = "label-ad-1", slug = "label-ad-2")] + | ^^^^^^^^^^^^^^^^^^^ + +error: specified multiple times + --> $DIR/subdiagnostic-derive.rs:327:5 + | +LL | #[primary_span] + | ^^^^^^^^^^^^^^^ + | +note: previously specified here + --> $DIR/subdiagnostic-derive.rs:324:5 + | +LL | #[primary_span] + | ^^^^^^^^^^^^^^^ + +error: subdiagnostic kind not specified + --> $DIR/subdiagnostic-derive.rs:333:8 + | +LL | struct AF { + | ^^ + +error: specified multiple times + --> $DIR/subdiagnostic-derive.rs:370:42 + | +LL | #[suggestion(slug = "...", code = "...", code = "...")] + | ^^^^^^^^^^^^ + | +note: previously specified here + --> $DIR/subdiagnostic-derive.rs:370:28 + | +LL | #[suggestion(slug = "...", code = "...", code = "...")] + | ^^^^^^^^^^^^ + +error: specified multiple times + --> $DIR/subdiagnostic-derive.rs:388:5 + | +LL | #[applicability] + | ^^^^^^^^^^^^^^^^ + | +note: previously specified here + --> $DIR/subdiagnostic-derive.rs:385:5 + | +LL | #[applicability] + | ^^^^^^^^^^^^^^^^ + +error: the `#[applicability]` attribute can only be applied to fields of type `Applicability` + --> $DIR/subdiagnostic-derive.rs:399:5 + | +LL | #[applicability] + | ^^^^^^^^^^^^^^^^ + +error: suggestion without `applicability` + --> $DIR/subdiagnostic-derive.rs:394:1 + | +LL | / #[suggestion(slug = "...", code = "...")] +LL | | +LL | | struct AK { +LL | | #[primary_span] +... | +LL | | applicability: Span, +LL | | } + | |_^ + +error: suggestion without `applicability` + --> $DIR/subdiagnostic-derive.rs:405:1 + | +LL | / #[suggestion(slug = "...", code = "...")] +LL | | +LL | | struct AL { +LL | | #[primary_span] +LL | | span: Span, +LL | | } + | |_^ + +error: suggestion without `code = "..."` + --> $DIR/subdiagnostic-derive.rs:413:1 + | +LL | / #[suggestion(slug = "...")] +LL | | +LL | | struct AM { +LL | | #[primary_span] +... | +LL | | applicability: Applicability, +LL | | } + | |_^ + +error: invalid applicability + --> $DIR/subdiagnostic-derive.rs:423:41 + | +LL | #[suggestion(slug = "...", code ="...", applicability = "foo")] + | ^^^^^^^^^^^^^^^^^^^^^ + +error: suggestion without `applicability` + --> $DIR/subdiagnostic-derive.rs:441:1 + | +LL | / #[suggestion(slug = "...", code = "...")] +LL | | +LL | | +LL | | struct AQ { +LL | | var: String, +LL | | } + | |_^ + +error: suggestion without `#[primary_span]` field + --> $DIR/subdiagnostic-derive.rs:441:1 + | +LL | / #[suggestion(slug = "...", code = "...")] +LL | | +LL | | +LL | | struct AQ { +LL | | var: String, +LL | | } + | |_^ + +error: unsupported type attribute for subdiagnostic enum + --> $DIR/subdiagnostic-derive.rs:456:1 + | +LL | #[label] + | ^^^^^^^^ + +error: `var` doesn't refer to a field on this type + --> $DIR/subdiagnostic-derive.rs:476:34 + | +LL | #[suggestion(slug = "...", code ="{var}", applicability = "machine-applicable")] + | ^^^^^^^ + +error: `var` doesn't refer to a field on this type + --> $DIR/subdiagnostic-derive.rs:495:38 + | +LL | #[suggestion(slug = "...", code ="{var}", applicability = "machine-applicable")] + | ^^^^^^^ + +error: cannot find attribute `foo` in this scope + --> $DIR/subdiagnostic-derive.rs:63:3 + | +LL | #[foo] + | ^^^ + +error: cannot find attribute `foo` in this scope + --> $DIR/subdiagnostic-derive.rs:145:3 + | +LL | #[foo] + | ^^^ + +error: cannot find attribute `bar` in this scope + --> $DIR/subdiagnostic-derive.rs:159:7 + | +LL | #[bar] + | ^^^ + +error: cannot find attribute `bar` in this scope + --> $DIR/subdiagnostic-derive.rs:171:7 + | +LL | #[bar = "..."] + | ^^^ + +error: cannot find attribute `bar` in this scope + --> $DIR/subdiagnostic-derive.rs:183:7 + | +LL | #[bar = 4] + | ^^^ + +error: cannot find attribute `bar` in this scope + --> $DIR/subdiagnostic-derive.rs:195:7 + | +LL | #[bar("...")] + | ^^^ + +error: cannot find attribute `bar` in this scope + --> $DIR/subdiagnostic-derive.rs:256:7 + | +LL | #[bar] + | ^^^ + +error: cannot find attribute `bar` in this scope + --> $DIR/subdiagnostic-derive.rs:267:7 + | +LL | #[bar = "..."] + | ^^^ + +error: cannot find attribute `bar` in this scope + --> $DIR/subdiagnostic-derive.rs:278:7 + | +LL | #[bar("...")] + | ^^^ + +error: aborting due to 51 previous errors + diff --git a/src/test/ui/array-slice-vec/repeat_empty_ok.stderr b/src/test/ui/array-slice-vec/repeat_empty_ok.stderr index eba1a8e2278..724bdcd920a 100644 --- a/src/test/ui/array-slice-vec/repeat_empty_ok.stderr +++ b/src/test/ui/array-slice-vec/repeat_empty_ok.stderr @@ -1,22 +1,22 @@ error[E0277]: the trait bound `Header<'_>: Copy` is not satisfied - --> $DIR/repeat_empty_ok.rs:8:19 + --> $DIR/repeat_empty_ok.rs:8:20 | LL | let headers = [Header{value: &[]}; 128]; - | ^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `Header<'_>` + | ^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `Header<'_>` | - = note: the `Copy` trait is required because the repeated element will be copied + = note: the `Copy` trait is required because this value will be copied for each element of the array help: consider annotating `Header<'_>` with `#[derive(Copy)]` | LL | #[derive(Copy)] | error[E0277]: the trait bound `Header<'_>: Copy` is not satisfied - --> $DIR/repeat_empty_ok.rs:13:19 + --> $DIR/repeat_empty_ok.rs:13:20 | LL | let headers = [Header{value: &[0]}; 128]; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `Header<'_>` + | ^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `Header<'_>` | - = note: the `Copy` trait is required because the repeated element will be copied + = note: the `Copy` trait is required because this value will be copied for each element of the array help: consider annotating `Header<'_>` with `#[derive(Copy)]` | LL | #[derive(Copy)] diff --git a/src/test/ui/asm/x86_64/bad-reg.rs b/src/test/ui/asm/x86_64/bad-reg.rs index 4c4ce8b5e9e..272372ebedc 100644 --- a/src/test/ui/asm/x86_64/bad-reg.rs +++ b/src/test/ui/asm/x86_64/bad-reg.rs @@ -29,13 +29,13 @@ fn main() { //~^ ERROR invalid register `rsp`: the stack pointer cannot be used as an operand asm!("", in("ip") foo); //~^ ERROR invalid register `ip`: the instruction pointer cannot be used as an operand - asm!("", in("k0") foo); - //~^ ERROR invalid register `k0`: the k0 AVX mask register cannot be used as an operand asm!("", in("st(2)") foo); //~^ ERROR register class `x87_reg` can only be used as a clobber, not as an input or output asm!("", in("mm0") foo); //~^ ERROR register class `mmx_reg` can only be used as a clobber, not as an input or output + asm!("", in("k0") foo); + //~^ ERROR register class `kreg0` can only be used as a clobber, not as an input or output asm!("", out("st(2)") _); asm!("", out("mm0") _); asm!("{}", in(x87_reg) foo); diff --git a/src/test/ui/asm/x86_64/bad-reg.stderr b/src/test/ui/asm/x86_64/bad-reg.stderr index f8b024e1acd..84b8b5ec285 100644 --- a/src/test/ui/asm/x86_64/bad-reg.stderr +++ b/src/test/ui/asm/x86_64/bad-reg.stderr @@ -64,24 +64,24 @@ error: invalid register `ip`: the instruction pointer cannot be used as an opera LL | asm!("", in("ip") foo); | ^^^^^^^^^^^^ -error: invalid register `k0`: the k0 AVX mask register cannot be used as an operand for inline asm - --> $DIR/bad-reg.rs:32:18 - | -LL | asm!("", in("k0") foo); - | ^^^^^^^^^^^^ - error: register class `x87_reg` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:35:18 + --> $DIR/bad-reg.rs:33:18 | LL | asm!("", in("st(2)") foo); | ^^^^^^^^^^^^^^^ error: register class `mmx_reg` can only be used as a clobber, not as an input or output - --> $DIR/bad-reg.rs:37:18 + --> $DIR/bad-reg.rs:35:18 | LL | asm!("", in("mm0") foo); | ^^^^^^^^^^^^^ +error: register class `kreg0` can only be used as a clobber, not as an input or output + --> $DIR/bad-reg.rs:37:18 + | +LL | asm!("", in("k0") foo); + | ^^^^^^^^^^^^ + error: register class `x87_reg` can only be used as a clobber, not as an input or output --> $DIR/bad-reg.rs:41:20 | diff --git a/src/test/ui/associated-types/impl-trait-return-missing-constraint.rs b/src/test/ui/associated-types/impl-trait-return-missing-constraint.rs index ef0443034ec..1de1ddbe3a4 100644 --- a/src/test/ui/associated-types/impl-trait-return-missing-constraint.rs +++ b/src/test/ui/associated-types/impl-trait-return-missing-constraint.rs @@ -24,7 +24,6 @@ fn bar() -> impl Bar { fn baz() -> impl Bar<Item = i32> { //~^ ERROR type mismatch resolving `<impl Bar as Foo>::Item == i32` - //~| ERROR type mismatch resolving `<impl Bar as Foo>::Item == i32` bar() } diff --git a/src/test/ui/associated-types/impl-trait-return-missing-constraint.stderr b/src/test/ui/associated-types/impl-trait-return-missing-constraint.stderr index b7c49570ca4..bd8c8a4414c 100644 --- a/src/test/ui/associated-types/impl-trait-return-missing-constraint.stderr +++ b/src/test/ui/associated-types/impl-trait-return-missing-constraint.stderr @@ -16,29 +16,6 @@ help: consider constraining the associated type `<impl Bar as Foo>::Item` to `i3 LL | fn bar() -> impl Bar<Item = i32> { | ++++++++++++ -error[E0271]: type mismatch resolving `<impl Bar as Foo>::Item == i32` - --> $DIR/impl-trait-return-missing-constraint.rs:25:34 - | -LL | fn bar() -> impl Bar { - | -------- the expected opaque type -... -LL | fn baz() -> impl Bar<Item = i32> { - | __________________________________^ -LL | | -LL | | -LL | | bar() -LL | | } - | |_^ expected associated type, found `i32` - | - = note: expected associated type `<impl Bar as Foo>::Item` - found type `i32` - = help: consider constraining the associated type `<impl Bar as Foo>::Item` to `i32` or calling a method that returns `<impl Bar as Foo>::Item` - = note: for more information, visit https://doc.rust-lang.org/book/ch19-03-advanced-traits.html -help: consider constraining the associated type `<impl Bar as Foo>::Item` to `i32` - | -LL | fn bar() -> impl Bar<Item = i32> { - | ++++++++++++ - -error: aborting due to 2 previous errors +error: aborting due to previous error For more information about this error, try `rustc --explain E0271`. diff --git a/src/test/ui/issues/issue-25339.rs b/src/test/ui/associated-types/issue-25339.rs index 6f8ec700951..6f8ec700951 100644 --- a/src/test/ui/issues/issue-25339.rs +++ b/src/test/ui/associated-types/issue-25339.rs diff --git a/src/test/ui/issues/issue-55846.rs b/src/test/ui/associated-types/issue-55846.rs index bd766752360..bd766752360 100644 --- a/src/test/ui/issues/issue-55846.rs +++ b/src/test/ui/associated-types/issue-55846.rs diff --git a/src/test/ui/async-await/async-unsafe-fn-call-in-safe.mir.stderr b/src/test/ui/async-await/async-unsafe-fn-call-in-safe.mir.stderr index d22413beecb..2114fb59ba3 100644 --- a/src/test/ui/async-await/async-unsafe-fn-call-in-safe.mir.stderr +++ b/src/test/ui/async-await/async-unsafe-fn-call-in-safe.mir.stderr @@ -7,7 +7,7 @@ LL | S::f(); = note: consult the function's documentation for information on how to avoid undefined behavior error[E0133]: call to unsafe function is unsafe and requires unsafe function or block - --> $DIR/async-unsafe-fn-call-in-safe.rs:15:5 + --> $DIR/async-unsafe-fn-call-in-safe.rs:17:5 | LL | f(); | ^^^ call to unsafe function @@ -15,7 +15,7 @@ LL | f(); = note: consult the function's documentation for information on how to avoid undefined behavior error[E0133]: call to unsafe function is unsafe and requires unsafe function or block - --> $DIR/async-unsafe-fn-call-in-safe.rs:19:5 + --> $DIR/async-unsafe-fn-call-in-safe.rs:23:5 | LL | S::f(); | ^^^^^^ call to unsafe function @@ -23,7 +23,7 @@ LL | S::f(); = note: consult the function's documentation for information on how to avoid undefined behavior error[E0133]: call to unsafe function is unsafe and requires unsafe function or block - --> $DIR/async-unsafe-fn-call-in-safe.rs:20:5 + --> $DIR/async-unsafe-fn-call-in-safe.rs:24:5 | LL | f(); | ^^^ call to unsafe function diff --git a/src/test/ui/async-await/async-unsafe-fn-call-in-safe.rs b/src/test/ui/async-await/async-unsafe-fn-call-in-safe.rs index fc37822cb7b..c941dc27aa3 100644 --- a/src/test/ui/async-await/async-unsafe-fn-call-in-safe.rs +++ b/src/test/ui/async-await/async-unsafe-fn-call-in-safe.rs @@ -11,8 +11,12 @@ impl S { async unsafe fn f() {} async fn g() { - S::f(); //~ ERROR call to unsafe function is unsafe - f(); //~ ERROR call to unsafe function is unsafe + S::f(); + //[mir]~^ ERROR call to unsafe function is unsafe + //[thir]~^^ ERROR call to unsafe function `S::f` is unsafe + f(); + //[mir]~^ ERROR call to unsafe function is unsafe + //[thir]~^^ ERROR call to unsafe function `f` is unsafe } fn main() { diff --git a/src/test/ui/async-await/async-unsafe-fn-call-in-safe.thir.stderr b/src/test/ui/async-await/async-unsafe-fn-call-in-safe.thir.stderr index 21ba45d7f1e..68d97d3fd7d 100644 --- a/src/test/ui/async-await/async-unsafe-fn-call-in-safe.thir.stderr +++ b/src/test/ui/async-await/async-unsafe-fn-call-in-safe.thir.stderr @@ -1,4 +1,4 @@ -error[E0133]: call to unsafe function is unsafe and requires unsafe function or block +error[E0133]: call to unsafe function `S::f` is unsafe and requires unsafe function or block --> $DIR/async-unsafe-fn-call-in-safe.rs:14:5 | LL | S::f(); @@ -6,8 +6,8 @@ LL | S::f(); | = note: consult the function's documentation for information on how to avoid undefined behavior -error[E0133]: call to unsafe function is unsafe and requires unsafe function or block - --> $DIR/async-unsafe-fn-call-in-safe.rs:15:5 +error[E0133]: call to unsafe function `f` is unsafe and requires unsafe function or block + --> $DIR/async-unsafe-fn-call-in-safe.rs:17:5 | LL | f(); | ^^^ call to unsafe function diff --git a/src/test/ui/async-await/issue-86507.stderr b/src/test/ui/async-await/issue-86507.stderr index ad0a3592241..5bbc20359c6 100644 --- a/src/test/ui/async-await/issue-86507.stderr +++ b/src/test/ui/async-await/issue-86507.stderr @@ -14,10 +14,10 @@ note: captured value is not `Send` because `&` references cannot be sent unless LL | let x = x; | ^ has type `&T` which is not `Send`, because `T` is not `Sync` = note: required for the cast to the object type `dyn Future<Output = ()> + Send` -help: consider further restricting type parameter `T` +help: consider further restricting this bound | -LL | where 'me:'async_trait, T: std::marker::Sync { - | ++++++++++++++++++++++ +LL | fn bar<'me, 'async_trait, T: Send + std::marker::Sync>(x: &'me T) + | +++++++++++++++++++ error: aborting due to previous error diff --git a/src/test/ui/issues/issue-3820.rs b/src/test/ui/binop/issue-3820.rs index b987a90b28b..b987a90b28b 100644 --- a/src/test/ui/issues/issue-3820.rs +++ b/src/test/ui/binop/issue-3820.rs diff --git a/src/test/ui/issues/issue-3820.stderr b/src/test/ui/binop/issue-3820.stderr index d5c24e1bb6c..d5c24e1bb6c 100644 --- a/src/test/ui/issues/issue-3820.stderr +++ b/src/test/ui/binop/issue-3820.stderr diff --git a/src/test/ui/binop/issue-93927.rs b/src/test/ui/binop/issue-93927.rs new file mode 100644 index 00000000000..de27c9785e6 --- /dev/null +++ b/src/test/ui/binop/issue-93927.rs @@ -0,0 +1,20 @@ +// Regression test for #93927: suggested trait bound for T should be Eq, not PartialEq +struct MyType<T>(T); + +impl<T> PartialEq for MyType<T> +where + T: Eq, +{ + fn eq(&self, other: &Self) -> bool { + true + } +} + +fn cond<T: PartialEq>(val: MyType<T>) -> bool { + val == val + //~^ ERROR binary operation `==` cannot be applied to type `MyType<T>` +} + +fn main() { + cond(MyType(0)); +} diff --git a/src/test/ui/binop/issue-93927.stderr b/src/test/ui/binop/issue-93927.stderr new file mode 100644 index 00000000000..75558b502f9 --- /dev/null +++ b/src/test/ui/binop/issue-93927.stderr @@ -0,0 +1,16 @@ +error[E0369]: binary operation `==` cannot be applied to type `MyType<T>` + --> $DIR/issue-93927.rs:14:9 + | +LL | val == val + | --- ^^ --- MyType<T> + | | + | MyType<T> + | +help: consider further restricting this bound + | +LL | fn cond<T: PartialEq + std::cmp::Eq>(val: MyType<T>) -> bool { + | ++++++++++++++ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0369`. diff --git a/src/test/ui/builtin-superkinds/builtin-superkinds-self-type.stderr b/src/test/ui/builtin-superkinds/builtin-superkinds-self-type.stderr index 2dac4a22ae7..b1e59e9d5de 100644 --- a/src/test/ui/builtin-superkinds/builtin-superkinds-self-type.stderr +++ b/src/test/ui/builtin-superkinds/builtin-superkinds-self-type.stderr @@ -2,9 +2,12 @@ error[E0310]: the parameter type `T` may not live long enough --> $DIR/builtin-superkinds-self-type.rs:10:16 | LL | impl <T: Sync> Foo for T { } - | -- ^^^ ...so that the type `T` will meet its required lifetime bounds - | | - | help: consider adding an explicit lifetime bound...: `T: 'static +` + | ^^^ ...so that the type `T` will meet its required lifetime bounds + | +help: consider adding an explicit lifetime bound... + | +LL | impl <T: Sync + 'static> Foo for T { } + | +++++++++ error: aborting due to previous error diff --git a/src/test/ui/closures/coerce-unsafe-closure-to-unsafe-fn-ptr.thir.stderr b/src/test/ui/closures/coerce-unsafe-closure-to-unsafe-fn-ptr.thir.stderr index a60100ddaea..8c516e8900c 100644 --- a/src/test/ui/closures/coerce-unsafe-closure-to-unsafe-fn-ptr.thir.stderr +++ b/src/test/ui/closures/coerce-unsafe-closure-to-unsafe-fn-ptr.thir.stderr @@ -1,4 +1,4 @@ -error[E0133]: call to unsafe function is unsafe and requires unsafe function or block +error[E0133]: call to unsafe function `Pin::<P>::new_unchecked` is unsafe and requires unsafe function or block --> $DIR/coerce-unsafe-closure-to-unsafe-fn-ptr.rs:5:31 | LL | let _: unsafe fn() = || { ::std::pin::Pin::new_unchecked(&0_u8); }; diff --git a/src/test/ui/coercion/coerce-issue-49593-box-never-windows.nofallback.stderr b/src/test/ui/coercion/coerce-issue-49593-box-never-windows.nofallback.stderr new file mode 100644 index 00000000000..ab9cc707aa0 --- /dev/null +++ b/src/test/ui/coercion/coerce-issue-49593-box-never-windows.nofallback.stderr @@ -0,0 +1,39 @@ +error[E0277]: the trait bound `(): std::error::Error` is not satisfied + --> $DIR/coerce-issue-49593-box-never-windows.rs:18:53 + | +LL | /* *mut $0 is coerced to Box<dyn Error> here */ Box::<_ /* ! */>::new(x) + | ^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::error::Error` is not implemented for `()` + | + = help: the following other types implement trait `std::error::Error`: + ! + &'a T + AccessError + AddrParseError + Arc<T> + BorrowError + BorrowMutError + Box<T> + and 45 others + = note: required for the cast to the object type `dyn std::error::Error` + +error[E0277]: the trait bound `(): std::error::Error` is not satisfied + --> $DIR/coerce-issue-49593-box-never-windows.rs:23:49 + | +LL | /* *mut $0 is coerced to *mut Error here */ raw_ptr_box::<_ /* ! */>(x) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::error::Error` is not implemented for `()` + | + = help: the following other types implement trait `std::error::Error`: + ! + &'a T + AccessError + AddrParseError + Arc<T> + BorrowError + BorrowMutError + Box<T> + and 45 others + = note: required for the cast to the object type `(dyn std::error::Error + 'static)` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/coercion/coerce-issue-49593-box-never-windows.rs b/src/test/ui/coercion/coerce-issue-49593-box-never-windows.rs new file mode 100644 index 00000000000..95d3935caa9 --- /dev/null +++ b/src/test/ui/coercion/coerce-issue-49593-box-never-windows.rs @@ -0,0 +1,58 @@ +// revisions: nofallback fallback +// only-windows - the number of `Error` impls is platform-dependent +//[fallback] check-pass +//[nofallback] check-fail + +#![feature(never_type)] +#![cfg_attr(fallback, feature(never_type_fallback))] +#![allow(unreachable_code)] + +use std::error::Error; +use std::mem; + +fn raw_ptr_box<T>(t: T) -> *mut T { + panic!() +} + +fn foo(x: !) -> Box<dyn Error> { + /* *mut $0 is coerced to Box<dyn Error> here */ Box::<_ /* ! */>::new(x) + //[nofallback]~^ ERROR trait bound `(): std::error::Error` is not satisfied +} + +fn foo_raw_ptr(x: !) -> *mut dyn Error { + /* *mut $0 is coerced to *mut Error here */ raw_ptr_box::<_ /* ! */>(x) + //[nofallback]~^ ERROR trait bound `(): std::error::Error` is not satisfied +} + +fn no_coercion(d: *mut dyn Error) -> *mut dyn Error { + /* an unsize coercion won't compile here, and it is indeed not used + because there is nothing requiring the _ to be Sized */ + d as *mut _ +} + +trait Xyz {} +struct S; +struct T; +impl Xyz for S {} +impl Xyz for T {} + +fn foo_no_never() { + let mut x /* : Option<S> */ = None; + let mut first_iter = false; + loop { + if !first_iter { + let y: Box<dyn Xyz> + = /* Box<$0> is coerced to Box<Xyz> here */ Box::new(x.unwrap()); + } + + x = Some(S); + first_iter = true; + } + + let mut y : Option<S> = None; + // assert types are equal + mem::swap(&mut x, &mut y); +} + +fn main() { +} diff --git a/src/test/ui/coercion/coerce-issue-49593-box-never.nofallback.stderr b/src/test/ui/coercion/coerce-issue-49593-box-never.nofallback.stderr index 1b1ce67cb0c..1daa91f025a 100644 --- a/src/test/ui/coercion/coerce-issue-49593-box-never.nofallback.stderr +++ b/src/test/ui/coercion/coerce-issue-49593-box-never.nofallback.stderr @@ -1,5 +1,5 @@ error[E0277]: the trait bound `(): std::error::Error` is not satisfied - --> $DIR/coerce-issue-49593-box-never.rs:17:53 + --> $DIR/coerce-issue-49593-box-never.rs:18:53 | LL | /* *mut $0 is coerced to Box<dyn Error> here */ Box::<_ /* ! */>::new(x) | ^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::error::Error` is not implemented for `()` @@ -17,7 +17,7 @@ LL | /* *mut $0 is coerced to Box<dyn Error> here */ Box::<_ /* ! */>::new(x = note: required for the cast to the object type `dyn std::error::Error` error[E0277]: the trait bound `(): std::error::Error` is not satisfied - --> $DIR/coerce-issue-49593-box-never.rs:22:49 + --> $DIR/coerce-issue-49593-box-never.rs:23:49 | LL | /* *mut $0 is coerced to *mut Error here */ raw_ptr_box::<_ /* ! */>(x) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::error::Error` is not implemented for `()` diff --git a/src/test/ui/coercion/coerce-issue-49593-box-never.rs b/src/test/ui/coercion/coerce-issue-49593-box-never.rs index 7a4324bd5ad..16efb65acb2 100644 --- a/src/test/ui/coercion/coerce-issue-49593-box-never.rs +++ b/src/test/ui/coercion/coerce-issue-49593-box-never.rs @@ -1,4 +1,5 @@ // revisions: nofallback fallback +// ignore-windows - the number of `Error` impls is platform-dependent //[fallback] check-pass //[nofallback] check-fail diff --git a/src/test/ui/coherence/coherence-cow.re_a.stderr b/src/test/ui/coherence/coherence-cow.re_a.stderr index 0cf2a406da4..fe4b5b41078 100644 --- a/src/test/ui/coherence/coherence-cow.re_a.stderr +++ b/src/test/ui/coherence/coherence-cow.re_a.stderr @@ -1,4 +1,4 @@ -error[E0117]: only traits defined in the current crate can be implemented for arbitrary types +error[E0117]: only traits defined in the current crate can be implemented for types defined outside of the crate --> $DIR/coherence-cow.rs:18:1 | LL | impl<T> Remote for Pair<T,Cover<T>> { } diff --git a/src/test/ui/coherence/coherence-cow.re_b.stderr b/src/test/ui/coherence/coherence-cow.re_b.stderr index b523db4da23..da4ede3251e 100644 --- a/src/test/ui/coherence/coherence-cow.re_b.stderr +++ b/src/test/ui/coherence/coherence-cow.re_b.stderr @@ -1,4 +1,4 @@ -error[E0117]: only traits defined in the current crate can be implemented for arbitrary types +error[E0117]: only traits defined in the current crate can be implemented for types defined outside of the crate --> $DIR/coherence-cow.rs:22:1 | LL | impl<T> Remote for Pair<Cover<T>,T> { } diff --git a/src/test/ui/coherence/coherence-cow.re_c.stderr b/src/test/ui/coherence/coherence-cow.re_c.stderr index bd635fc2e8c..d1a20c0ca10 100644 --- a/src/test/ui/coherence/coherence-cow.re_c.stderr +++ b/src/test/ui/coherence/coherence-cow.re_c.stderr @@ -1,4 +1,4 @@ -error[E0117]: only traits defined in the current crate can be implemented for arbitrary types +error[E0117]: only traits defined in the current crate can be implemented for types defined outside of the crate --> $DIR/coherence-cow.rs:26:1 | LL | impl<T,U> Remote for Pair<Cover<T>,U> { } diff --git a/src/test/ui/coherence/coherence-impls-copy.stderr b/src/test/ui/coherence/coherence-impls-copy.stderr index a7d6968a296..b3ca354c633 100644 --- a/src/test/ui/coherence/coherence-impls-copy.stderr +++ b/src/test/ui/coherence/coherence-impls-copy.stderr @@ -1,4 +1,4 @@ -error[E0117]: only traits defined in the current crate can be implemented for arbitrary types +error[E0117]: only traits defined in the current crate can be implemented for primitive types --> $DIR/coherence-impls-copy.rs:5:1 | LL | impl Copy for i32 {} diff --git a/src/test/ui/coherence/coherence-orphan.stderr b/src/test/ui/coherence/coherence-orphan.stderr index 52d2cc88cbe..01f166a21f7 100644 --- a/src/test/ui/coherence/coherence-orphan.stderr +++ b/src/test/ui/coherence/coherence-orphan.stderr @@ -1,4 +1,4 @@ -error[E0117]: only traits defined in the current crate can be implemented for arbitrary types +error[E0117]: only traits defined in the current crate can be implemented for primitive types --> $DIR/coherence-orphan.rs:10:1 | LL | impl TheTrait<usize> for isize { } @@ -10,7 +10,7 @@ LL | impl TheTrait<usize> for isize { } | = note: define and implement a trait or new type instead -error[E0117]: only traits defined in the current crate can be implemented for arbitrary types +error[E0117]: only traits defined in the current crate can be implemented for types defined outside of the crate --> $DIR/coherence-orphan.rs:17:1 | LL | impl !Send for Vec<isize> { } diff --git a/src/test/ui/coherence/coherence-overlapping-pairs.stderr b/src/test/ui/coherence/coherence-overlapping-pairs.stderr index c1a02681c13..15c92dfeb07 100644 --- a/src/test/ui/coherence/coherence-overlapping-pairs.stderr +++ b/src/test/ui/coherence/coherence-overlapping-pairs.stderr @@ -1,4 +1,4 @@ -error[E0117]: only traits defined in the current crate can be implemented for arbitrary types +error[E0117]: only traits defined in the current crate can be implemented for types defined outside of the crate --> $DIR/coherence-overlapping-pairs.rs:8:1 | LL | impl<T> Remote for lib::Pair<T,Foo> { } diff --git a/src/test/ui/coherence/coherence-pair-covered-uncovered-1.stderr b/src/test/ui/coherence/coherence-pair-covered-uncovered-1.stderr index b18bf44dbdf..03d78712381 100644 --- a/src/test/ui/coherence/coherence-pair-covered-uncovered-1.stderr +++ b/src/test/ui/coherence/coherence-pair-covered-uncovered-1.stderr @@ -1,4 +1,4 @@ -error[E0117]: only traits defined in the current crate can be implemented for arbitrary types +error[E0117]: only traits defined in the current crate can be implemented for primitive types --> $DIR/coherence-pair-covered-uncovered-1.rs:12:1 | LL | impl<T, U> Remote1<Pair<T, Local<U>>> for i32 { } diff --git a/src/test/ui/coherence/coherence-pair-covered-uncovered.stderr b/src/test/ui/coherence/coherence-pair-covered-uncovered.stderr index 34fdf64ea10..73dfe2f572a 100644 --- a/src/test/ui/coherence/coherence-pair-covered-uncovered.stderr +++ b/src/test/ui/coherence/coherence-pair-covered-uncovered.stderr @@ -1,4 +1,4 @@ -error[E0117]: only traits defined in the current crate can be implemented for arbitrary types +error[E0117]: only traits defined in the current crate can be implemented for types defined outside of the crate --> $DIR/coherence-pair-covered-uncovered.rs:8:1 | LL | impl<T,U> Remote for Pair<T,Local<U>> { } diff --git a/src/test/ui/coherence/coherence-vec-local-2.stderr b/src/test/ui/coherence/coherence-vec-local-2.stderr index 567b6a6c17f..95fdf172ec2 100644 --- a/src/test/ui/coherence/coherence-vec-local-2.stderr +++ b/src/test/ui/coherence/coherence-vec-local-2.stderr @@ -1,4 +1,4 @@ -error[E0117]: only traits defined in the current crate can be implemented for arbitrary types +error[E0117]: only traits defined in the current crate can be implemented for types defined outside of the crate --> $DIR/coherence-vec-local-2.rs:11:1 | LL | impl<T> Remote for Vec<Local<T>> { } diff --git a/src/test/ui/coherence/coherence-vec-local.stderr b/src/test/ui/coherence/coherence-vec-local.stderr index 38464f12a21..4835e771abd 100644 --- a/src/test/ui/coherence/coherence-vec-local.stderr +++ b/src/test/ui/coherence/coherence-vec-local.stderr @@ -1,4 +1,4 @@ -error[E0117]: only traits defined in the current crate can be implemented for arbitrary types +error[E0117]: only traits defined in the current crate can be implemented for types defined outside of the crate --> $DIR/coherence-vec-local.rs:11:1 | LL | impl Remote for Vec<Local> { } diff --git a/src/test/ui/coherence/coherence_local_err_struct.stderr b/src/test/ui/coherence/coherence_local_err_struct.stderr index 8c310b318a7..afc6fc45d0e 100644 --- a/src/test/ui/coherence/coherence_local_err_struct.stderr +++ b/src/test/ui/coherence/coherence_local_err_struct.stderr @@ -1,4 +1,4 @@ -error[E0117]: only traits defined in the current crate can be implemented for arbitrary types +error[E0117]: only traits defined in the current crate can be implemented for types defined outside of the crate --> $DIR/coherence_local_err_struct.rs:14:1 | LL | impl lib::MyCopy for lib::MyStruct<MyType> { } diff --git a/src/test/ui/coherence/impl-foreign-for-foreign.stderr b/src/test/ui/coherence/impl-foreign-for-foreign.stderr index fe7c9b93f54..93f7a6fdc25 100644 --- a/src/test/ui/coherence/impl-foreign-for-foreign.stderr +++ b/src/test/ui/coherence/impl-foreign-for-foreign.stderr @@ -1,4 +1,4 @@ -error[E0117]: only traits defined in the current crate can be implemented for arbitrary types +error[E0117]: only traits defined in the current crate can be implemented for primitive types --> $DIR/impl-foreign-for-foreign.rs:10:1 | LL | impl Remote for i32 { diff --git a/src/test/ui/coherence/impl-foreign-for-foreign[foreign].stderr b/src/test/ui/coherence/impl-foreign-for-foreign[foreign].stderr index bdf19cf00a7..e24537bce22 100644 --- a/src/test/ui/coherence/impl-foreign-for-foreign[foreign].stderr +++ b/src/test/ui/coherence/impl-foreign-for-foreign[foreign].stderr @@ -1,4 +1,4 @@ -error[E0117]: only traits defined in the current crate can be implemented for arbitrary types +error[E0117]: only traits defined in the current crate can be implemented for primitive types --> $DIR/impl-foreign-for-foreign[foreign].rs:10:1 | LL | impl Remote1<Rc<i32>> for i32 { @@ -10,7 +10,7 @@ LL | impl Remote1<Rc<i32>> for i32 { | = note: define and implement a trait or new type instead -error[E0117]: only traits defined in the current crate can be implemented for arbitrary types +error[E0117]: only traits defined in the current crate can be implemented for primitive types --> $DIR/impl-foreign-for-foreign[foreign].rs:14:1 | LL | impl Remote1<Rc<Local>> for f64 { @@ -22,7 +22,7 @@ LL | impl Remote1<Rc<Local>> for f64 { | = note: define and implement a trait or new type instead -error[E0117]: only traits defined in the current crate can be implemented for arbitrary types +error[E0117]: only traits defined in the current crate can be implemented for primitive types --> $DIR/impl-foreign-for-foreign[foreign].rs:18:1 | LL | impl<T> Remote1<Rc<T>> for f32 { diff --git a/src/test/ui/coherence/impl-foreign-for-fundamental[foreign].stderr b/src/test/ui/coherence/impl-foreign-for-fundamental[foreign].stderr index 20dc955ffe4..55ea4409e6f 100644 --- a/src/test/ui/coherence/impl-foreign-for-fundamental[foreign].stderr +++ b/src/test/ui/coherence/impl-foreign-for-fundamental[foreign].stderr @@ -1,4 +1,4 @@ -error[E0117]: only traits defined in the current crate can be implemented for arbitrary types +error[E0117]: only traits defined in the current crate can be implemented for types defined outside of the crate --> $DIR/impl-foreign-for-fundamental[foreign].rs:10:1 | LL | impl Remote for Box<i32> { @@ -10,7 +10,7 @@ LL | impl Remote for Box<i32> { | = note: define and implement a trait or new type instead -error[E0117]: only traits defined in the current crate can be implemented for arbitrary types +error[E0117]: only traits defined in the current crate can be implemented for types defined outside of the crate --> $DIR/impl-foreign-for-fundamental[foreign].rs:14:1 | LL | impl<T> Remote for Box<Rc<T>> { diff --git a/src/test/ui/coherence/impl-foreign[foreign]-for-foreign.stderr b/src/test/ui/coherence/impl-foreign[foreign]-for-foreign.stderr index 5552d825793..65b3aa394a8 100644 --- a/src/test/ui/coherence/impl-foreign[foreign]-for-foreign.stderr +++ b/src/test/ui/coherence/impl-foreign[foreign]-for-foreign.stderr @@ -1,4 +1,4 @@ -error[E0117]: only traits defined in the current crate can be implemented for arbitrary types +error[E0117]: only traits defined in the current crate can be implemented for primitive types --> $DIR/impl-foreign[foreign]-for-foreign.rs:10:1 | LL | impl Remote1<u32> for f64 { diff --git a/src/test/ui/coherence/impl-foreign[fundemental[foreign]]-for-foreign.stderr b/src/test/ui/coherence/impl-foreign[fundemental[foreign]]-for-foreign.stderr index c1e2fdaf5e3..8e77c13e111 100644 --- a/src/test/ui/coherence/impl-foreign[fundemental[foreign]]-for-foreign.stderr +++ b/src/test/ui/coherence/impl-foreign[fundemental[foreign]]-for-foreign.stderr @@ -1,4 +1,4 @@ -error[E0117]: only traits defined in the current crate can be implemented for arbitrary types +error[E0117]: only traits defined in the current crate can be implemented for primitive types --> $DIR/impl-foreign[fundemental[foreign]]-for-foreign.rs:11:1 | LL | impl Remote1<Box<String>> for i32 { @@ -11,7 +11,7 @@ LL | impl Remote1<Box<String>> for i32 { | = note: define and implement a trait or new type instead -error[E0117]: only traits defined in the current crate can be implemented for arbitrary types +error[E0117]: only traits defined in the current crate can be implemented for primitive types --> $DIR/impl-foreign[fundemental[foreign]]-for-foreign.rs:15:1 | LL | impl Remote1<Box<Rc<i32>>> for f64 { @@ -24,7 +24,7 @@ LL | impl Remote1<Box<Rc<i32>>> for f64 { | = note: define and implement a trait or new type instead -error[E0117]: only traits defined in the current crate can be implemented for arbitrary types +error[E0117]: only traits defined in the current crate can be implemented for primitive types --> $DIR/impl-foreign[fundemental[foreign]]-for-foreign.rs:19:1 | LL | impl<T> Remote1<Box<Rc<T>>> for f32 { diff --git a/src/test/ui/coherence/impl[t]-foreign-for-foreign[t].stderr b/src/test/ui/coherence/impl[t]-foreign-for-foreign[t].stderr index 7f8ec83b24a..92346c29198 100644 --- a/src/test/ui/coherence/impl[t]-foreign-for-foreign[t].stderr +++ b/src/test/ui/coherence/impl[t]-foreign-for-foreign[t].stderr @@ -1,4 +1,4 @@ -error[E0117]: only traits defined in the current crate can be implemented for arbitrary types +error[E0117]: only traits defined in the current crate can be implemented for types defined outside of the crate --> $DIR/impl[t]-foreign-for-foreign[t].rs:11:1 | LL | impl Remote for Rc<Local> { @@ -9,7 +9,7 @@ LL | impl Remote for Rc<Local> { | = note: define and implement a trait or new type instead -error[E0117]: only traits defined in the current crate can be implemented for arbitrary types +error[E0117]: only traits defined in the current crate can be implemented for types defined outside of the crate --> $DIR/impl[t]-foreign-for-foreign[t].rs:16:1 | LL | impl<T> Remote for Arc<T> { diff --git a/src/test/ui/conservative_impl_trait.rs b/src/test/ui/conservative_impl_trait.rs index b8488d83998..b7f795eadb7 100644 --- a/src/test/ui/conservative_impl_trait.rs +++ b/src/test/ui/conservative_impl_trait.rs @@ -2,7 +2,6 @@ fn will_ice(something: &u32) -> impl Iterator<Item = &u32> { //~^ ERROR `()` is not an iterator - //~| ERROR `()` is not an iterator } fn main() {} diff --git a/src/test/ui/conservative_impl_trait.stderr b/src/test/ui/conservative_impl_trait.stderr index 2348f2f5297..63a4df242f8 100644 --- a/src/test/ui/conservative_impl_trait.stderr +++ b/src/test/ui/conservative_impl_trait.stderr @@ -6,18 +6,6 @@ LL | fn will_ice(something: &u32) -> impl Iterator<Item = &u32> { | = help: the trait `Iterator` is not implemented for `()` -error[E0277]: `()` is not an iterator - --> $DIR/conservative_impl_trait.rs:3:60 - | -LL | fn will_ice(something: &u32) -> impl Iterator<Item = &u32> { - | ____________________________________________________________^ -LL | | -LL | | -LL | | } - | |_^ `()` is not an iterator - | - = help: the trait `Iterator` is not implemented for `()` - -error: aborting due to 2 previous errors +error: aborting due to previous error For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/const-generics/const-arg-in-const-arg.min.stderr b/src/test/ui/const-generics/const-arg-in-const-arg.min.stderr index ac693426fbd..88d9ed46e1a 100644 --- a/src/test/ui/const-generics/const-arg-in-const-arg.min.stderr +++ b/src/test/ui/const-generics/const-arg-in-const-arg.min.stderr @@ -16,53 +16,8 @@ LL | let _: [u8; bar::<N>()]; = help: const parameters may only be used as standalone arguments, i.e. `N` = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions -error: generic parameters may not be used in const operations - --> $DIR/const-arg-in-const-arg.rs:24:23 - | -LL | let _ = [0; bar::<N>()]; - | ^ cannot perform const operation using `N` - | - = help: const parameters may only be used as standalone arguments, i.e. `N` - = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions - -error: generic parameters may not be used in const operations - --> $DIR/const-arg-in-const-arg.rs:29:24 - | -LL | let _: Foo<{ foo::<T>() }>; - | ^ cannot perform const operation using `T` - | - = note: type parameters may not be used in const expressions - = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions - -error: generic parameters may not be used in const operations - --> $DIR/const-arg-in-const-arg.rs:30:24 - | -LL | let _: Foo<{ bar::<N>() }>; - | ^ cannot perform const operation using `N` - | - = help: const parameters may only be used as standalone arguments, i.e. `N` - = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions - -error: generic parameters may not be used in const operations - --> $DIR/const-arg-in-const-arg.rs:35:27 - | -LL | let _ = Foo::<{ foo::<T>() }>; - | ^ cannot perform const operation using `T` - | - = note: type parameters may not be used in const expressions - = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions - -error: generic parameters may not be used in const operations - --> $DIR/const-arg-in-const-arg.rs:36:27 - | -LL | let _ = Foo::<{ bar::<N>() }>; - | ^ cannot perform const operation using `N` - | - = help: const parameters may only be used as standalone arguments, i.e. `N` - = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions - error[E0658]: a non-static lifetime is not allowed in a `const` - --> $DIR/const-arg-in-const-arg.rs:15:23 + --> $DIR/const-arg-in-const-arg.rs:16:23 | LL | let _: [u8; faz::<'a>(&())]; | ^^ @@ -71,7 +26,7 @@ LL | let _: [u8; faz::<'a>(&())]; = help: add `#![feature(generic_const_exprs)]` to the crate attributes to enable error[E0658]: a non-static lifetime is not allowed in a `const` - --> $DIR/const-arg-in-const-arg.rs:16:23 + --> $DIR/const-arg-in-const-arg.rs:18:23 | LL | let _: [u8; baz::<'a>(&())]; | ^^ @@ -80,7 +35,7 @@ LL | let _: [u8; baz::<'a>(&())]; = help: add `#![feature(generic_const_exprs)]` to the crate attributes to enable error[E0658]: a non-static lifetime is not allowed in a `const` - --> $DIR/const-arg-in-const-arg.rs:17:23 + --> $DIR/const-arg-in-const-arg.rs:19:23 | LL | let _: [u8; faz::<'b>(&())]; | ^^ @@ -89,7 +44,7 @@ LL | let _: [u8; faz::<'b>(&())]; = help: add `#![feature(generic_const_exprs)]` to the crate attributes to enable error[E0658]: a non-static lifetime is not allowed in a `const` - --> $DIR/const-arg-in-const-arg.rs:18:23 + --> $DIR/const-arg-in-const-arg.rs:21:23 | LL | let _: [u8; baz::<'b>(&())]; | ^^ @@ -97,8 +52,17 @@ LL | let _: [u8; baz::<'b>(&())]; = note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information = help: add `#![feature(generic_const_exprs)]` to the crate attributes to enable +error: generic parameters may not be used in const operations + --> $DIR/const-arg-in-const-arg.rs:24:23 + | +LL | let _ = [0; bar::<N>()]; + | ^ cannot perform const operation using `N` + | + = help: const parameters may only be used as standalone arguments, i.e. `N` + = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions + error[E0658]: a non-static lifetime is not allowed in a `const` - --> $DIR/const-arg-in-const-arg.rs:25:23 + --> $DIR/const-arg-in-const-arg.rs:26:23 | LL | let _ = [0; faz::<'a>(&())]; | ^^ @@ -107,7 +71,7 @@ LL | let _ = [0; faz::<'a>(&())]; = help: add `#![feature(generic_const_exprs)]` to the crate attributes to enable error[E0658]: a non-static lifetime is not allowed in a `const` - --> $DIR/const-arg-in-const-arg.rs:26:23 + --> $DIR/const-arg-in-const-arg.rs:28:23 | LL | let _ = [0; baz::<'a>(&())]; | ^^ @@ -116,7 +80,7 @@ LL | let _ = [0; baz::<'a>(&())]; = help: add `#![feature(generic_const_exprs)]` to the crate attributes to enable error[E0658]: a non-static lifetime is not allowed in a `const` - --> $DIR/const-arg-in-const-arg.rs:27:23 + --> $DIR/const-arg-in-const-arg.rs:29:23 | LL | let _ = [0; faz::<'b>(&())]; | ^^ @@ -125,7 +89,7 @@ LL | let _ = [0; faz::<'b>(&())]; = help: add `#![feature(generic_const_exprs)]` to the crate attributes to enable error[E0658]: a non-static lifetime is not allowed in a `const` - --> $DIR/const-arg-in-const-arg.rs:28:23 + --> $DIR/const-arg-in-const-arg.rs:31:23 | LL | let _ = [0; baz::<'b>(&())]; | ^^ @@ -133,8 +97,26 @@ LL | let _ = [0; baz::<'b>(&())]; = note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information = help: add `#![feature(generic_const_exprs)]` to the crate attributes to enable +error: generic parameters may not be used in const operations + --> $DIR/const-arg-in-const-arg.rs:32:24 + | +LL | let _: Foo<{ foo::<T>() }>; + | ^ cannot perform const operation using `T` + | + = note: type parameters may not be used in const expressions + = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions + +error: generic parameters may not be used in const operations + --> $DIR/const-arg-in-const-arg.rs:33:24 + | +LL | let _: Foo<{ bar::<N>() }>; + | ^ cannot perform const operation using `N` + | + = help: const parameters may only be used as standalone arguments, i.e. `N` + = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions + error[E0658]: a non-static lifetime is not allowed in a `const` - --> $DIR/const-arg-in-const-arg.rs:31:24 + --> $DIR/const-arg-in-const-arg.rs:35:24 | LL | let _: Foo<{ faz::<'a>(&()) }>; | ^^ @@ -143,7 +125,7 @@ LL | let _: Foo<{ faz::<'a>(&()) }>; = help: add `#![feature(generic_const_exprs)]` to the crate attributes to enable error[E0658]: a non-static lifetime is not allowed in a `const` - --> $DIR/const-arg-in-const-arg.rs:32:24 + --> $DIR/const-arg-in-const-arg.rs:37:24 | LL | let _: Foo<{ baz::<'a>(&()) }>; | ^^ @@ -152,7 +134,7 @@ LL | let _: Foo<{ baz::<'a>(&()) }>; = help: add `#![feature(generic_const_exprs)]` to the crate attributes to enable error[E0658]: a non-static lifetime is not allowed in a `const` - --> $DIR/const-arg-in-const-arg.rs:33:24 + --> $DIR/const-arg-in-const-arg.rs:38:24 | LL | let _: Foo<{ faz::<'b>(&()) }>; | ^^ @@ -161,7 +143,7 @@ LL | let _: Foo<{ faz::<'b>(&()) }>; = help: add `#![feature(generic_const_exprs)]` to the crate attributes to enable error[E0658]: a non-static lifetime is not allowed in a `const` - --> $DIR/const-arg-in-const-arg.rs:34:24 + --> $DIR/const-arg-in-const-arg.rs:40:24 | LL | let _: Foo<{ baz::<'b>(&()) }>; | ^^ @@ -169,8 +151,26 @@ LL | let _: Foo<{ baz::<'b>(&()) }>; = note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information = help: add `#![feature(generic_const_exprs)]` to the crate attributes to enable +error: generic parameters may not be used in const operations + --> $DIR/const-arg-in-const-arg.rs:41:27 + | +LL | let _ = Foo::<{ foo::<T>() }>; + | ^ cannot perform const operation using `T` + | + = note: type parameters may not be used in const expressions + = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions + +error: generic parameters may not be used in const operations + --> $DIR/const-arg-in-const-arg.rs:42:27 + | +LL | let _ = Foo::<{ bar::<N>() }>; + | ^ cannot perform const operation using `N` + | + = help: const parameters may only be used as standalone arguments, i.e. `N` + = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions + error[E0658]: a non-static lifetime is not allowed in a `const` - --> $DIR/const-arg-in-const-arg.rs:37:27 + --> $DIR/const-arg-in-const-arg.rs:44:27 | LL | let _ = Foo::<{ faz::<'a>(&()) }>; | ^^ @@ -179,7 +179,7 @@ LL | let _ = Foo::<{ faz::<'a>(&()) }>; = help: add `#![feature(generic_const_exprs)]` to the crate attributes to enable error[E0658]: a non-static lifetime is not allowed in a `const` - --> $DIR/const-arg-in-const-arg.rs:38:27 + --> $DIR/const-arg-in-const-arg.rs:46:27 | LL | let _ = Foo::<{ baz::<'a>(&()) }>; | ^^ @@ -188,7 +188,7 @@ LL | let _ = Foo::<{ baz::<'a>(&()) }>; = help: add `#![feature(generic_const_exprs)]` to the crate attributes to enable error[E0658]: a non-static lifetime is not allowed in a `const` - --> $DIR/const-arg-in-const-arg.rs:39:27 + --> $DIR/const-arg-in-const-arg.rs:47:27 | LL | let _ = Foo::<{ faz::<'b>(&()) }>; | ^^ @@ -197,7 +197,7 @@ LL | let _ = Foo::<{ faz::<'b>(&()) }>; = help: add `#![feature(generic_const_exprs)]` to the crate attributes to enable error[E0658]: a non-static lifetime is not allowed in a `const` - --> $DIR/const-arg-in-const-arg.rs:40:27 + --> $DIR/const-arg-in-const-arg.rs:49:27 | LL | let _ = Foo::<{ baz::<'b>(&()) }>; | ^^ @@ -205,6 +205,155 @@ LL | let _ = Foo::<{ baz::<'b>(&()) }>; = note: see issue #76560 <https://github.com/rust-lang/rust/issues/76560> for more information = help: add `#![feature(generic_const_exprs)]` to the crate attributes to enable -error: aborting due to 23 previous errors +error[E0747]: unresolved item provided when a constant was expected + --> $DIR/const-arg-in-const-arg.rs:14:23 + | +LL | let _: [u8; bar::<N>()]; + | ^ + | +help: if this generic argument was intended as a const parameter, surround it with braces + | +LL | let _: [u8; bar::<{ N }>()]; + | + + + +error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present + --> $DIR/const-arg-in-const-arg.rs:16:23 + | +LL | let _: [u8; faz::<'a>(&())]; + | ^^ + | +note: the late bound lifetime parameter is introduced here + --> $DIR/const-arg-in-const-arg.rs:8:14 + | +LL | const fn faz<'a>(_: &'a ()) -> usize { 13 } + | ^^ + +error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present + --> $DIR/const-arg-in-const-arg.rs:19:23 + | +LL | let _: [u8; faz::<'b>(&())]; + | ^^ + | +note: the late bound lifetime parameter is introduced here + --> $DIR/const-arg-in-const-arg.rs:8:14 + | +LL | const fn faz<'a>(_: &'a ()) -> usize { 13 } + | ^^ + +error[E0747]: unresolved item provided when a constant was expected + --> $DIR/const-arg-in-const-arg.rs:24:23 + | +LL | let _ = [0; bar::<N>()]; + | ^ + | +help: if this generic argument was intended as a const parameter, surround it with braces + | +LL | let _ = [0; bar::<{ N }>()]; + | + + + +error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present + --> $DIR/const-arg-in-const-arg.rs:26:23 + | +LL | let _ = [0; faz::<'a>(&())]; + | ^^ + | +note: the late bound lifetime parameter is introduced here + --> $DIR/const-arg-in-const-arg.rs:8:14 + | +LL | const fn faz<'a>(_: &'a ()) -> usize { 13 } + | ^^ + +error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present + --> $DIR/const-arg-in-const-arg.rs:29:23 + | +LL | let _ = [0; faz::<'b>(&())]; + | ^^ + | +note: the late bound lifetime parameter is introduced here + --> $DIR/const-arg-in-const-arg.rs:8:14 + | +LL | const fn faz<'a>(_: &'a ()) -> usize { 13 } + | ^^ + +error[E0747]: unresolved item provided when a constant was expected + --> $DIR/const-arg-in-const-arg.rs:33:24 + | +LL | let _: Foo<{ bar::<N>() }>; + | ^ + | +help: if this generic argument was intended as a const parameter, surround it with braces + | +LL | let _: Foo<{ bar::<{ N }>() }>; + | + + + +error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present + --> $DIR/const-arg-in-const-arg.rs:35:24 + | +LL | let _: Foo<{ faz::<'a>(&()) }>; + | ^^ + | +note: the late bound lifetime parameter is introduced here + --> $DIR/const-arg-in-const-arg.rs:8:14 + | +LL | const fn faz<'a>(_: &'a ()) -> usize { 13 } + | ^^ + +error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present + --> $DIR/const-arg-in-const-arg.rs:38:24 + | +LL | let _: Foo<{ faz::<'b>(&()) }>; + | ^^ + | +note: the late bound lifetime parameter is introduced here + --> $DIR/const-arg-in-const-arg.rs:8:14 + | +LL | const fn faz<'a>(_: &'a ()) -> usize { 13 } + | ^^ + +error: constant expression depends on a generic parameter + --> $DIR/const-arg-in-const-arg.rs:23:17 + | +LL | let _ = [0; foo::<T>()]; + | ^^^^^^^^^^ + | + = note: this may fail depending on what value the parameter takes + +error[E0747]: unresolved item provided when a constant was expected + --> $DIR/const-arg-in-const-arg.rs:42:27 + | +LL | let _ = Foo::<{ bar::<N>() }>; + | ^ + | +help: if this generic argument was intended as a const parameter, surround it with braces + | +LL | let _ = Foo::<{ bar::<{ N }>() }>; + | + + + +error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present + --> $DIR/const-arg-in-const-arg.rs:44:27 + | +LL | let _ = Foo::<{ faz::<'a>(&()) }>; + | ^^ + | +note: the late bound lifetime parameter is introduced here + --> $DIR/const-arg-in-const-arg.rs:8:14 + | +LL | const fn faz<'a>(_: &'a ()) -> usize { 13 } + | ^^ + +error: cannot specify lifetime arguments explicitly if late bound lifetime parameters are present + --> $DIR/const-arg-in-const-arg.rs:47:27 + | +LL | let _ = Foo::<{ faz::<'b>(&()) }>; + | ^^ + | +note: the late bound lifetime parameter is introduced here + --> $DIR/const-arg-in-const-arg.rs:8:14 + | +LL | const fn faz<'a>(_: &'a ()) -> usize { 13 } + | ^^ + +error: aborting due to 36 previous errors -For more information about this error, try `rustc --explain E0658`. +Some errors have detailed explanations: E0658, E0747. +For more information about an error, try `rustc --explain E0658`. diff --git a/src/test/ui/const-generics/const-arg-in-const-arg.rs b/src/test/ui/const-generics/const-arg-in-const-arg.rs index 39f0b237330..b9daadb5474 100644 --- a/src/test/ui/const-generics/const-arg-in-const-arg.rs +++ b/src/test/ui/const-generics/const-arg-in-const-arg.rs @@ -12,31 +12,40 @@ struct Foo<const N: usize>; fn test<'a, 'b, T, const N: usize>() where &'b (): Sized { let _: [u8; foo::<T>()]; //~ ERROR generic parameters may not let _: [u8; bar::<N>()]; //~ ERROR generic parameters may not + //~^ ERROR unresolved item provided when a constant was expected let _: [u8; faz::<'a>(&())]; //~ ERROR a non-static lifetime + //~^ ERROR cannot specify lifetime arguments let _: [u8; baz::<'a>(&())]; //~ ERROR a non-static lifetime let _: [u8; faz::<'b>(&())]; //~ ERROR a non-static lifetime + //~^ ERROR cannot specify lifetime arguments let _: [u8; baz::<'b>(&())]; //~ ERROR a non-static lifetime - // NOTE: This can be a future compat warning instead of an error, - // so we stop compilation before emitting this error in this test. - let _ = [0; foo::<T>()]; - + let _ = [0; foo::<T>()]; //~ ERROR constant expression depends on a generic parameter let _ = [0; bar::<N>()]; //~ ERROR generic parameters may not + //~^ ERROR unresolved item provided when a constant was expected let _ = [0; faz::<'a>(&())]; //~ ERROR a non-static lifetime + //~^ ERROR cannot specify lifetime arguments let _ = [0; baz::<'a>(&())]; //~ ERROR a non-static lifetime let _ = [0; faz::<'b>(&())]; //~ ERROR a non-static lifetime + //~^ ERROR cannot specify lifetime arguments let _ = [0; baz::<'b>(&())]; //~ ERROR a non-static lifetime let _: Foo<{ foo::<T>() }>; //~ ERROR generic parameters may not let _: Foo<{ bar::<N>() }>; //~ ERROR generic parameters may not + //~^ ERROR unresolved item provided when a constant was expected let _: Foo<{ faz::<'a>(&()) }>; //~ ERROR a non-static lifetime + //~^ ERROR cannot specify lifetime arguments let _: Foo<{ baz::<'a>(&()) }>; //~ ERROR a non-static lifetime let _: Foo<{ faz::<'b>(&()) }>; //~ ERROR a non-static lifetime + //~^ ERROR cannot specify lifetime arguments let _: Foo<{ baz::<'b>(&()) }>; //~ ERROR a non-static lifetime let _ = Foo::<{ foo::<T>() }>; //~ ERROR generic parameters may not let _ = Foo::<{ bar::<N>() }>; //~ ERROR generic parameters may not + //~^ ERROR unresolved item provided when a constant was expected let _ = Foo::<{ faz::<'a>(&()) }>; //~ ERROR a non-static lifetime + //~^ ERROR cannot specify lifetime arguments let _ = Foo::<{ baz::<'a>(&()) }>; //~ ERROR a non-static lifetime let _ = Foo::<{ faz::<'b>(&()) }>; //~ ERROR a non-static lifetime + //~^ ERROR cannot specify lifetime arguments let _ = Foo::<{ baz::<'b>(&()) }>; //~ ERROR a non-static lifetime } diff --git a/src/test/ui/const-generics/defaults/rp_impl_trait_fail.rs b/src/test/ui/const-generics/defaults/rp_impl_trait_fail.rs index 24031aa1e61..308c121a941 100644 --- a/src/test/ui/const-generics/defaults/rp_impl_trait_fail.rs +++ b/src/test/ui/const-generics/defaults/rp_impl_trait_fail.rs @@ -5,7 +5,6 @@ impl<const N: u32> Trait for Uwu<N> {} fn rawr() -> impl Trait { //~^ error: the trait bound `Uwu<10_u32, 12_u32>: Trait` is not satisfied - //~| error: the trait bound `Uwu<10_u32, 12_u32>: Trait` is not satisfied Uwu::<10, 12> } @@ -17,13 +16,11 @@ impl Traitor<1, 2> for u64 {} fn uwu<const N: u8>() -> impl Traitor<N> { //~^ error: the trait bound `u32: Traitor<N, N>` is not satisfied - //~| error: the trait bound `u32: Traitor<N, N>` is not satisfied 1_u32 } fn owo() -> impl Traitor { //~^ error: the trait bound `u64: Traitor<1_u8, 1_u8>` is not satisfied - //~| error: the trait bound `u64: Traitor<1_u8, 1_u8>` is not satisfied 1_u64 } diff --git a/src/test/ui/const-generics/defaults/rp_impl_trait_fail.stderr b/src/test/ui/const-generics/defaults/rp_impl_trait_fail.stderr index 48c61c22e7a..8031da28ca1 100644 --- a/src/test/ui/const-generics/defaults/rp_impl_trait_fail.stderr +++ b/src/test/ui/const-generics/defaults/rp_impl_trait_fail.stderr @@ -6,21 +6,8 @@ LL | fn rawr() -> impl Trait { | = help: the trait `Trait` is implemented for `Uwu<N>` -error[E0277]: the trait bound `Uwu<10_u32, 12_u32>: Trait` is not satisfied - --> $DIR/rp_impl_trait_fail.rs:6:25 - | -LL | fn rawr() -> impl Trait { - | _________________________^ -LL | | -LL | | -LL | | Uwu::<10, 12> -LL | | } - | |_^ the trait `Trait` is not implemented for `Uwu<10_u32, 12_u32>` - | - = help: the trait `Trait` is implemented for `Uwu<N>` - error[E0277]: the trait bound `u32: Traitor<N, N>` is not satisfied - --> $DIR/rp_impl_trait_fail.rs:18:26 + --> $DIR/rp_impl_trait_fail.rs:17:26 | LL | fn uwu<const N: u8>() -> impl Traitor<N> { | ^^^^^^^^^^^^^^^ the trait `Traitor<N, N>` is not implemented for `u32` @@ -29,23 +16,8 @@ LL | fn uwu<const N: u8>() -> impl Traitor<N> { <u32 as Traitor<N, 2_u8>> <u64 as Traitor<1_u8, 2_u8>> -error[E0277]: the trait bound `u32: Traitor<N, N>` is not satisfied - --> $DIR/rp_impl_trait_fail.rs:18:42 - | -LL | fn uwu<const N: u8>() -> impl Traitor<N> { - | __________________________________________^ -LL | | -LL | | -LL | | 1_u32 -LL | | } - | |_^ the trait `Traitor<N, N>` is not implemented for `u32` - | - = help: the following other types implement trait `Traitor<N, M>`: - <u32 as Traitor<N, 2_u8>> - <u64 as Traitor<1_u8, 2_u8>> - error[E0277]: the trait bound `u64: Traitor<1_u8, 1_u8>` is not satisfied - --> $DIR/rp_impl_trait_fail.rs:24:13 + --> $DIR/rp_impl_trait_fail.rs:22:13 | LL | fn owo() -> impl Traitor { | ^^^^^^^^^^^^ the trait `Traitor<1_u8, 1_u8>` is not implemented for `u64` @@ -54,21 +26,6 @@ LL | fn owo() -> impl Traitor { <u32 as Traitor<N, 2_u8>> <u64 as Traitor<1_u8, 2_u8>> -error[E0277]: the trait bound `u64: Traitor<1_u8, 1_u8>` is not satisfied - --> $DIR/rp_impl_trait_fail.rs:24:26 - | -LL | fn owo() -> impl Traitor { - | __________________________^ -LL | | -LL | | -LL | | 1_u64 -LL | | } - | |_^ the trait `Traitor<1_u8, 1_u8>` is not implemented for `u64` - | - = help: the following other types implement trait `Traitor<N, M>`: - <u32 as Traitor<N, 2_u8>> - <u64 as Traitor<1_u8, 2_u8>> - -error: aborting due to 6 previous errors +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/const-generics/issues/issue-56445-1.min.stderr b/src/test/ui/const-generics/issues/issue-56445-1.min.stderr index 179643a7552..43a5df117fd 100644 --- a/src/test/ui/const-generics/issues/issue-56445-1.min.stderr +++ b/src/test/ui/const-generics/issues/issue-56445-1.min.stderr @@ -6,6 +6,15 @@ LL | struct Bug<'a, const S: &'a str>(PhantomData<&'a ()>); | = note: for more information, see issue #74052 <https://github.com/rust-lang/rust/issues/74052> -error: aborting due to previous error +error: `&'static str` is forbidden as the type of a const generic parameter + --> $DIR/issue-56445-1.rs:9:25 + | +LL | struct Bug<'a, const S: &'a str>(PhantomData<&'a ()>); + | ^^^^^^^ + | + = note: the only supported types are integers, `bool` and `char` + = help: more complex types are supported with `#![feature(adt_const_params)]` + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0771`. diff --git a/src/test/ui/const-generics/issues/issue-56445-1.rs b/src/test/ui/const-generics/issues/issue-56445-1.rs index aeef778991f..13eb2ea9f69 100644 --- a/src/test/ui/const-generics/issues/issue-56445-1.rs +++ b/src/test/ui/const-generics/issues/issue-56445-1.rs @@ -8,5 +8,6 @@ use std::marker::PhantomData; struct Bug<'a, const S: &'a str>(PhantomData<&'a ()>); //~^ ERROR: use of non-static lifetime `'a` in const generic +//[min]~| ERROR: `&'static str` is forbidden as the type of a const generic parameter impl Bug<'_, ""> {} diff --git a/src/test/ui/const-generics/issues/issue-61336-2.stderr b/src/test/ui/const-generics/issues/issue-61336-2.stderr index 48aaaf5e544..5bb35669623 100644 --- a/src/test/ui/const-generics/issues/issue-61336-2.stderr +++ b/src/test/ui/const-generics/issues/issue-61336-2.stderr @@ -1,10 +1,10 @@ error[E0277]: the trait bound `T: Copy` is not satisfied - --> $DIR/issue-61336-2.rs:6:5 + --> $DIR/issue-61336-2.rs:6:6 | LL | [x; { N }] - | ^^^^^^^^^^ the trait `Copy` is not implemented for `T` + | ^ the trait `Copy` is not implemented for `T` | - = note: the `Copy` trait is required because the repeated element will be copied + = note: the `Copy` trait is required because this value will be copied for each element of the array help: consider restricting type parameter `T` | LL | fn g<T: std::marker::Copy, const N: usize>(x: T) -> [T; N] { diff --git a/src/test/ui/const-generics/issues/issue-61336.stderr b/src/test/ui/const-generics/issues/issue-61336.stderr index 665a1a677a1..8d9e545b456 100644 --- a/src/test/ui/const-generics/issues/issue-61336.stderr +++ b/src/test/ui/const-generics/issues/issue-61336.stderr @@ -1,10 +1,10 @@ error[E0277]: the trait bound `T: Copy` is not satisfied - --> $DIR/issue-61336.rs:6:5 + --> $DIR/issue-61336.rs:6:6 | LL | [x; N] - | ^^^^^^ the trait `Copy` is not implemented for `T` + | ^ the trait `Copy` is not implemented for `T` | - = note: the `Copy` trait is required because the repeated element will be copied + = note: the `Copy` trait is required because this value will be copied for each element of the array help: consider restricting type parameter `T` | LL | fn g<T: std::marker::Copy, const N: usize>(x: T) -> [T; N] { diff --git a/src/test/ui/consts/const-blocks/fn-call-in-non-const.rs b/src/test/ui/consts/const-blocks/fn-call-in-non-const.rs index 19217843759..18b4dc714de 100644 --- a/src/test/ui/consts/const-blocks/fn-call-in-non-const.rs +++ b/src/test/ui/consts/const-blocks/fn-call-in-non-const.rs @@ -12,5 +12,5 @@ const fn copy() -> u32 { fn main() { let _: [u32; 2] = [copy(); 2]; let _: [Option<Bar>; 2] = [no_copy(); 2]; - //~^ ERROR the trait bound `Option<Bar>: Copy` is not satisfied + //~^ ERROR the trait bound `Bar: Copy` is not satisfied } diff --git a/src/test/ui/consts/const-blocks/fn-call-in-non-const.stderr b/src/test/ui/consts/const-blocks/fn-call-in-non-const.stderr index 52a1669e330..5306fed2251 100644 --- a/src/test/ui/consts/const-blocks/fn-call-in-non-const.stderr +++ b/src/test/ui/consts/const-blocks/fn-call-in-non-const.stderr @@ -1,13 +1,17 @@ -error[E0277]: the trait bound `Option<Bar>: Copy` is not satisfied - --> $DIR/fn-call-in-non-const.rs:14:31 +error[E0277]: the trait bound `Bar: Copy` is not satisfied + --> $DIR/fn-call-in-non-const.rs:14:32 | LL | let _: [Option<Bar>; 2] = [no_copy(); 2]; - | ^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `Option<Bar>` + | ^^^^^^^^^ the trait `Copy` is not implemented for `Bar` | - = help: the trait `Copy` is implemented for `Option<T>` - = note: the `Copy` trait is required because the repeated element will be copied + = note: required because of the requirements on the impl of `Copy` for `Option<Bar>` + = note: the `Copy` trait is required because this value will be copied for each element of the array = help: consider creating a new `const` item and initializing it with the result of the function call to be used in the repeat position, like `const VAL: Type = const_fn();` and `let x = [VAL; 42];` = help: create an inline `const` block, see RFC #2920 <https://github.com/rust-lang/rfcs/pull/2920> for more information +help: consider annotating `Bar` with `#[derive(Copy)]` + | +LL | #[derive(Copy)] + | error: aborting due to previous error diff --git a/src/test/ui/consts/const-blocks/migrate-fail.rs b/src/test/ui/consts/const-blocks/migrate-fail.rs index bb12139a7ba..d5a17249cc9 100644 --- a/src/test/ui/consts/const-blocks/migrate-fail.rs +++ b/src/test/ui/consts/const-blocks/migrate-fail.rs @@ -11,13 +11,13 @@ mod non_constants { fn no_impl_copy_empty_value_multiple_elements() { let x = None; let arr: [Option<Bar>; 2] = [x; 2]; - //~^ ERROR the trait bound `Option<Bar>: Copy` is not satisfied [E0277] + //~^ ERROR the trait bound `Bar: Copy` is not satisfied [E0277] } fn no_impl_copy_value_multiple_elements() { let x = Some(Bar); let arr: [Option<Bar>; 2] = [x; 2]; - //~^ ERROR the trait bound `Option<Bar>: Copy` is not satisfied [E0277] + //~^ ERROR the trait bound `Bar: Copy` is not satisfied [E0277] } } diff --git a/src/test/ui/consts/const-blocks/migrate-fail.stderr b/src/test/ui/consts/const-blocks/migrate-fail.stderr index 318fec60290..2e7ff5cb8b3 100644 --- a/src/test/ui/consts/const-blocks/migrate-fail.stderr +++ b/src/test/ui/consts/const-blocks/migrate-fail.stderr @@ -1,20 +1,28 @@ -error[E0277]: the trait bound `Option<Bar>: Copy` is not satisfied - --> $DIR/migrate-fail.rs:13:37 +error[E0277]: the trait bound `Bar: Copy` is not satisfied + --> $DIR/migrate-fail.rs:13:38 | LL | let arr: [Option<Bar>; 2] = [x; 2]; - | ^^^^^^ the trait `Copy` is not implemented for `Option<Bar>` + | ^ the trait `Copy` is not implemented for `Bar` + | + = note: required because of the requirements on the impl of `Copy` for `Option<Bar>` + = note: the `Copy` trait is required because this value will be copied for each element of the array +help: consider annotating `Bar` with `#[derive(Copy)]` + | +LL | #[derive(Copy)] | - = help: the trait `Copy` is implemented for `Option<T>` - = note: the `Copy` trait is required because the repeated element will be copied -error[E0277]: the trait bound `Option<Bar>: Copy` is not satisfied - --> $DIR/migrate-fail.rs:19:37 +error[E0277]: the trait bound `Bar: Copy` is not satisfied + --> $DIR/migrate-fail.rs:19:38 | LL | let arr: [Option<Bar>; 2] = [x; 2]; - | ^^^^^^ the trait `Copy` is not implemented for `Option<Bar>` + | ^ the trait `Copy` is not implemented for `Bar` + | + = note: required because of the requirements on the impl of `Copy` for `Option<Bar>` + = note: the `Copy` trait is required because this value will be copied for each element of the array +help: consider annotating `Bar` with `#[derive(Copy)]` + | +LL | #[derive(Copy)] | - = help: the trait `Copy` is implemented for `Option<T>` - = note: the `Copy` trait is required because the repeated element will be copied error: aborting due to 2 previous errors diff --git a/src/test/ui/consts/const-blocks/nll-fail.rs b/src/test/ui/consts/const-blocks/nll-fail.rs index 871387c1fd0..9d4aef39e54 100644 --- a/src/test/ui/consts/const-blocks/nll-fail.rs +++ b/src/test/ui/consts/const-blocks/nll-fail.rs @@ -10,13 +10,13 @@ mod non_constants { fn no_impl_copy_empty_value_multiple_elements() { let x = None; let arr: [Option<Bar>; 2] = [x; 2]; - //~^ ERROR the trait bound `Option<Bar>: Copy` is not satisfied [E0277] + //~^ ERROR the trait bound `Bar: Copy` is not satisfied [E0277] } fn no_impl_copy_value_multiple_elements() { let x = Some(Bar); let arr: [Option<Bar>; 2] = [x; 2]; - //~^ ERROR the trait bound `Option<Bar>: Copy` is not satisfied [E0277] + //~^ ERROR the trait bound `Bar: Copy` is not satisfied [E0277] } } diff --git a/src/test/ui/consts/const-blocks/nll-fail.stderr b/src/test/ui/consts/const-blocks/nll-fail.stderr index 5a34361aa83..c0d273b5a9a 100644 --- a/src/test/ui/consts/const-blocks/nll-fail.stderr +++ b/src/test/ui/consts/const-blocks/nll-fail.stderr @@ -1,20 +1,28 @@ -error[E0277]: the trait bound `Option<Bar>: Copy` is not satisfied - --> $DIR/nll-fail.rs:12:37 +error[E0277]: the trait bound `Bar: Copy` is not satisfied + --> $DIR/nll-fail.rs:12:38 | LL | let arr: [Option<Bar>; 2] = [x; 2]; - | ^^^^^^ the trait `Copy` is not implemented for `Option<Bar>` + | ^ the trait `Copy` is not implemented for `Bar` + | + = note: required because of the requirements on the impl of `Copy` for `Option<Bar>` + = note: the `Copy` trait is required because this value will be copied for each element of the array +help: consider annotating `Bar` with `#[derive(Copy)]` + | +LL | #[derive(Copy)] | - = help: the trait `Copy` is implemented for `Option<T>` - = note: the `Copy` trait is required because the repeated element will be copied -error[E0277]: the trait bound `Option<Bar>: Copy` is not satisfied - --> $DIR/nll-fail.rs:18:37 +error[E0277]: the trait bound `Bar: Copy` is not satisfied + --> $DIR/nll-fail.rs:18:38 | LL | let arr: [Option<Bar>; 2] = [x; 2]; - | ^^^^^^ the trait `Copy` is not implemented for `Option<Bar>` + | ^ the trait `Copy` is not implemented for `Bar` + | + = note: required because of the requirements on the impl of `Copy` for `Option<Bar>` + = note: the `Copy` trait is required because this value will be copied for each element of the array +help: consider annotating `Bar` with `#[derive(Copy)]` + | +LL | #[derive(Copy)] | - = help: the trait `Copy` is implemented for `Option<T>` - = note: the `Copy` trait is required because the repeated element will be copied error: aborting due to 2 previous errors diff --git a/src/test/ui/consts/const-blocks/trait-error.rs b/src/test/ui/consts/const-blocks/trait-error.rs index 5a614cbdd15..49d1e9b9434 100644 --- a/src/test/ui/consts/const-blocks/trait-error.rs +++ b/src/test/ui/consts/const-blocks/trait-error.rs @@ -3,5 +3,5 @@ struct Foo<T>(T); fn main() { [Foo(String::new()); 4]; - //~^ ERROR the trait bound `Foo<String>: Copy` is not satisfied [E0277] + //~^ ERROR the trait bound `String: Copy` is not satisfied [E0277] } diff --git a/src/test/ui/consts/const-blocks/trait-error.stderr b/src/test/ui/consts/const-blocks/trait-error.stderr index 6979ff36176..ece200ad10b 100644 --- a/src/test/ui/consts/const-blocks/trait-error.stderr +++ b/src/test/ui/consts/const-blocks/trait-error.stderr @@ -1,11 +1,18 @@ -error[E0277]: the trait bound `Foo<String>: Copy` is not satisfied - --> $DIR/trait-error.rs:5:5 +error[E0277]: the trait bound `String: Copy` is not satisfied + --> $DIR/trait-error.rs:5:6 | LL | [Foo(String::new()); 4]; - | ^^^^^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `Foo<String>` + | ^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `String` | - = help: the trait `Copy` is implemented for `Foo<T>` - = note: the `Copy` trait is required because the repeated element will be copied +note: required because of the requirements on the impl of `Copy` for `Foo<String>` + --> $DIR/trait-error.rs:1:10 + | +LL | #[derive(Copy, Clone)] + | ^^^^ + = note: the `Copy` trait is required because this value will be copied for each element of the array + = help: consider creating a new `const` item and initializing it with the result of the function call to be used in the repeat position, like `const VAL: Type = const_fn();` and `let x = [VAL; 42];` + = help: create an inline `const` block, see RFC #2920 <https://github.com/rust-lang/rfcs/pull/2920> for more information + = note: this error originates in the derive macro `Copy` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/consts/const-eval/issue-50814-2.stderr b/src/test/ui/consts/const-eval/issue-50814-2.stderr index d34ac773da2..298f0a4a446 100644 --- a/src/test/ui/consts/const-eval/issue-50814-2.stderr +++ b/src/test/ui/consts/const-eval/issue-50814-2.stderr @@ -16,6 +16,12 @@ error[E0080]: evaluation of `foo::<()>` failed LL | &<A<T> as Foo<T>>::BAR | ^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors +note: the above error was encountered while instantiating `fn foo::<()>` + --> $DIR/issue-50814-2.rs:31:22 + | +LL | println!("{:x}", foo::<()>() as *const usize as usize); + | ^^^^^^^^^^^ + error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0080`. diff --git a/src/test/ui/consts/const-eval/issue-50814.stderr b/src/test/ui/consts/const-eval/issue-50814.stderr index dd8d6bf839a..87bea28e763 100644 --- a/src/test/ui/consts/const-eval/issue-50814.stderr +++ b/src/test/ui/consts/const-eval/issue-50814.stderr @@ -16,6 +16,12 @@ error[E0080]: evaluation of `foo::<i32>` failed LL | &Sum::<U8,U8>::MAX | ^^^^^^^^^^^^^^^^^ referenced constant has errors +note: the above error was encountered while instantiating `fn foo::<i32>` + --> $DIR/issue-50814.rs:26:5 + | +LL | foo(0); + | ^^^^^^ + error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0080`. diff --git a/src/test/ui/consts/const-eval/ub-enum.32bit.stderr b/src/test/ui/consts/const-eval/ub-enum.32bit.stderr index 111d243959a..b60bac541f4 100644 --- a/src/test/ui/consts/const-eval/ub-enum.32bit.stderr +++ b/src/test/ui/consts/const-eval/ub-enum.32bit.stderr @@ -119,27 +119,17 @@ LL | const BAD_OPTION_CHAR: Option<(char, char)> = Some(('x', unsafe { mem::tran 78 00 00 00 ff ff ff ff │ x....... } -error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-enum.rs:92:1 +error[E0080]: evaluation of constant value failed + --> $DIR/ub-enum.rs:92:77 | LL | const BAD_UNINHABITED_WITH_DATA1: Result<(i32, Never), (i32, !)> = unsafe { mem::transmute(0u64) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed at .<enum-variant(Ok)>.0.1: encountered a value of uninhabited type Never - | - = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. - = note: the raw bytes of the constant (size: 8, align: 4) { - 00 00 00 00 00 00 00 00 │ ........ - } + | ^^^^^^^^^^^^^^^^^^^^ transmuting to uninhabited type -error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-enum.rs:94:1 +error[E0080]: evaluation of constant value failed + --> $DIR/ub-enum.rs:94:77 | LL | const BAD_UNINHABITED_WITH_DATA2: Result<(i32, !), (i32, Never)> = unsafe { mem::transmute(0u64) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed at .<enum-variant(Ok)>.0.1: encountered a value of the never type `!` - | - = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. - = note: the raw bytes of the constant (size: 8, align: 4) { - 00 00 00 00 00 00 00 00 │ ........ - } + | ^^^^^^^^^^^^^^^^^^^^ transmuting to uninhabited type error: aborting due to 13 previous errors diff --git a/src/test/ui/consts/const-eval/ub-enum.64bit.stderr b/src/test/ui/consts/const-eval/ub-enum.64bit.stderr index eee132bae00..1d81e2b3eed 100644 --- a/src/test/ui/consts/const-eval/ub-enum.64bit.stderr +++ b/src/test/ui/consts/const-eval/ub-enum.64bit.stderr @@ -119,27 +119,17 @@ LL | const BAD_OPTION_CHAR: Option<(char, char)> = Some(('x', unsafe { mem::tran 78 00 00 00 ff ff ff ff │ x....... } -error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-enum.rs:92:1 +error[E0080]: evaluation of constant value failed + --> $DIR/ub-enum.rs:92:77 | LL | const BAD_UNINHABITED_WITH_DATA1: Result<(i32, Never), (i32, !)> = unsafe { mem::transmute(0u64) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed at .<enum-variant(Ok)>.0.1: encountered a value of uninhabited type Never - | - = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. - = note: the raw bytes of the constant (size: 8, align: 4) { - 00 00 00 00 00 00 00 00 │ ........ - } + | ^^^^^^^^^^^^^^^^^^^^ transmuting to uninhabited type -error[E0080]: it is undefined behavior to use this value - --> $DIR/ub-enum.rs:94:1 +error[E0080]: evaluation of constant value failed + --> $DIR/ub-enum.rs:94:77 | LL | const BAD_UNINHABITED_WITH_DATA2: Result<(i32, !), (i32, Never)> = unsafe { mem::transmute(0u64) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed at .<enum-variant(Ok)>.0.1: encountered a value of the never type `!` - | - = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. - = note: the raw bytes of the constant (size: 8, align: 4) { - 00 00 00 00 00 00 00 00 │ ........ - } + | ^^^^^^^^^^^^^^^^^^^^ transmuting to uninhabited type error: aborting due to 13 previous errors diff --git a/src/test/ui/consts/const-eval/ub-enum.rs b/src/test/ui/consts/const-eval/ub-enum.rs index e408d8ec072..86288685303 100644 --- a/src/test/ui/consts/const-eval/ub-enum.rs +++ b/src/test/ui/consts/const-eval/ub-enum.rs @@ -90,9 +90,9 @@ const BAD_OPTION_CHAR: Option<(char, char)> = Some(('x', unsafe { mem::transmute // All variants are uninhabited but also have data. // Use `0` as constant to make behavior endianess-independent. const BAD_UNINHABITED_WITH_DATA1: Result<(i32, Never), (i32, !)> = unsafe { mem::transmute(0u64) }; -//~^ ERROR is undefined behavior +//~^ ERROR evaluation of constant value failed const BAD_UNINHABITED_WITH_DATA2: Result<(i32, !), (i32, Never)> = unsafe { mem::transmute(0u64) }; -//~^ ERROR is undefined behavior +//~^ ERROR evaluation of constant value failed fn main() { } diff --git a/src/test/ui/consts/const-eval/validate_uninhabited_zsts.32bit.stderr b/src/test/ui/consts/const-eval/validate_uninhabited_zsts.32bit.stderr index 7dc1ec865af..65ab1b02b35 100644 --- a/src/test/ui/consts/const-eval/validate_uninhabited_zsts.32bit.stderr +++ b/src/test/ui/consts/const-eval/validate_uninhabited_zsts.32bit.stderr @@ -7,14 +7,14 @@ LL | unsafe { std::mem::transmute(()) } | transmuting to uninhabited type | inside `foo` at $DIR/validate_uninhabited_zsts.rs:4:14 ... -LL | const FOO: [Empty; 3] = [foo(); 3]; - | ----- inside `FOO` at $DIR/validate_uninhabited_zsts.rs:13:26 +LL | const FOO: [empty::Empty; 3] = [foo(); 3]; + | ----- inside `FOO` at $DIR/validate_uninhabited_zsts.rs:20:33 error[E0080]: it is undefined behavior to use this value - --> $DIR/validate_uninhabited_zsts.rs:16:1 + --> $DIR/validate_uninhabited_zsts.rs:23:1 | -LL | const BAR: [Empty; 3] = [unsafe { std::mem::transmute(()) }; 3]; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed at [0]: encountered a value of uninhabited type Empty +LL | const BAR: [empty::Empty; 3] = [unsafe { std::mem::transmute(()) }; 3]; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed at [0].0: encountered a value of uninhabited type empty::Void | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. = note: the raw bytes of the constant (size: 0, align: 1) {} @@ -31,16 +31,20 @@ LL | unsafe { std::mem::transmute(()) } = note: `#[warn(invalid_value)]` on by default = note: the `!` type has no valid value -warning: the type `Empty` does not permit zero-initialization - --> $DIR/validate_uninhabited_zsts.rs:16:35 +warning: the type `empty::Empty` does not permit zero-initialization + --> $DIR/validate_uninhabited_zsts.rs:23:42 | -LL | const BAR: [Empty; 3] = [unsafe { std::mem::transmute(()) }; 3]; - | ^^^^^^^^^^^^^^^^^^^^^^^ - | | - | this code causes undefined behavior when executed - | help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done +LL | const BAR: [empty::Empty; 3] = [unsafe { std::mem::transmute(()) }; 3]; + | ^^^^^^^^^^^^^^^^^^^^^^^ + | | + | this code causes undefined behavior when executed + | help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done | - = note: enums with no variants have no valid value +note: enums with no variants have no valid value (in this struct field) + --> $DIR/validate_uninhabited_zsts.rs:16:22 + | +LL | pub struct Empty(Void); + | ^^^^ error: aborting due to 2 previous errors; 2 warnings emitted diff --git a/src/test/ui/consts/const-eval/validate_uninhabited_zsts.64bit.stderr b/src/test/ui/consts/const-eval/validate_uninhabited_zsts.64bit.stderr index 7dc1ec865af..65ab1b02b35 100644 --- a/src/test/ui/consts/const-eval/validate_uninhabited_zsts.64bit.stderr +++ b/src/test/ui/consts/const-eval/validate_uninhabited_zsts.64bit.stderr @@ -7,14 +7,14 @@ LL | unsafe { std::mem::transmute(()) } | transmuting to uninhabited type | inside `foo` at $DIR/validate_uninhabited_zsts.rs:4:14 ... -LL | const FOO: [Empty; 3] = [foo(); 3]; - | ----- inside `FOO` at $DIR/validate_uninhabited_zsts.rs:13:26 +LL | const FOO: [empty::Empty; 3] = [foo(); 3]; + | ----- inside `FOO` at $DIR/validate_uninhabited_zsts.rs:20:33 error[E0080]: it is undefined behavior to use this value - --> $DIR/validate_uninhabited_zsts.rs:16:1 + --> $DIR/validate_uninhabited_zsts.rs:23:1 | -LL | const BAR: [Empty; 3] = [unsafe { std::mem::transmute(()) }; 3]; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed at [0]: encountered a value of uninhabited type Empty +LL | const BAR: [empty::Empty; 3] = [unsafe { std::mem::transmute(()) }; 3]; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed at [0].0: encountered a value of uninhabited type empty::Void | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. = note: the raw bytes of the constant (size: 0, align: 1) {} @@ -31,16 +31,20 @@ LL | unsafe { std::mem::transmute(()) } = note: `#[warn(invalid_value)]` on by default = note: the `!` type has no valid value -warning: the type `Empty` does not permit zero-initialization - --> $DIR/validate_uninhabited_zsts.rs:16:35 +warning: the type `empty::Empty` does not permit zero-initialization + --> $DIR/validate_uninhabited_zsts.rs:23:42 | -LL | const BAR: [Empty; 3] = [unsafe { std::mem::transmute(()) }; 3]; - | ^^^^^^^^^^^^^^^^^^^^^^^ - | | - | this code causes undefined behavior when executed - | help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done +LL | const BAR: [empty::Empty; 3] = [unsafe { std::mem::transmute(()) }; 3]; + | ^^^^^^^^^^^^^^^^^^^^^^^ + | | + | this code causes undefined behavior when executed + | help: use `MaybeUninit<T>` instead, and only call `assume_init` after initialization is done | - = note: enums with no variants have no valid value +note: enums with no variants have no valid value (in this struct field) + --> $DIR/validate_uninhabited_zsts.rs:16:22 + | +LL | pub struct Empty(Void); + | ^^^^ error: aborting due to 2 previous errors; 2 warnings emitted diff --git a/src/test/ui/consts/const-eval/validate_uninhabited_zsts.rs b/src/test/ui/consts/const-eval/validate_uninhabited_zsts.rs index 34650484556..96f33127582 100644 --- a/src/test/ui/consts/const-eval/validate_uninhabited_zsts.rs +++ b/src/test/ui/consts/const-eval/validate_uninhabited_zsts.rs @@ -6,16 +6,23 @@ const fn foo() -> ! { //~| WARN the type `!` does not permit zero-initialization [invalid_value] } -#[derive(Clone, Copy)] -enum Empty { } +// Type defined in a submodule, so that it is not "visibly" +// uninhabited (which would change interpreter behavior). +pub mod empty { + #[derive(Clone, Copy)] + enum Void {} + + #[derive(Clone, Copy)] + pub struct Empty(Void); +} #[warn(const_err)] -const FOO: [Empty; 3] = [foo(); 3]; +const FOO: [empty::Empty; 3] = [foo(); 3]; #[warn(const_err)] -const BAR: [Empty; 3] = [unsafe { std::mem::transmute(()) }; 3]; +const BAR: [empty::Empty; 3] = [unsafe { std::mem::transmute(()) }; 3]; //~^ ERROR it is undefined behavior to use this value -//~| WARN the type `Empty` does not permit zero-initialization +//~| WARN the type `empty::Empty` does not permit zero-initialization fn main() { FOO; diff --git a/src/test/ui/consts/const-extern-fn/const-extern-fn-requires-unsafe.mir.stderr b/src/test/ui/consts/const-extern-fn/const-extern-fn-requires-unsafe.mir.stderr index 33014a1500c..4cd0fd2eaf7 100644 --- a/src/test/ui/consts/const-extern-fn/const-extern-fn-requires-unsafe.mir.stderr +++ b/src/test/ui/consts/const-extern-fn/const-extern-fn-requires-unsafe.mir.stderr @@ -7,7 +7,7 @@ LL | let a: [u8; foo()]; = note: consult the function's documentation for information on how to avoid undefined behavior error[E0133]: call to unsafe function is unsafe and requires unsafe function or block - --> $DIR/const-extern-fn-requires-unsafe.rs:11:5 + --> $DIR/const-extern-fn-requires-unsafe.rs:12:5 | LL | foo(); | ^^^^^ call to unsafe function diff --git a/src/test/ui/consts/const-extern-fn/const-extern-fn-requires-unsafe.rs b/src/test/ui/consts/const-extern-fn/const-extern-fn-requires-unsafe.rs index 031e67a1e3c..afe645ae881 100644 --- a/src/test/ui/consts/const-extern-fn/const-extern-fn-requires-unsafe.rs +++ b/src/test/ui/consts/const-extern-fn/const-extern-fn-requires-unsafe.rs @@ -7,7 +7,8 @@ const unsafe extern "C" fn foo() -> usize { 5 } fn main() { let a: [u8; foo()]; - //~^ ERROR call to unsafe function is unsafe and requires unsafe function or block + //[mir]~^ call to unsafe function is unsafe and requires unsafe function or block + //[thir]~^^ call to unsafe function `foo` is unsafe and requires unsafe function or block foo(); //[mir]~^ ERROR call to unsafe function is unsafe and requires unsafe function or block } diff --git a/src/test/ui/consts/const-extern-fn/const-extern-fn-requires-unsafe.thir.stderr b/src/test/ui/consts/const-extern-fn/const-extern-fn-requires-unsafe.thir.stderr index c6077da768b..b313f06539f 100644 --- a/src/test/ui/consts/const-extern-fn/const-extern-fn-requires-unsafe.thir.stderr +++ b/src/test/ui/consts/const-extern-fn/const-extern-fn-requires-unsafe.thir.stderr @@ -1,4 +1,4 @@ -error[E0133]: call to unsafe function is unsafe and requires unsafe function or block +error[E0133]: call to unsafe function `foo` is unsafe and requires unsafe function or block --> $DIR/const-extern-fn-requires-unsafe.rs:9:17 | LL | let a: [u8; foo()]; diff --git a/src/test/ui/consts/const-float-bits-conv.rs b/src/test/ui/consts/const-float-bits-conv.rs index c857ad6df2d..310db2174aa 100644 --- a/src/test/ui/consts/const-float-bits-conv.rs +++ b/src/test/ui/consts/const-float-bits-conv.rs @@ -37,22 +37,6 @@ fn f32() { const_assert!(f32::from_bits(0x44a72000), 1337.0); const_assert!(f32::from_ne_bytes(0x44a72000u32.to_ne_bytes()), 1337.0); const_assert!(f32::from_bits(0xc1640000), -14.25); - - // Check that NaNs roundtrip their bits regardless of signalingness - // 0xA is 0b1010; 0x5 is 0b0101 -- so these two together clobbers all the mantissa bits - const MASKED_NAN1: u32 = f32::NAN.to_bits() ^ 0x002A_AAAA; - const MASKED_NAN2: u32 = f32::NAN.to_bits() ^ 0x0055_5555; - - const_assert!(f32::from_bits(MASKED_NAN1).is_nan()); - const_assert!(f32::from_bits(MASKED_NAN1).is_nan()); - - // LLVM does not guarantee that loads and stores of NaNs preserve their exact bit pattern. - // In practice, this seems to only cause a problem on x86, since the most widely used calling - // convention mandates that floating point values are returned on the x87 FPU stack. See #73328. - if !cfg!(target_arch = "x86") { - const_assert!(f32::from_bits(MASKED_NAN1).to_bits(), MASKED_NAN1); - const_assert!(f32::from_bits(MASKED_NAN2).to_bits(), MASKED_NAN2); - } } fn f64() { @@ -70,20 +54,6 @@ fn f64() { const_assert!(f64::from_bits(0x4094e40000000000), 1337.0); const_assert!(f64::from_ne_bytes(0x4094e40000000000u64.to_ne_bytes()), 1337.0); const_assert!(f64::from_bits(0xc02c800000000000), -14.25); - - // Check that NaNs roundtrip their bits regardless of signalingness - // 0xA is 0b1010; 0x5 is 0b0101 -- so these two together clobbers all the mantissa bits - const MASKED_NAN1: u64 = f64::NAN.to_bits() ^ 0x000A_AAAA_AAAA_AAAA; - const MASKED_NAN2: u64 = f64::NAN.to_bits() ^ 0x0005_5555_5555_5555; - - const_assert!(f64::from_bits(MASKED_NAN1).is_nan()); - const_assert!(f64::from_bits(MASKED_NAN1).is_nan()); - - // See comment above. - if !cfg!(target_arch = "x86") { - const_assert!(f64::from_bits(MASKED_NAN1).to_bits(), MASKED_NAN1); - const_assert!(f64::from_bits(MASKED_NAN2).to_bits(), MASKED_NAN2); - } } fn main() { diff --git a/src/test/ui/consts/const-float-bits-reject-conv.rs b/src/test/ui/consts/const-float-bits-reject-conv.rs new file mode 100644 index 00000000000..122f5b97eee --- /dev/null +++ b/src/test/ui/consts/const-float-bits-reject-conv.rs @@ -0,0 +1,62 @@ +// compile-flags: -Zmir-opt-level=0 +#![feature(const_float_bits_conv)] +#![feature(const_float_classify)] + +// Don't promote +const fn nop<T>(x: T) -> T { x } + +macro_rules! const_assert { + ($a:expr) => { + { + const _: () = assert!($a); + assert!(nop($a)); + } + }; + ($a:expr, $b:expr) => { + { + const _: () = assert!($a == $b); + assert_eq!(nop($a), nop($b)); + } + }; +} + +fn f32() { + // Check that NaNs roundtrip their bits regardless of signalingness + // 0xA is 0b1010; 0x5 is 0b0101 -- so these two together clobbers all the mantissa bits + // ...actually, let's just check that these break. :D + const MASKED_NAN1: u32 = f32::NAN.to_bits() ^ 0x002A_AAAA; + const MASKED_NAN2: u32 = f32::NAN.to_bits() ^ 0x0055_5555; + + const_assert!(f32::from_bits(MASKED_NAN1).is_nan()); + const_assert!(f32::from_bits(MASKED_NAN1).is_nan()); + + // LLVM does not guarantee that loads and stores of NaNs preserve their exact bit pattern. + // In practice, this seems to only cause a problem on x86, since the most widely used calling + // convention mandates that floating point values are returned on the x87 FPU stack. See #73328. + if !cfg!(target_arch = "x86") { + const_assert!(f32::from_bits(MASKED_NAN1).to_bits(), MASKED_NAN1); + const_assert!(f32::from_bits(MASKED_NAN2).to_bits(), MASKED_NAN2); + } +} + +fn f64() { + // Check that NaNs roundtrip their bits regardless of signalingness + // 0xA is 0b1010; 0x5 is 0b0101 -- so these two together clobbers all the mantissa bits + // ...actually, let's just check that these break. :D + const MASKED_NAN1: u64 = f64::NAN.to_bits() ^ 0x000A_AAAA_AAAA_AAAA; + const MASKED_NAN2: u64 = f64::NAN.to_bits() ^ 0x0005_5555_5555_5555; + + const_assert!(f64::from_bits(MASKED_NAN1).is_nan()); + const_assert!(f64::from_bits(MASKED_NAN1).is_nan()); + + // See comment above. + if !cfg!(target_arch = "x86") { + const_assert!(f64::from_bits(MASKED_NAN1).to_bits(), MASKED_NAN1); + const_assert!(f64::from_bits(MASKED_NAN2).to_bits(), MASKED_NAN2); + } +} + +fn main() { + f32(); + f64(); +} diff --git a/src/test/ui/consts/const-float-bits-reject-conv.stderr b/src/test/ui/consts/const-float-bits-reject-conv.stderr new file mode 100644 index 00000000000..b39e8819701 --- /dev/null +++ b/src/test/ui/consts/const-float-bits-reject-conv.stderr @@ -0,0 +1,119 @@ +error[E0080]: evaluation of constant value failed + --> $SRC_DIR/core/src/num/f32.rs:LL:COL + | +LL | panic!("const-eval error: cannot use f32::to_bits on a NaN") + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | the evaluated program panicked at 'const-eval error: cannot use f32::to_bits on a NaN', $SRC_DIR/core/src/num/f32.rs:LL:COL + | inside `core::f32::<impl f32>::to_bits::ct_f32_to_u32` at $SRC_DIR/core/src/panic.rs:LL:COL +... +LL | unsafe { intrinsics::const_eval_select((self,), ct_f32_to_u32, rt_f32_to_u32) } + | -------------------------------------------------------------------- inside `core::f32::<impl f32>::to_bits` at $SRC_DIR/core/src/num/f32.rs:LL:COL + | + ::: $SRC_DIR/core/src/ops/function.rs:LL:COL + | +LL | extern "rust-call" fn call_once(self, args: Args) -> Self::Output; + | ------------------------------------------------------------------ inside `<fn(f32) -> u32 {core::f32::<impl f32>::to_bits::ct_f32_to_u32} as FnOnce<(f32,)>>::call_once - shim(fn(f32) -> u32 {core::f32::<impl f32>::to_bits::ct_f32_to_u32})` at $SRC_DIR/core/src/ops/function.rs:LL:COL + | + ::: $SRC_DIR/core/src/intrinsics.rs:LL:COL + | +LL | called_in_const.call_once(arg) + | ------------------------------ inside `const_eval_select::<(f32,), fn(f32) -> u32 {core::f32::<impl f32>::to_bits::ct_f32_to_u32}, [closure@core::f32::<impl f32>::to_bits::{closure#0}], u32>` at $SRC_DIR/core/src/intrinsics.rs:LL:COL + | + ::: $DIR/const-float-bits-reject-conv.rs:27:30 + | +LL | const MASKED_NAN1: u32 = f32::NAN.to_bits() ^ 0x002A_AAAA; + | ------------------ inside `f32::MASKED_NAN1` at $DIR/const-float-bits-reject-conv.rs:27:30 + | + = note: this error originates in the macro `$crate::panic::panic_2021` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0080]: evaluation of constant value failed + --> $SRC_DIR/core/src/num/f32.rs:LL:COL + | +LL | panic!("const-eval error: cannot use f32::to_bits on a NaN") + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | the evaluated program panicked at 'const-eval error: cannot use f32::to_bits on a NaN', $SRC_DIR/core/src/num/f32.rs:LL:COL + | inside `core::f32::<impl f32>::to_bits::ct_f32_to_u32` at $SRC_DIR/core/src/panic.rs:LL:COL +... +LL | unsafe { intrinsics::const_eval_select((self,), ct_f32_to_u32, rt_f32_to_u32) } + | -------------------------------------------------------------------- inside `core::f32::<impl f32>::to_bits` at $SRC_DIR/core/src/num/f32.rs:LL:COL + | + ::: $SRC_DIR/core/src/ops/function.rs:LL:COL + | +LL | extern "rust-call" fn call_once(self, args: Args) -> Self::Output; + | ------------------------------------------------------------------ inside `<fn(f32) -> u32 {core::f32::<impl f32>::to_bits::ct_f32_to_u32} as FnOnce<(f32,)>>::call_once - shim(fn(f32) -> u32 {core::f32::<impl f32>::to_bits::ct_f32_to_u32})` at $SRC_DIR/core/src/ops/function.rs:LL:COL + | + ::: $SRC_DIR/core/src/intrinsics.rs:LL:COL + | +LL | called_in_const.call_once(arg) + | ------------------------------ inside `const_eval_select::<(f32,), fn(f32) -> u32 {core::f32::<impl f32>::to_bits::ct_f32_to_u32}, [closure@core::f32::<impl f32>::to_bits::{closure#0}], u32>` at $SRC_DIR/core/src/intrinsics.rs:LL:COL + | + ::: $DIR/const-float-bits-reject-conv.rs:28:30 + | +LL | const MASKED_NAN2: u32 = f32::NAN.to_bits() ^ 0x0055_5555; + | ------------------ inside `f32::MASKED_NAN2` at $DIR/const-float-bits-reject-conv.rs:28:30 + | + = note: this error originates in the macro `$crate::panic::panic_2021` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0080]: evaluation of constant value failed + --> $SRC_DIR/core/src/num/f64.rs:LL:COL + | +LL | panic!("const-eval error: cannot use f64::to_bits on a NaN") + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | the evaluated program panicked at 'const-eval error: cannot use f64::to_bits on a NaN', $SRC_DIR/core/src/num/f64.rs:LL:COL + | inside `core::f64::<impl f64>::to_bits::ct_f64_to_u64` at $SRC_DIR/core/src/panic.rs:LL:COL +... +LL | unsafe { intrinsics::const_eval_select((self,), ct_f64_to_u64, rt_f64_to_u64) } + | -------------------------------------------------------------------- inside `core::f64::<impl f64>::to_bits` at $SRC_DIR/core/src/num/f64.rs:LL:COL + | + ::: $SRC_DIR/core/src/ops/function.rs:LL:COL + | +LL | extern "rust-call" fn call_once(self, args: Args) -> Self::Output; + | ------------------------------------------------------------------ inside `<fn(f64) -> u64 {core::f64::<impl f64>::to_bits::ct_f64_to_u64} as FnOnce<(f64,)>>::call_once - shim(fn(f64) -> u64 {core::f64::<impl f64>::to_bits::ct_f64_to_u64})` at $SRC_DIR/core/src/ops/function.rs:LL:COL + | + ::: $SRC_DIR/core/src/intrinsics.rs:LL:COL + | +LL | called_in_const.call_once(arg) + | ------------------------------ inside `const_eval_select::<(f64,), fn(f64) -> u64 {core::f64::<impl f64>::to_bits::ct_f64_to_u64}, [closure@core::f64::<impl f64>::to_bits::{closure#0}], u64>` at $SRC_DIR/core/src/intrinsics.rs:LL:COL + | + ::: $DIR/const-float-bits-reject-conv.rs:46:30 + | +LL | const MASKED_NAN1: u64 = f64::NAN.to_bits() ^ 0x000A_AAAA_AAAA_AAAA; + | ------------------ inside `f64::MASKED_NAN1` at $DIR/const-float-bits-reject-conv.rs:46:30 + | + = note: this error originates in the macro `$crate::panic::panic_2021` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0080]: evaluation of constant value failed + --> $SRC_DIR/core/src/num/f64.rs:LL:COL + | +LL | panic!("const-eval error: cannot use f64::to_bits on a NaN") + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | the evaluated program panicked at 'const-eval error: cannot use f64::to_bits on a NaN', $SRC_DIR/core/src/num/f64.rs:LL:COL + | inside `core::f64::<impl f64>::to_bits::ct_f64_to_u64` at $SRC_DIR/core/src/panic.rs:LL:COL +... +LL | unsafe { intrinsics::const_eval_select((self,), ct_f64_to_u64, rt_f64_to_u64) } + | -------------------------------------------------------------------- inside `core::f64::<impl f64>::to_bits` at $SRC_DIR/core/src/num/f64.rs:LL:COL + | + ::: $SRC_DIR/core/src/ops/function.rs:LL:COL + | +LL | extern "rust-call" fn call_once(self, args: Args) -> Self::Output; + | ------------------------------------------------------------------ inside `<fn(f64) -> u64 {core::f64::<impl f64>::to_bits::ct_f64_to_u64} as FnOnce<(f64,)>>::call_once - shim(fn(f64) -> u64 {core::f64::<impl f64>::to_bits::ct_f64_to_u64})` at $SRC_DIR/core/src/ops/function.rs:LL:COL + | + ::: $SRC_DIR/core/src/intrinsics.rs:LL:COL + | +LL | called_in_const.call_once(arg) + | ------------------------------ inside `const_eval_select::<(f64,), fn(f64) -> u64 {core::f64::<impl f64>::to_bits::ct_f64_to_u64}, [closure@core::f64::<impl f64>::to_bits::{closure#0}], u64>` at $SRC_DIR/core/src/intrinsics.rs:LL:COL + | + ::: $DIR/const-float-bits-reject-conv.rs:47:30 + | +LL | const MASKED_NAN2: u64 = f64::NAN.to_bits() ^ 0x0005_5555_5555_5555; + | ------------------ inside `f64::MASKED_NAN2` at $DIR/const-float-bits-reject-conv.rs:47:30 + | + = note: this error originates in the macro `$crate::panic::panic_2021` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0080`. diff --git a/src/test/ui/consts/const-fn-error.stderr b/src/test/ui/consts/const-fn-error.stderr index 4d53cfc35e1..e36324f0b3e 100644 --- a/src/test/ui/consts/const-fn-error.stderr +++ b/src/test/ui/consts/const-fn-error.stderr @@ -22,8 +22,8 @@ LL | for i in 0..x { note: impl defined here, but it is not `const` --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL | -LL | impl<I: Iterator> IntoIterator for I { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | impl<I: ~const Iterator> const IntoIterator for I { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants error[E0658]: mutable references are not allowed in constant functions diff --git a/src/test/ui/consts/const-fn-in-vec.stderr b/src/test/ui/consts/const-fn-in-vec.stderr index f02cb4f1ff1..9eb7524b504 100644 --- a/src/test/ui/consts/const-fn-in-vec.stderr +++ b/src/test/ui/consts/const-fn-in-vec.stderr @@ -1,10 +1,10 @@ error[E0277]: the trait bound `String: Copy` is not satisfied - --> $DIR/const-fn-in-vec.rs:4:32 + --> $DIR/const-fn-in-vec.rs:4:33 | LL | let strings: [String; 5] = [String::new(); 5]; - | ^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `String` + | ^^^^^^^^^^^^^ the trait `Copy` is not implemented for `String` | - = note: the `Copy` trait is required because the repeated element will be copied + = note: the `Copy` trait is required because this value will be copied for each element of the array = help: consider creating a new `const` item and initializing it with the result of the function call to be used in the repeat position, like `const VAL: Type = const_fn();` and `let x = [VAL; 42];` = help: create an inline `const` block, see RFC #2920 <https://github.com/rust-lang/rfcs/pull/2920> for more information diff --git a/src/test/ui/consts/const-for.stderr b/src/test/ui/consts/const-for.stderr index b0dc43eb8e8..f2e1c8a4991 100644 --- a/src/test/ui/consts/const-for.stderr +++ b/src/test/ui/consts/const-for.stderr @@ -7,8 +7,8 @@ LL | for _ in 0..5 {} note: impl defined here, but it is not `const` --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL | -LL | impl<I: Iterator> IntoIterator for I { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | impl<I: ~const Iterator> const IntoIterator for I { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: calls in constants are limited to constant functions, tuple structs and tuple variants error[E0015]: cannot call non-const fn `<std::ops::Range<i32> as Iterator>::next` in constants diff --git a/src/test/ui/issues/issue-19244.rs b/src/test/ui/consts/issue-19244.rs index 44d9748fd2a..44d9748fd2a 100644 --- a/src/test/ui/issues/issue-19244.rs +++ b/src/test/ui/consts/issue-19244.rs diff --git a/src/test/ui/did_you_mean/replace-impl-infer-ty-from-trait.fixed b/src/test/ui/did_you_mean/replace-impl-infer-ty-from-trait.fixed new file mode 100644 index 00000000000..4963790c35d --- /dev/null +++ b/src/test/ui/did_you_mean/replace-impl-infer-ty-from-trait.fixed @@ -0,0 +1,15 @@ +// run-rustfix +#![allow(unused)] + +trait Foo<T>: Sized { + fn bar(i: i32, t: T, s: &Self) -> (T, i32); +} + +impl Foo<usize> for () { + fn bar(i: i32, t: usize, s: &()) -> (usize, i32) { + //~^ ERROR the placeholder `_` is not allowed within types on item signatures for functions + (1, 2) + } +} + +fn main() {} diff --git a/src/test/ui/did_you_mean/replace-impl-infer-ty-from-trait.rs b/src/test/ui/did_you_mean/replace-impl-infer-ty-from-trait.rs new file mode 100644 index 00000000000..ddf39c9c861 --- /dev/null +++ b/src/test/ui/did_you_mean/replace-impl-infer-ty-from-trait.rs @@ -0,0 +1,15 @@ +// run-rustfix +#![allow(unused)] + +trait Foo<T>: Sized { + fn bar(i: i32, t: T, s: &Self) -> (T, i32); +} + +impl Foo<usize> for () { + fn bar(i: _, t: _, s: _) -> _ { + //~^ ERROR the placeholder `_` is not allowed within types on item signatures for functions + (1, 2) + } +} + +fn main() {} diff --git a/src/test/ui/did_you_mean/replace-impl-infer-ty-from-trait.stderr b/src/test/ui/did_you_mean/replace-impl-infer-ty-from-trait.stderr new file mode 100644 index 00000000000..730836a40c2 --- /dev/null +++ b/src/test/ui/did_you_mean/replace-impl-infer-ty-from-trait.stderr @@ -0,0 +1,18 @@ +error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions + --> $DIR/replace-impl-infer-ty-from-trait.rs:9:15 + | +LL | fn bar(i: _, t: _, s: _) -> _ { + | ^ ^ ^ ^ not allowed in type signatures + | | | | + | | | not allowed in type signatures + | | not allowed in type signatures + | not allowed in type signatures + | +help: try replacing `_` with the types in the corresponding trait method signature + | +LL | fn bar(i: i32, t: usize, s: &()) -> (usize, i32) { + | ~~~ ~~~~~ ~~~ ~~~~~~~~~~~~ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0121`. diff --git a/src/test/ui/error-codes/E0117.stderr b/src/test/ui/error-codes/E0117.stderr index cdbafff2a20..76d9f5cc0e5 100644 --- a/src/test/ui/error-codes/E0117.stderr +++ b/src/test/ui/error-codes/E0117.stderr @@ -1,4 +1,4 @@ -error[E0117]: only traits defined in the current crate can be implemented for arbitrary types +error[E0117]: only traits defined in the current crate can be implemented for primitive types --> $DIR/E0117.rs:1:1 | LL | impl Drop for u32 {} diff --git a/src/test/ui/error-codes/E0133.thir.stderr b/src/test/ui/error-codes/E0133.thir.stderr index b11d5e2c2fc..f1d7aba2aa3 100644 --- a/src/test/ui/error-codes/E0133.thir.stderr +++ b/src/test/ui/error-codes/E0133.thir.stderr @@ -1,4 +1,4 @@ -error[E0133]: call to unsafe function is unsafe and requires unsafe function or block +error[E0133]: call to unsafe function `f` is unsafe and requires unsafe function or block --> $DIR/E0133.rs:7:5 | LL | f(); diff --git a/src/test/ui/error-codes/E0283.stderr b/src/test/ui/error-codes/E0283.stderr index 7dcfe96b35c..e2bab486064 100644 --- a/src/test/ui/error-codes/E0283.stderr +++ b/src/test/ui/error-codes/E0283.stderr @@ -14,7 +14,6 @@ LL | let bar = foo_impl.into() * 1u32; | | | | | cannot infer type for type parameter `T` declared on the trait `Into` | this method call resolves to `T` - | help: use the fully qualified path for the potential candidate: `<Impl as Into<u32>>::into(foo_impl)` | note: multiple `impl`s satisfying `Impl: Into<_>` found --> $DIR/E0283.rs:17:1 @@ -24,6 +23,10 @@ LL | impl Into<u32> for Impl { = note: and another `impl` found in the `core` crate: - impl<T, U> Into<U> for T where U: From<T>; +help: use the fully qualified path for the potential candidate + | +LL | let bar = <Impl as Into<u32>>::into(foo_impl) * 1u32; + | ++++++++++++++++++++++++++ ~ error: aborting due to 2 previous errors diff --git a/src/test/ui/error-codes/E0771.stderr b/src/test/ui/error-codes/E0771.stderr index 5a16d5845a6..3ab727f5f69 100644 --- a/src/test/ui/error-codes/E0771.stderr +++ b/src/test/ui/error-codes/E0771.stderr @@ -1,3 +1,11 @@ +error[E0771]: use of non-static lifetime `'a` in const generic + --> $DIR/E0771.rs:4:41 + | +LL | fn function_with_str<'a, const STRING: &'a str>() {} + | ^^ + | + = note: for more information, see issue #74052 <https://github.com/rust-lang/rust/issues/74052> + warning: the feature `adt_const_params` is incomplete and may not be safe to use and/or cause compiler crashes --> $DIR/E0771.rs:1:12 | @@ -7,14 +15,6 @@ LL | #![feature(adt_const_params)] = note: `#[warn(incomplete_features)]` on by default = note: see issue #95174 <https://github.com/rust-lang/rust/issues/95174> for more information -error[E0771]: use of non-static lifetime `'a` in const generic - --> $DIR/E0771.rs:4:41 - | -LL | fn function_with_str<'a, const STRING: &'a str>() {} - | ^^ - | - = note: for more information, see issue #74052 <https://github.com/rust-lang/rust/issues/74052> - error: aborting due to previous error; 1 warning emitted For more information about this error, try `rustc --explain E0771`. diff --git a/src/test/ui/extern-flag/no-nounused.rs b/src/test/ui/extern-flag/no-nounused.rs new file mode 100644 index 00000000000..5ec75595243 --- /dev/null +++ b/src/test/ui/extern-flag/no-nounused.rs @@ -0,0 +1,6 @@ +// aux-crate:somedep=somedep.rs +// compile-flags: -Zunstable-options -Dunused-crate-dependencies +// edition:2018 + +fn main() { //~ ERROR external crate `somedep` unused in `no_nounused` +} diff --git a/src/test/ui/extern-flag/no-nounused.stderr b/src/test/ui/extern-flag/no-nounused.stderr new file mode 100644 index 00000000000..6446c53236c --- /dev/null +++ b/src/test/ui/extern-flag/no-nounused.stderr @@ -0,0 +1,10 @@ +error: external crate `somedep` unused in `no_nounused`: remove the dependency or add `use somedep as _;` + --> $DIR/no-nounused.rs:5:1 + | +LL | fn main() { + | ^ + | + = note: requested on the command line with `-D unused-crate-dependencies` + +error: aborting due to previous error + diff --git a/src/test/ui/extern-flag/nounused.rs b/src/test/ui/extern-flag/nounused.rs new file mode 100644 index 00000000000..2513986bbec --- /dev/null +++ b/src/test/ui/extern-flag/nounused.rs @@ -0,0 +1,7 @@ +// check-pass +// aux-crate:nounused:somedep=somedep.rs +// compile-flags: -Zunstable-options -Dunused-crate-dependencies +// edition:2018 + +fn main() { +} diff --git a/src/test/ui/extern/extern-type-diag-not-similar.rs b/src/test/ui/extern/extern-type-diag-not-similar.rs new file mode 100644 index 00000000000..39d00a6c1bc --- /dev/null +++ b/src/test/ui/extern/extern-type-diag-not-similar.rs @@ -0,0 +1,22 @@ +// We previously mentioned other extern types in the error message here. +// +// Two extern types shouldn't really be considered similar just +// because they are both extern types. + +#![feature(extern_types)] +extern { + type ShouldNotBeMentioned; +} + +extern { + type Foo; +} + +unsafe impl Send for ShouldNotBeMentioned {} + +fn assert_send<T: Send + ?Sized>() {} + +fn main() { + assert_send::<Foo>() + //~^ ERROR `Foo` cannot be sent between threads safely +} diff --git a/src/test/ui/extern/extern-type-diag-not-similar.stderr b/src/test/ui/extern/extern-type-diag-not-similar.stderr new file mode 100644 index 00000000000..75836f7eca1 --- /dev/null +++ b/src/test/ui/extern/extern-type-diag-not-similar.stderr @@ -0,0 +1,16 @@ +error[E0277]: `Foo` cannot be sent between threads safely + --> $DIR/extern-type-diag-not-similar.rs:20:19 + | +LL | assert_send::<Foo>() + | ^^^ `Foo` cannot be sent between threads safely + | + = help: the trait `Send` is not implemented for `Foo` +note: required by a bound in `assert_send` + --> $DIR/extern-type-diag-not-similar.rs:17:19 + | +LL | fn assert_send<T: Send + ?Sized>() {} + | ^^^^ required by this bound in `assert_send` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/feature-gates/feature-gate-infer_static_outlives_requirements.stderr b/src/test/ui/feature-gates/feature-gate-infer_static_outlives_requirements.stderr index 2bccec45894..7ffebab4153 100644 --- a/src/test/ui/feature-gates/feature-gate-infer_static_outlives_requirements.stderr +++ b/src/test/ui/feature-gates/feature-gate-infer_static_outlives_requirements.stderr @@ -1,8 +1,6 @@ error[E0310]: the parameter type `U` may not live long enough --> $DIR/feature-gate-infer_static_outlives_requirements.rs:5:10 | -LL | struct Foo<U> { - | - help: consider adding an explicit lifetime bound...: `U: 'static` LL | bar: Bar<U> | ^^^^^^ ...so that the type `U` will meet its required lifetime bounds... | @@ -11,6 +9,10 @@ note: ...that is required by this bound | LL | struct Bar<T: 'static> { | ^^^^^^^ +help: consider adding an explicit lifetime bound... + | +LL | struct Foo<U: 'static> { + | +++++++++ error: aborting due to previous error diff --git a/src/test/ui/feature-gates/feature-gate-yeet_expr-in-cfg.rs b/src/test/ui/feature-gates/feature-gate-yeet_expr-in-cfg.rs new file mode 100644 index 00000000000..a33bd34508c --- /dev/null +++ b/src/test/ui/feature-gates/feature-gate-yeet_expr-in-cfg.rs @@ -0,0 +1,19 @@ +// compile-flags: --edition 2021 + +pub fn demo() -> Option<i32> { + #[cfg(nope)] + { + do yeet //~ ERROR `do yeet` expression is experimental + } + + Some(1) +} + +#[cfg(nope)] +pub fn alternative() -> Result<(), String> { + do yeet "hello"; //~ ERROR `do yeet` expression is experimental +} + +fn main() { + demo(); +} diff --git a/src/test/ui/feature-gates/feature-gate-yeet_expr-in-cfg.stderr b/src/test/ui/feature-gates/feature-gate-yeet_expr-in-cfg.stderr new file mode 100644 index 00000000000..f90c379bdaf --- /dev/null +++ b/src/test/ui/feature-gates/feature-gate-yeet_expr-in-cfg.stderr @@ -0,0 +1,21 @@ +error[E0658]: `do yeet` expression is experimental + --> $DIR/feature-gate-yeet_expr-in-cfg.rs:6:9 + | +LL | do yeet + | ^^^^^^^ + | + = note: see issue #96373 <https://github.com/rust-lang/rust/issues/96373> for more information + = help: add `#![feature(yeet_expr)]` to the crate attributes to enable + +error[E0658]: `do yeet` expression is experimental + --> $DIR/feature-gate-yeet_expr-in-cfg.rs:14:5 + | +LL | do yeet "hello"; + | ^^^^^^^^^^^^^^^ + | + = note: see issue #96373 <https://github.com/rust-lang/rust/issues/96373> for more information + = help: add `#![feature(yeet_expr)]` to the crate attributes to enable + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gates/feature-gate-yeet_expr.rs b/src/test/ui/feature-gates/feature-gate-yeet_expr.rs new file mode 100644 index 00000000000..978a84cf6e5 --- /dev/null +++ b/src/test/ui/feature-gates/feature-gate-yeet_expr.rs @@ -0,0 +1,9 @@ +// compile-flags: --edition 2018 + +pub fn demo() -> Option<i32> { + do yeet //~ ERROR `do yeet` expression is experimental +} + +pub fn main() -> Result<(), String> { + do yeet "hello"; //~ ERROR `do yeet` expression is experimental +} diff --git a/src/test/ui/feature-gates/feature-gate-yeet_expr.stderr b/src/test/ui/feature-gates/feature-gate-yeet_expr.stderr new file mode 100644 index 00000000000..8d1b92370fb --- /dev/null +++ b/src/test/ui/feature-gates/feature-gate-yeet_expr.stderr @@ -0,0 +1,21 @@ +error[E0658]: `do yeet` expression is experimental + --> $DIR/feature-gate-yeet_expr.rs:4:5 + | +LL | do yeet + | ^^^^^^^ + | + = note: see issue #96373 <https://github.com/rust-lang/rust/issues/96373> for more information + = help: add `#![feature(yeet_expr)]` to the crate attributes to enable + +error[E0658]: `do yeet` expression is experimental + --> $DIR/feature-gate-yeet_expr.rs:8:5 + | +LL | do yeet "hello"; + | ^^^^^^^^^^^^^^^ + | + = note: see issue #96373 <https://github.com/rust-lang/rust/issues/96373> for more information + = help: add `#![feature(yeet_expr)]` to the crate attributes to enable + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/foreign-unsafe-fn-called.rs b/src/test/ui/foreign-unsafe-fn-called.rs index de3de286fc9..67302ea1bcd 100644 --- a/src/test/ui/foreign-unsafe-fn-called.rs +++ b/src/test/ui/foreign-unsafe-fn-called.rs @@ -9,5 +9,6 @@ mod test { fn main() { test::free(); - //~^ ERROR call to unsafe function is unsafe + //[mir]~^ ERROR call to unsafe function is unsafe + //[thir]~^^ ERROR call to unsafe function `test::free` is unsafe } diff --git a/src/test/ui/foreign-unsafe-fn-called.thir.stderr b/src/test/ui/foreign-unsafe-fn-called.thir.stderr index d3cf5d84fdd..00ba0f7a6a3 100644 --- a/src/test/ui/foreign-unsafe-fn-called.thir.stderr +++ b/src/test/ui/foreign-unsafe-fn-called.thir.stderr @@ -1,4 +1,4 @@ -error[E0133]: call to unsafe function is unsafe and requires unsafe function or block +error[E0133]: call to unsafe function `test::free` is unsafe and requires unsafe function or block --> $DIR/foreign-unsafe-fn-called.rs:11:5 | LL | test::free(); diff --git a/src/test/ui/functions-closures/fn-help-with-err.rs b/src/test/ui/functions-closures/fn-help-with-err.rs index f8a81af786f..3d2bcb8ad35 100644 --- a/src/test/ui/functions-closures/fn-help-with-err.rs +++ b/src/test/ui/functions-closures/fn-help-with-err.rs @@ -3,14 +3,14 @@ fn main() { let arc = std::sync::Arc::new(oops); //~^ ERROR cannot find value `oops` in this scope //~| NOTE not found - // The error "note: `arc` is a function, perhaps you wish to call it" MUST NOT appear. + // The error "note: this is a function, perhaps you wish to call it" MUST NOT appear. arc.blablabla(); //~^ ERROR no method named `blablabla` //~| NOTE method not found let arc2 = std::sync::Arc::new(|| 1); - // The error "note: `arc2` is a function, perhaps you wish to call it" SHOULD appear + // The error "note: this is a function, perhaps you wish to call it" SHOULD appear arc2.blablabla(); //~^ ERROR no method named `blablabla` //~| NOTE method not found - //~| NOTE `arc2` is a function, perhaps you wish to call it + //~| NOTE this is a function, perhaps you wish to call it } diff --git a/src/test/ui/functions-closures/fn-help-with-err.stderr b/src/test/ui/functions-closures/fn-help-with-err.stderr index 4d6b3282ad9..3e42cb1fb6e 100644 --- a/src/test/ui/functions-closures/fn-help-with-err.stderr +++ b/src/test/ui/functions-closures/fn-help-with-err.stderr @@ -14,9 +14,9 @@ error[E0599]: no method named `blablabla` found for struct `Arc<[closure@$DIR/fn --> $DIR/fn-help-with-err.rs:12:10 | LL | arc2.blablabla(); - | ^^^^^^^^^ method not found in `Arc<[closure@$DIR/fn-help-with-err.rs:10:36: 10:40]>` - | - = note: `arc2` is a function, perhaps you wish to call it + | ---- ^^^^^^^^^ method not found in `Arc<[closure@$DIR/fn-help-with-err.rs:10:36: 10:40]>` + | | + | this is a function, perhaps you wish to call it error: aborting due to 3 previous errors diff --git a/src/test/ui/generator/issue-88653.rs b/src/test/ui/generator/issue-88653.rs index f27956e4595..caa452060b1 100644 --- a/src/test/ui/generator/issue-88653.rs +++ b/src/test/ui/generator/issue-88653.rs @@ -7,13 +7,10 @@ use std::ops::Generator; fn foo(bar: bool) -> impl Generator<(bool,)> { //~^ ERROR: type mismatch in generator arguments [E0631] - //~| ERROR: type mismatch in generator arguments [E0631] - //~| NOTE: expected signature of `fn((bool,)) -> _` //~| NOTE: expected signature of `fn((bool,)) -> _` //~| NOTE: in this expansion of desugaring of `impl Trait` |bar| { //~^ NOTE: found signature of `fn(bool) -> _` - //~| NOTE: found signature of `fn(bool) -> _` if bar { yield bar; } diff --git a/src/test/ui/generator/issue-88653.stderr b/src/test/ui/generator/issue-88653.stderr index 25357411ce1..5bd8ad129fe 100644 --- a/src/test/ui/generator/issue-88653.stderr +++ b/src/test/ui/generator/issue-88653.stderr @@ -7,22 +7,6 @@ LL | fn foo(bar: bool) -> impl Generator<(bool,)> { LL | |bar| { | ----- found signature of `fn(bool) -> _` -error[E0631]: type mismatch in generator arguments - --> $DIR/issue-88653.rs:8:46 - | -LL | fn foo(bar: bool) -> impl Generator<(bool,)> { - | ______________________________________________^ -LL | | -LL | | -LL | | -... | -LL | | |bar| { - | | ----- found signature of `fn(bool) -> _` -... | -LL | | } -LL | | } - | |_^ expected signature of `fn((bool,)) -> _` - -error: aborting due to 2 previous errors +error: aborting due to previous error For more information about this error, try `rustc --explain E0631`. diff --git a/src/test/ui/generator/issue-93161.rs b/src/test/ui/generator/issue-93161.rs index 9988acbcb73..92305609c83 100644 --- a/src/test/ui/generator/issue-93161.rs +++ b/src/test/ui/generator/issue-93161.rs @@ -1,5 +1,6 @@ // edition:2021 // run-pass +// compile-flags: -Zdrop-tracking #![feature(never_type)] @@ -32,7 +33,7 @@ fn never() -> Never { } async fn includes_never(crash: bool, x: u32) -> u32 { - let mut result = async { x * x }.await; + let result = async { x * x }.await; if !crash { return result; } diff --git a/src/test/ui/generator/type-mismatch-signature-deduction.rs b/src/test/ui/generator/type-mismatch-signature-deduction.rs index 77b830783c3..8d1ce6c7a43 100644 --- a/src/test/ui/generator/type-mismatch-signature-deduction.rs +++ b/src/test/ui/generator/type-mismatch-signature-deduction.rs @@ -4,7 +4,6 @@ use std::ops::Generator; fn foo() -> impl Generator<Return = i32> { //~^ ERROR type mismatch - //~| ERROR type mismatch || { if false { return Ok(6); diff --git a/src/test/ui/generator/type-mismatch-signature-deduction.stderr b/src/test/ui/generator/type-mismatch-signature-deduction.stderr index 6369e7ec4c7..f05faedf21b 100644 --- a/src/test/ui/generator/type-mismatch-signature-deduction.stderr +++ b/src/test/ui/generator/type-mismatch-signature-deduction.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/type-mismatch-signature-deduction.rs:15:9 + --> $DIR/type-mismatch-signature-deduction.rs:14:9 | LL | 5 | ^ expected enum `Result`, found integer @@ -7,12 +7,12 @@ LL | 5 = note: expected type `Result<{integer}, _>` found type `{integer}` note: return type inferred to be `Result<{integer}, _>` here - --> $DIR/type-mismatch-signature-deduction.rs:10:20 + --> $DIR/type-mismatch-signature-deduction.rs:9:20 | LL | return Ok(6); | ^^^^^ -error[E0271]: type mismatch resolving `<[generator@$DIR/type-mismatch-signature-deduction.rs:8:5: 16:6] as Generator>::Return == i32` +error[E0271]: type mismatch resolving `<[generator@$DIR/type-mismatch-signature-deduction.rs:7:5: 15:6] as Generator>::Return == i32` --> $DIR/type-mismatch-signature-deduction.rs:5:13 | LL | fn foo() -> impl Generator<Return = i32> { @@ -21,23 +21,7 @@ LL | fn foo() -> impl Generator<Return = i32> { = note: expected enum `Result<{integer}, _>` found type `i32` -error[E0271]: type mismatch resolving `<[generator@$DIR/type-mismatch-signature-deduction.rs:8:5: 16:6] as Generator>::Return == i32` - --> $DIR/type-mismatch-signature-deduction.rs:5:42 - | -LL | fn foo() -> impl Generator<Return = i32> { - | __________________________________________^ -LL | | -LL | | -LL | | || { -... | -LL | | } -LL | | } - | |_^ expected enum `Result`, found `i32` - | - = note: expected enum `Result<{integer}, _>` - found type `i32` - -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors Some errors have detailed explanations: E0271, E0308. For more information about an error, try `rustc --explain E0271`. diff --git a/src/test/ui/generic-associated-types/issue-70304.rs b/src/test/ui/generic-associated-types/issue-70304.rs index 448d7ec2873..1c3d166a1af 100644 --- a/src/test/ui/generic-associated-types/issue-70304.rs +++ b/src/test/ui/generic-associated-types/issue-70304.rs @@ -46,6 +46,7 @@ where fn create_doc() -> impl Document<Cursor<'_> = DocCursorImpl<'_>> { //~^ ERROR: missing lifetime specifier + //~| ERROR: missing lifetime specifier DocumentImpl {} } diff --git a/src/test/ui/generic-associated-types/issue-70304.stderr b/src/test/ui/generic-associated-types/issue-70304.stderr index c5f59a24057..08efc82c886 100644 --- a/src/test/ui/generic-associated-types/issue-70304.stderr +++ b/src/test/ui/generic-associated-types/issue-70304.stderr @@ -10,6 +10,18 @@ help: consider using the `'static` lifetime LL | fn create_doc() -> impl Document<Cursor<'static> = DocCursorImpl<'_>> { | ~~~~~~~ -error: aborting due to previous error +error[E0106]: missing lifetime specifier + --> $DIR/issue-70304.rs:47:61 + | +LL | fn create_doc() -> impl Document<Cursor<'_> = DocCursorImpl<'_>> { + | ^^ expected named lifetime parameter + | + = help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from +help: consider using the `'static` lifetime + | +LL | fn create_doc() -> impl Document<Cursor<'_> = DocCursorImpl<'static>> { + | ~~~~~~~ + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0106`. diff --git a/src/test/ui/generic-associated-types/issue-86483.stderr b/src/test/ui/generic-associated-types/issue-86483.stderr index 2f29cd5d9e9..a13dc043dc5 100644 --- a/src/test/ui/generic-associated-types/issue-86483.stderr +++ b/src/test/ui/generic-associated-types/issue-86483.stderr @@ -1,10 +1,7 @@ error[E0311]: the parameter type `T` may not live long enough --> $DIR/issue-86483.rs:5:1 | -LL | pub trait IceIce<T> - | ^ - help: consider adding an explicit lifetime bound...: `T: 'a` - | _| - | | +LL | / pub trait IceIce<T> LL | | where LL | | for<'a> T: 'a, LL | | { @@ -19,13 +16,14 @@ note: ...that is required by this bound | LL | for<'a> T: 'a, | ^^ +help: consider adding an explicit lifetime bound... + | +LL | for<'a> T: 'a + 'a, + | ++++ error[E0311]: the parameter type `T` may not live long enough --> $DIR/issue-86483.rs:9:5 | -LL | pub trait IceIce<T> - | - help: consider adding an explicit lifetime bound...: `T: 'a` -... LL | type Ice<'v>: IntoIterator<Item = &'v T>; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds... | @@ -34,6 +32,10 @@ note: ...that is required by this bound | LL | for<'a> T: 'a, | ^^ +help: consider adding an explicit lifetime bound... + | +LL | for<'a> T: 'a + 'a, + | ++++ error[E0309]: the parameter type `T` may not live long enough --> $DIR/issue-86483.rs:9:32 diff --git a/src/test/ui/generic-associated-types/issue-91139.migrate.stderr b/src/test/ui/generic-associated-types/issue-91139.migrate.stderr index a27d8110238..b424d9a2fdb 100644 --- a/src/test/ui/generic-associated-types/issue-91139.migrate.stderr +++ b/src/test/ui/generic-associated-types/issue-91139.migrate.stderr @@ -1,10 +1,13 @@ error[E0311]: the parameter type `T` may not live long enough --> $DIR/issue-91139.rs:27:12 | -LL | fn foo<T>() { - | - help: consider adding an explicit lifetime bound...: `T: 'a` LL | let _: for<'a> fn(<() as Foo<T>>::Type<'a>, &'a T) = |_, _| (); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds + | +help: consider adding an explicit lifetime bound... + | +LL | fn foo<T: 'a>() { + | ++++ error: aborting due to previous error diff --git a/src/test/ui/generic-associated-types/issue-92096.migrate.stderr b/src/test/ui/generic-associated-types/issue-92096.migrate.stderr index 72ade5774d7..c74161cd3e0 100644 --- a/src/test/ui/generic-associated-types/issue-92096.migrate.stderr +++ b/src/test/ui/generic-associated-types/issue-92096.migrate.stderr @@ -2,17 +2,23 @@ error[E0311]: the parameter type `C` may not live long enough --> $DIR/issue-92096.rs:20:33 | LL | fn call_connect<C>(c: &'_ C) -> impl '_ + Future + Send - | - ^^^^^^^^^^^^^^^^^^^^^^^ ...so that the type `C` will meet its required lifetime bounds - | | - | help: consider adding an explicit lifetime bound...: `C: 'a` + | ^^^^^^^^^^^^^^^^^^^^^^^ ...so that the type `C` will meet its required lifetime bounds + | +help: consider adding an explicit lifetime bound... + | +LL | C: Client + Send + Sync + 'a, + | ++++ error[E0311]: the parameter type `C` may not live long enough --> $DIR/issue-92096.rs:20:33 | LL | fn call_connect<C>(c: &'_ C) -> impl '_ + Future + Send - | - ^^^^^^^^^^^^^^^^^^^^^^^ ...so that the type `C` will meet its required lifetime bounds - | | - | help: consider adding an explicit lifetime bound...: `C: 'a` + | ^^^^^^^^^^^^^^^^^^^^^^^ ...so that the type `C` will meet its required lifetime bounds + | +help: consider adding an explicit lifetime bound... + | +LL | C: Client + Send + Sync + 'a, + | ++++ error: aborting due to 2 previous errors diff --git a/src/test/ui/generic-associated-types/issue-95305.rs b/src/test/ui/generic-associated-types/issue-95305.rs new file mode 100644 index 00000000000..9ead347984b --- /dev/null +++ b/src/test/ui/generic-associated-types/issue-95305.rs @@ -0,0 +1,17 @@ +// It's not yet clear how '_ and GATs should interact. +// Forbid it for now but proper support might be added +// at some point in the future. + +#![feature(generic_associated_types)] + +trait Foo { + type Item<'a>; +} + +fn foo(x: &impl Foo<Item<'_> = u32>) { } + //~^ ERROR missing lifetime specifier + +fn bar(x: &impl for<'a> Foo<Item<'a> = &'_ u32>) { } + //~^ ERROR missing lifetime specifier + +fn main() {} diff --git a/src/test/ui/generic-associated-types/issue-95305.stderr b/src/test/ui/generic-associated-types/issue-95305.stderr new file mode 100644 index 00000000000..2b48378dc43 --- /dev/null +++ b/src/test/ui/generic-associated-types/issue-95305.stderr @@ -0,0 +1,25 @@ +error[E0106]: missing lifetime specifier + --> $DIR/issue-95305.rs:11:26 + | +LL | fn foo(x: &impl Foo<Item<'_> = u32>) { } + | ^^ expected named lifetime parameter + | +help: consider introducing a named lifetime parameter + | +LL | fn foo<'a>(x: &impl Foo<Item<'a> = u32>) { } + | ++++ ~~ + +error[E0106]: missing lifetime specifier + --> $DIR/issue-95305.rs:14:41 + | +LL | fn bar(x: &impl for<'a> Foo<Item<'a> = &'_ u32>) { } + | ^^ expected named lifetime parameter + | +help: consider using the `'a` lifetime + | +LL | fn bar(x: &impl for<'a> Foo<Item<'a> = &'a u32>) { } + | ~~ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0106`. diff --git a/src/test/ui/generic-associated-types/missing-bounds.fixed b/src/test/ui/generic-associated-types/missing-bounds.fixed deleted file mode 100644 index 0e234120a51..00000000000 --- a/src/test/ui/generic-associated-types/missing-bounds.fixed +++ /dev/null @@ -1,46 +0,0 @@ -// run-rustfix - -use std::ops::Add; - -struct A<B>(B); - -impl<B> Add for A<B> where B: Add + Add<Output = B> { - type Output = Self; - - fn add(self, rhs: Self) -> Self { - A(self.0 + rhs.0) //~ ERROR mismatched types - } -} - -struct C<B>(B); - -impl<B: Add + Add<Output = B>> Add for C<B> { - type Output = Self; - - fn add(self, rhs: Self) -> Self { - Self(self.0 + rhs.0) //~ ERROR mismatched types - } -} - -struct D<B>(B); - -impl<B: std::ops::Add<Output = B>> Add for D<B> { - type Output = Self; - - fn add(self, rhs: Self) -> Self { - Self(self.0 + rhs.0) //~ ERROR cannot add `B` to `B` - } -} - -struct E<B>(B); - -impl<B: Add> Add for E<B> where B: Add<Output = B>, B: Add<Output = B> { - //~^ ERROR equality constraints are not yet supported in `where` clauses - type Output = Self; - - fn add(self, rhs: Self) -> Self { - Self(self.0 + rhs.0) //~ ERROR mismatched types - } -} - -fn main() {} diff --git a/src/test/ui/generic-associated-types/missing-bounds.rs b/src/test/ui/generic-associated-types/missing-bounds.rs index ffafff5e9f5..b3661ba3744 100644 --- a/src/test/ui/generic-associated-types/missing-bounds.rs +++ b/src/test/ui/generic-associated-types/missing-bounds.rs @@ -1,5 +1,3 @@ -// run-rustfix - use std::ops::Add; struct A<B>(B); diff --git a/src/test/ui/generic-associated-types/missing-bounds.stderr b/src/test/ui/generic-associated-types/missing-bounds.stderr index 240be93cf96..5323ee17226 100644 --- a/src/test/ui/generic-associated-types/missing-bounds.stderr +++ b/src/test/ui/generic-associated-types/missing-bounds.stderr @@ -1,5 +1,5 @@ error: equality constraints are not yet supported in `where` clauses - --> $DIR/missing-bounds.rs:37:33 + --> $DIR/missing-bounds.rs:35:33 | LL | impl<B: Add> Add for E<B> where <B as Add>::Output = B { | ^^^^^^^^^^^^^^^^^^^^^^ not supported @@ -11,7 +11,7 @@ LL | impl<B: Add> Add for E<B> where B: Add<Output = B> { | ~~~~~~~~~~~~~~~~~~ error[E0308]: mismatched types - --> $DIR/missing-bounds.rs:11:11 + --> $DIR/missing-bounds.rs:9:11 | LL | impl<B> Add for A<B> where B: Add { | - this type parameter @@ -24,7 +24,7 @@ LL | A(self.0 + rhs.0) = note: expected type parameter `B` found associated type `<B as Add>::Output` note: tuple struct defined here - --> $DIR/missing-bounds.rs:5:8 + --> $DIR/missing-bounds.rs:3:8 | LL | struct A<B>(B); | ^ @@ -34,7 +34,7 @@ LL | impl<B> Add for A<B> where B: Add + Add<Output = B> { | +++++++++++++++++ error[E0308]: mismatched types - --> $DIR/missing-bounds.rs:21:14 + --> $DIR/missing-bounds.rs:19:14 | LL | impl<B: Add> Add for C<B> { | - this type parameter @@ -47,7 +47,7 @@ LL | Self(self.0 + rhs.0) = note: expected type parameter `B` found associated type `<B as Add>::Output` note: tuple struct defined here - --> $DIR/missing-bounds.rs:15:8 + --> $DIR/missing-bounds.rs:13:8 | LL | struct C<B>(B); | ^ @@ -57,7 +57,7 @@ LL | impl<B: Add + Add<Output = B>> Add for C<B> { | +++++++++++++++++ error[E0369]: cannot add `B` to `B` - --> $DIR/missing-bounds.rs:31:21 + --> $DIR/missing-bounds.rs:29:21 | LL | Self(self.0 + rhs.0) | ------ ^ ----- B @@ -66,11 +66,11 @@ LL | Self(self.0 + rhs.0) | help: consider restricting type parameter `B` | -LL | impl<B: std::ops::Add<Output = B>> Add for D<B> { - | +++++++++++++++++++++++++++ +LL | impl<B: std::ops::Add> Add for D<B> { + | +++++++++++++++ error[E0308]: mismatched types - --> $DIR/missing-bounds.rs:42:14 + --> $DIR/missing-bounds.rs:40:14 | LL | impl<B: Add> Add for E<B> where <B as Add>::Output = B { | - this type parameter @@ -83,14 +83,14 @@ LL | Self(self.0 + rhs.0) = note: expected type parameter `B` found associated type `<B as Add>::Output` note: tuple struct defined here - --> $DIR/missing-bounds.rs:35:8 + --> $DIR/missing-bounds.rs:33:8 | LL | struct E<B>(B); | ^ -help: consider further restricting type parameter `B` +help: consider further restricting this bound | -LL | impl<B: Add> Add for E<B> where <B as Add>::Output = B, B: Add<Output = B> { - | ++++++++++++++++++++ +LL | impl<B: Add + Add<Output = B>> Add for E<B> where <B as Add>::Output = B { + | +++++++++++++++++ error: aborting due to 5 previous errors diff --git a/src/test/ui/generic-associated-types/unsatified-item-lifetime-bound.stderr b/src/test/ui/generic-associated-types/unsatified-item-lifetime-bound.stderr index 4f0a023ee39..ae52010cc50 100644 --- a/src/test/ui/generic-associated-types/unsatified-item-lifetime-bound.stderr +++ b/src/test/ui/generic-associated-types/unsatified-item-lifetime-bound.stderr @@ -2,7 +2,7 @@ warning: unnecessary lifetime parameter `'a` --> $DIR/unsatified-item-lifetime-bound.rs:4:12 | LL | type Y<'a: 'static>; - | ^^^^^^^^^^^ + | ^^ | = help: you can use the `'static` lifetime directly, in place of `'a` diff --git a/src/test/ui/issues/issue-80512-param-reordering-with-defaults.rs b/src/test/ui/generics/issue-80512-param-reordering-with-defaults.rs index fe3e4fbc7e0..fe3e4fbc7e0 100644 --- a/src/test/ui/issues/issue-80512-param-reordering-with-defaults.rs +++ b/src/test/ui/generics/issue-80512-param-reordering-with-defaults.rs diff --git a/src/test/ui/issues/issue-80512-param-reordering-with-defaults.stderr b/src/test/ui/generics/issue-80512-param-reordering-with-defaults.stderr index 119b1a0d207..119b1a0d207 100644 --- a/src/test/ui/issues/issue-80512-param-reordering-with-defaults.stderr +++ b/src/test/ui/generics/issue-80512-param-reordering-with-defaults.stderr diff --git a/src/test/ui/generics/post_monomorphization_error_backtrace.rs b/src/test/ui/generics/post_monomorphization_error_backtrace.rs new file mode 100644 index 00000000000..1fd9b6b3b9d --- /dev/null +++ b/src/test/ui/generics/post_monomorphization_error_backtrace.rs @@ -0,0 +1,33 @@ +// build-fail + +fn assert_zst<T>() { + struct F<T>(T); + impl<T> F<T> { + const V: () = assert!(std::mem::size_of::<T>() == 0); + //~^ ERROR: evaluation of `assert_zst::F::<u32>::V` failed [E0080] + //~| NOTE: in this expansion of assert! + //~| NOTE: the evaluated program panicked + //~| ERROR: evaluation of `assert_zst::F::<i32>::V` failed [E0080] + //~| NOTE: in this expansion of assert! + //~| NOTE: the evaluated program panicked + } + let _ = F::<T>::V; +} + +fn foo<U>() { + assert_zst::<U>() + //~^ NOTE: the above error was encountered while instantiating `fn assert_zst::<u32>` + //~| NOTE: the above error was encountered while instantiating `fn assert_zst::<i32>` +} + + +fn bar<V>() { + foo::<V>() +} + +fn main() { + bar::<()>(); + bar::<u32>(); + bar::<u32>(); + bar::<i32>(); +} diff --git a/src/test/ui/generics/post_monomorphization_error_backtrace.stderr b/src/test/ui/generics/post_monomorphization_error_backtrace.stderr new file mode 100644 index 00000000000..0d707d83d26 --- /dev/null +++ b/src/test/ui/generics/post_monomorphization_error_backtrace.stderr @@ -0,0 +1,31 @@ +error[E0080]: evaluation of `assert_zst::F::<u32>::V` failed + --> $DIR/post_monomorphization_error_backtrace.rs:6:23 + | +LL | const V: () = assert!(std::mem::size_of::<T>() == 0); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'assertion failed: std::mem::size_of::<T>() == 0', $DIR/post_monomorphization_error_backtrace.rs:6:23 + | + = note: this error originates in the macro `assert` (in Nightly builds, run with -Z macro-backtrace for more info) + +note: the above error was encountered while instantiating `fn assert_zst::<u32>` + --> $DIR/post_monomorphization_error_backtrace.rs:18:5 + | +LL | assert_zst::<U>() + | ^^^^^^^^^^^^^^^^^ + +error[E0080]: evaluation of `assert_zst::F::<i32>::V` failed + --> $DIR/post_monomorphization_error_backtrace.rs:6:23 + | +LL | const V: () = assert!(std::mem::size_of::<T>() == 0); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'assertion failed: std::mem::size_of::<T>() == 0', $DIR/post_monomorphization_error_backtrace.rs:6:23 + | + = note: this error originates in the macro `assert` (in Nightly builds, run with -Z macro-backtrace for more info) + +note: the above error was encountered while instantiating `fn assert_zst::<i32>` + --> $DIR/post_monomorphization_error_backtrace.rs:18:5 + | +LL | assert_zst::<U>() + | ^^^^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0080`. diff --git a/src/test/ui/hrtb/issue-30786.migrate.stderr b/src/test/ui/hrtb/issue-30786.migrate.stderr index 7ffe2f4cd7e..7157b186fc8 100644 --- a/src/test/ui/hrtb/issue-30786.migrate.stderr +++ b/src/test/ui/hrtb/issue-30786.migrate.stderr @@ -18,6 +18,10 @@ note: the following trait bounds were not satisfied: | LL | impl<T> StreamExt for T where for<'a> &'a mut T: Stream {} | --------- - ^^^^^^ unsatisfied trait bound introduced here +help: one of the expressions' fields has a method of the same name + | +LL | let filter = map.stream.filterx(|x: &_| true); + | +++++++ error[E0599]: the method `countx` exists for struct `Filter<Map<Repeat, for<'r> fn(&'r u64) -> &'r u64 {identity::<u64>}>, [closure@$DIR/issue-30786.rs:139:30: 139:42]>`, but its trait bounds were not satisfied --> $DIR/issue-30786.rs:140:24 @@ -39,6 +43,10 @@ note: the following trait bounds were not satisfied: | LL | impl<T> StreamExt for T where for<'a> &'a mut T: Stream {} | --------- - ^^^^^^ unsatisfied trait bound introduced here +help: one of the expressions' fields has a method of the same name + | +LL | let count = filter.stream.countx(); + | +++++++ error: aborting due to 2 previous errors diff --git a/src/test/ui/hrtb/issue-30786.nll.stderr b/src/test/ui/hrtb/issue-30786.nll.stderr index 7ffe2f4cd7e..7157b186fc8 100644 --- a/src/test/ui/hrtb/issue-30786.nll.stderr +++ b/src/test/ui/hrtb/issue-30786.nll.stderr @@ -18,6 +18,10 @@ note: the following trait bounds were not satisfied: | LL | impl<T> StreamExt for T where for<'a> &'a mut T: Stream {} | --------- - ^^^^^^ unsatisfied trait bound introduced here +help: one of the expressions' fields has a method of the same name + | +LL | let filter = map.stream.filterx(|x: &_| true); + | +++++++ error[E0599]: the method `countx` exists for struct `Filter<Map<Repeat, for<'r> fn(&'r u64) -> &'r u64 {identity::<u64>}>, [closure@$DIR/issue-30786.rs:139:30: 139:42]>`, but its trait bounds were not satisfied --> $DIR/issue-30786.rs:140:24 @@ -39,6 +43,10 @@ note: the following trait bounds were not satisfied: | LL | impl<T> StreamExt for T where for<'a> &'a mut T: Stream {} | --------- - ^^^^^^ unsatisfied trait bound introduced here +help: one of the expressions' fields has a method of the same name + | +LL | let count = filter.stream.countx(); + | +++++++ error: aborting due to 2 previous errors diff --git a/src/test/ui/impl-trait/bound-normalization-fail.rs b/src/test/ui/impl-trait/bound-normalization-fail.rs index 9f962fa9bba..3329592478d 100644 --- a/src/test/ui/impl-trait/bound-normalization-fail.rs +++ b/src/test/ui/impl-trait/bound-normalization-fail.rs @@ -24,7 +24,6 @@ mod impl_trait { /// `T::Assoc` can't be normalized any further here. fn foo_fail<T: Trait>() -> impl FooLike<Output = T::Assoc> { //~^ ERROR: type mismatch - //~| ERROR: type mismatch Foo(()) } } @@ -42,7 +41,6 @@ mod lifetimes { fn foo2_fail<'a, T: Trait<'a>>() -> impl FooLike<Output = T::Assoc> { //~^ ERROR `impl Trait` return type cannot contain a projection or `Self` that references lifetimes from a parent scope //~| ERROR: type mismatch - //~| ERROR: type mismatch Foo(()) } } diff --git a/src/test/ui/impl-trait/bound-normalization-fail.stderr b/src/test/ui/impl-trait/bound-normalization-fail.stderr index 0344f416eb7..eac7e6b315e 100644 --- a/src/test/ui/impl-trait/bound-normalization-fail.stderr +++ b/src/test/ui/impl-trait/bound-normalization-fail.stderr @@ -16,37 +16,14 @@ help: consider constraining the associated type `<T as impl_trait::Trait>::Assoc LL | fn foo_fail<T: Trait<Assoc = ()>>() -> impl FooLike<Output = T::Assoc> { | ++++++++++++ -error[E0271]: type mismatch resolving `<Foo<()> as FooLike>::Output == <T as impl_trait::Trait>::Assoc` - --> $DIR/bound-normalization-fail.rs:25:64 - | -LL | fn foo_fail<T: Trait>() -> impl FooLike<Output = T::Assoc> { - | ________________________________________________________________^ -LL | | -LL | | -LL | | Foo(()) -LL | | } - | |_____^ type mismatch resolving `<Foo<()> as FooLike>::Output == <T as impl_trait::Trait>::Assoc` - | -note: expected this to be `()` - --> $DIR/bound-normalization-fail.rs:14:19 - | -LL | type Output = T; - | ^ - = note: expected unit type `()` - found associated type `<T as impl_trait::Trait>::Assoc` -help: consider constraining the associated type `<T as impl_trait::Trait>::Assoc` to `()` - | -LL | fn foo_fail<T: Trait<Assoc = ()>>() -> impl FooLike<Output = T::Assoc> { - | ++++++++++++ - error[E0760]: `impl Trait` return type cannot contain a projection or `Self` that references lifetimes from a parent scope - --> $DIR/bound-normalization-fail.rs:42:41 + --> $DIR/bound-normalization-fail.rs:41:41 | LL | fn foo2_fail<'a, T: Trait<'a>>() -> impl FooLike<Output = T::Assoc> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0271]: type mismatch resolving `<Foo<()> as FooLike>::Output == <T as lifetimes::Trait<'static>>::Assoc` - --> $DIR/bound-normalization-fail.rs:42:41 + --> $DIR/bound-normalization-fail.rs:41:41 | LL | fn foo2_fail<'a, T: Trait<'a>>() -> impl FooLike<Output = T::Assoc> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type mismatch resolving `<Foo<()> as FooLike>::Output == <T as lifetimes::Trait<'static>>::Assoc` @@ -63,31 +40,7 @@ help: consider constraining the associated type `<T as lifetimes::Trait<'static> LL | fn foo2_fail<'a, T: Trait<'a, Assoc = ()>>() -> impl FooLike<Output = T::Assoc> { | ++++++++++++ -error[E0271]: type mismatch resolving `<Foo<()> as FooLike>::Output == <T as lifetimes::Trait<'static>>::Assoc` - --> $DIR/bound-normalization-fail.rs:42:73 - | -LL | fn foo2_fail<'a, T: Trait<'a>>() -> impl FooLike<Output = T::Assoc> { - | _________________________________________________________________________^ -LL | | -LL | | -LL | | -LL | | Foo(()) -LL | | } - | |_____^ type mismatch resolving `<Foo<()> as FooLike>::Output == <T as lifetimes::Trait<'static>>::Assoc` - | -note: expected this to be `()` - --> $DIR/bound-normalization-fail.rs:14:19 - | -LL | type Output = T; - | ^ - = note: expected unit type `()` - found associated type `<T as lifetimes::Trait<'static>>::Assoc` -help: consider constraining the associated type `<T as lifetimes::Trait<'static>>::Assoc` to `()` - | -LL | fn foo2_fail<'a, T: Trait<'a, Assoc = ()>>() -> impl FooLike<Output = T::Assoc> { - | ++++++++++++ - -error: aborting due to 5 previous errors +error: aborting due to 3 previous errors Some errors have detailed explanations: E0271, E0760. For more information about an error, try `rustc --explain E0271`. diff --git a/src/test/ui/impl-trait/cross-return-site-inference.rs b/src/test/ui/impl-trait/cross-return-site-inference.rs index c27b5ca9f66..a7428f9bf12 100644 --- a/src/test/ui/impl-trait/cross-return-site-inference.rs +++ b/src/test/ui/impl-trait/cross-return-site-inference.rs @@ -29,17 +29,17 @@ fn baa(b: bool) -> impl std::fmt::Debug { } fn muh() -> Result<(), impl std::fmt::Debug> { - Err("whoops")?; //~ ERROR `?` couldn't convert the error to `impl Debug` + Err("whoops")?; //~^ ERROR type annotations needed Ok(()) } fn muh2() -> Result<(), impl std::fmt::Debug> { - return Err(From::from("foo")); //~ ERROR the trait bound `impl Debug: From<&str>` is not satisfied + return Err(From::from("foo")); //~^ ERROR type annotations needed Ok(()) } fn muh3() -> Result<(), impl std::fmt::Debug> { - Err(From::from("foo")) //~ ERROR the trait bound `impl Debug: From<&str>` is not satisfied + Err(From::from("foo")) //~^ ERROR type annotations needed } fn main() {} diff --git a/src/test/ui/impl-trait/cross-return-site-inference.stderr b/src/test/ui/impl-trait/cross-return-site-inference.stderr index d458c7be783..5209d7a5743 100644 --- a/src/test/ui/impl-trait/cross-return-site-inference.stderr +++ b/src/test/ui/impl-trait/cross-return-site-inference.stderr @@ -1,27 +1,21 @@ -error[E0277]: `?` couldn't convert the error to `impl Debug` - --> $DIR/cross-return-site-inference.rs:32:18 +error[E0282]: type annotations needed + --> $DIR/cross-return-site-inference.rs:31:24 | LL | fn muh() -> Result<(), impl std::fmt::Debug> { - | -------------------------------- expected `impl Debug` because of this -LL | Err("whoops")?; - | ^ the trait `From<&str>` is not implemented for `impl Debug` - | - = note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait - = help: the trait `FromResidual<Result<Infallible, E>>` is implemented for `Result<T, F>` - = note: required because of the requirements on the impl of `FromResidual<Result<Infallible, &str>>` for `Result<(), impl Debug>` + | ^^^^^^^^^^^^^^^^^^^^ cannot infer type -error[E0277]: the trait bound `impl Debug: From<&str>` is not satisfied - --> $DIR/cross-return-site-inference.rs:37:16 +error[E0282]: type annotations needed + --> $DIR/cross-return-site-inference.rs:36:25 | -LL | return Err(From::from("foo")); - | ^^^^^^^^^^ the trait `From<&str>` is not implemented for `impl Debug` +LL | fn muh2() -> Result<(), impl std::fmt::Debug> { + | ^^^^^^^^^^^^^^^^^^^^ cannot infer type -error[E0277]: the trait bound `impl Debug: From<&str>` is not satisfied - --> $DIR/cross-return-site-inference.rs:42:9 +error[E0282]: type annotations needed + --> $DIR/cross-return-site-inference.rs:41:25 | -LL | Err(From::from("foo")) - | ^^^^^^^^^^ the trait `From<&str>` is not implemented for `impl Debug` +LL | fn muh3() -> Result<(), impl std::fmt::Debug> { + | ^^^^^^^^^^^^^^^^^^^^ cannot infer type error: aborting due to 3 previous errors -For more information about this error, try `rustc --explain E0277`. +For more information about this error, try `rustc --explain E0282`. diff --git a/src/test/ui/impl-trait/equal-hidden-lifetimes.stderr b/src/test/ui/impl-trait/equal-hidden-lifetimes.stderr index 51247f1d7b0..3e48aef553b 100644 --- a/src/test/ui/impl-trait/equal-hidden-lifetimes.stderr +++ b/src/test/ui/impl-trait/equal-hidden-lifetimes.stderr @@ -2,7 +2,7 @@ warning: unnecessary lifetime parameter `'a` --> $DIR/equal-hidden-lifetimes.rs:7:25 | LL | fn equal_regions_static<'a: 'static>(x: &'a i32) -> impl Sized { - | ^^^^^^^^^^^ + | ^^ | = help: you can use the `'static` lifetime directly, in place of `'a` diff --git a/src/test/ui/impl-trait/fallback_inference.rs b/src/test/ui/impl-trait/fallback_inference.rs new file mode 100644 index 00000000000..001f9ee4877 --- /dev/null +++ b/src/test/ui/impl-trait/fallback_inference.rs @@ -0,0 +1,7 @@ +use std::marker::PhantomData; + +fn weird() -> PhantomData<impl Sized> { + PhantomData //~^ ERROR type annotations needed +} + +fn main() {} diff --git a/src/test/ui/impl-trait/fallback_inference.stderr b/src/test/ui/impl-trait/fallback_inference.stderr new file mode 100644 index 00000000000..b637ca694c2 --- /dev/null +++ b/src/test/ui/impl-trait/fallback_inference.stderr @@ -0,0 +1,9 @@ +error[E0282]: type annotations needed + --> $DIR/fallback_inference.rs:3:27 + | +LL | fn weird() -> PhantomData<impl Sized> { + | ^^^^^^^^^^ cannot infer type + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0282`. diff --git a/src/test/ui/impl-trait/issue-72911.rs b/src/test/ui/impl-trait/issue-72911.rs index cf2c8b7e415..be9c643b2d8 100644 --- a/src/test/ui/impl-trait/issue-72911.rs +++ b/src/test/ui/impl-trait/issue-72911.rs @@ -5,7 +5,7 @@ pub struct Lint {} impl Lint {} pub fn gather_all() -> impl Iterator<Item = Lint> { - //~^ ERROR `()` is not an iterator + //~^ ERROR type annotations needed lint_files().flat_map(|f| gather_from_file(&f)) } diff --git a/src/test/ui/impl-trait/issue-72911.stderr b/src/test/ui/impl-trait/issue-72911.stderr index 4a990286d96..fc7200c75c2 100644 --- a/src/test/ui/impl-trait/issue-72911.stderr +++ b/src/test/ui/impl-trait/issue-72911.stderr @@ -10,15 +10,13 @@ error[E0433]: failed to resolve: use of undeclared crate or module `foo` LL | fn lint_files() -> impl Iterator<Item = foo::MissingItem> { | ^^^ use of undeclared crate or module `foo` -error[E0277]: `()` is not an iterator +error[E0282]: type annotations needed --> $DIR/issue-72911.rs:7:24 | LL | pub fn gather_all() -> impl Iterator<Item = Lint> { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ `()` is not an iterator - | - = help: the trait `Iterator` is not implemented for `()` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type error: aborting due to 3 previous errors -Some errors have detailed explanations: E0277, E0433. -For more information about an error, try `rustc --explain E0277`. +Some errors have detailed explanations: E0282, E0433. +For more information about an error, try `rustc --explain E0282`. diff --git a/src/test/ui/impl-trait/issues/issue-67830.stderr b/src/test/ui/impl-trait/issues/issue-67830.stderr index 74e2f99cd33..4c0490c721b 100644 --- a/src/test/ui/impl-trait/issues/issue-67830.stderr +++ b/src/test/ui/impl-trait/issues/issue-67830.stderr @@ -1,12 +1,8 @@ error: implementation of `FnOnce` is not general enough - --> $DIR/issue-67830.rs:21:66 + --> $DIR/issue-67830.rs:21:14 | -LL | fn test() -> impl for<'a> MyFn<&'a A, Output=impl Iterator + 'a> { - | __________________________________________________________________^ -LL | | -LL | | Wrap(|a| Some(a).into_iter()) -LL | | } - | |_^ implementation of `FnOnce` is not general enough +LL | fn test() -> impl for<'a> MyFn<&'a A, Output=impl Iterator + 'a> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `FnOnce` is not general enough | = note: closure with signature `fn(&'2 A) -> std::option::IntoIter<&A>` must implement `FnOnce<(&'1 A,)>`, for any lifetime `'1`... = note: ...but it actually implements `FnOnce<(&'2 A,)>`, for some specific lifetime `'2` diff --git a/src/test/ui/impl-trait/issues/issue-86800.rs b/src/test/ui/impl-trait/issues/issue-86800.rs index e8cef42f208..19edeaffc49 100644 --- a/src/test/ui/impl-trait/issues/issue-86800.rs +++ b/src/test/ui/impl-trait/issues/issue-86800.rs @@ -27,16 +27,16 @@ type TransactionFuture<'__, O> = impl '__ + Future<Output = TransactionResult<O> fn execute_transaction_fut<'f, F, O>( f: F, -) -> impl FnOnce(&mut dyn Transaction) -> TransactionFuture<O> +) -> impl FnOnce(&mut dyn Transaction) -> TransactionFuture<'_, O> where - F: FnOnce(&mut dyn Transaction) -> TransactionFuture<O> + 'f + F: FnOnce(&mut dyn Transaction) -> TransactionFuture<'_, O> + 'f { f } impl Context { async fn do_transaction<O>( - &self, f: impl FnOnce(&mut dyn Transaction) -> TransactionFuture<O> + &self, f: impl FnOnce(&mut dyn Transaction) -> TransactionFuture<'_, O> ) -> TransactionResult<O> { let mut conn = Connection {}; diff --git a/src/test/ui/impl-trait/issues/issue-88236-2.nll.stderr b/src/test/ui/impl-trait/issues/issue-88236-2.nll.stderr index 9cf8ff76c87..66cffa9e36c 100644 --- a/src/test/ui/impl-trait/issues/issue-88236-2.nll.stderr +++ b/src/test/ui/impl-trait/issues/issue-88236-2.nll.stderr @@ -24,10 +24,14 @@ LL | fn make_bad_impl<'b>(x: &'b ()) -> impl for<'a> Hrtb<'a, Assoc = impl Send LL | x | ^ returning this value requires that `'b` must outlive `'static` | -help: to allow this `impl Trait` to capture borrowed data with lifetime `'b`, add `'b` as a bound +help: to declare that the `impl Trait` captures data from argument `x`, you can add an explicit `'b` lifetime bound | LL | fn make_bad_impl<'b>(x: &'b ()) -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> + 'b { | ++++ +help: to declare that the `impl Trait` captures data from argument `x`, you can add an explicit `'b` lifetime bound + | +LL | fn make_bad_impl<'b>(x: &'b ()) -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a + 'b> { + | ++++ error: implementation of `Hrtb` is not general enough --> $DIR/issue-88236-2.rs:20:5 diff --git a/src/test/ui/impl-trait/issues/issue-88236-2.stderr b/src/test/ui/impl-trait/issues/issue-88236-2.stderr index 45fadcab3f2..9574b880f7d 100644 --- a/src/test/ui/impl-trait/issues/issue-88236-2.stderr +++ b/src/test/ui/impl-trait/issues/issue-88236-2.stderr @@ -8,15 +8,12 @@ LL | fn make_weird_impl<'b>(x: &'b ()) -> impl for<'a> Hrtb<'a, Assoc = impl Sen = note: ...but `Hrtb<'1>` is actually implemented for the type `&'1 ()`, for some specific lifetime `'1` error: implementation of `Hrtb` is not general enough - --> $DIR/issue-88236-2.rs:19:82 + --> $DIR/issue-88236-2.rs:19:36 | -LL | fn make_bad_impl<'b>(x: &'b ()) -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> { - | __________________________________________________________________________________^ -LL | | x -LL | | } - | |_^ implementation of `Hrtb` is not general enough +LL | fn make_bad_impl<'b>(x: &'b ()) -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Hrtb` is not general enough | - = note: `&()` must implement `Hrtb<'0>`, for any lifetime `'0`... + = note: `Hrtb<'1>` would have to be implemented for the type `&()`, for any lifetime `'1`... = note: ...but `Hrtb<'_>` is actually implemented for the type `&()` error: aborting due to 2 previous errors diff --git a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.nll.stderr b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.nll.stderr index 9589b69491e..db737a9c544 100644 --- a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.nll.stderr +++ b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.nll.stderr @@ -32,7 +32,14 @@ LL | fn elided2(x: &i32) -> impl Copy + 'static { x } | | | let's call the lifetime of this reference `'1` | - = help: consider replacing `'1` with `'static` +help: consider changing the `impl Trait`'s explicit `'static` bound to the lifetime of argument `x` + | +LL | fn elided2(x: &i32) -> impl Copy + '_ { x } + | ~~ +help: alternatively, add an explicit `'static` bound to this reference + | +LL | fn elided2(x: &'static i32) -> impl Copy + 'static { x } + | ~~~~~~~~~~~~ error: lifetime may not live long enough --> $DIR/must_outlive_least_region_or_bound.rs:11:55 @@ -40,7 +47,14 @@ error: lifetime may not live long enough LL | fn explicit2<'a>(x: &'a i32) -> impl Copy + 'static { x } | -- lifetime `'a` defined here ^ returning this value requires that `'a` must outlive `'static` | - = help: consider replacing `'a` with `'static` +help: consider changing the `impl Trait`'s explicit `'static` bound to the lifetime of argument `x` + | +LL | fn explicit2<'a>(x: &'a i32) -> impl Copy + 'a { x } + | ~~ +help: alternatively, add an explicit `'static` bound to this reference + | +LL | fn explicit2<'a>(x: &'static i32) -> impl Copy + 'static { x } + | ~~~~~~~~~~~~ error[E0621]: explicit lifetime required in the type of `x` --> $DIR/must_outlive_least_region_or_bound.rs:13:41 @@ -57,6 +71,15 @@ LL | fn elided5(x: &i32) -> (Box<dyn Debug>, impl Debug) { (Box::new(x), x) } | - ^^^^^^^^^^^^^^^^ returning this value requires that `'1` must outlive `'static` | | | let's call the lifetime of this reference `'1` + | +help: to declare that the trait object captures data from argument `x`, you can add an explicit `'_` lifetime bound + | +LL | fn elided5(x: &i32) -> (Box<dyn Debug + '_>, impl Debug) { (Box::new(x), x) } + | ++++ +help: to declare that the `impl Trait` captures data from argument `x`, you can add an explicit `'_` lifetime bound + | +LL | fn elided5(x: &i32) -> (Box<dyn Debug>, impl Debug + '_) { (Box::new(x), x) } + | ++++ error: lifetime may not live long enough --> $DIR/must_outlive_least_region_or_bound.rs:29:69 @@ -64,7 +87,14 @@ error: lifetime may not live long enough LL | fn with_bound<'a>(x: &'a i32) -> impl LifetimeTrait<'a> + 'static { x } | -- lifetime `'a` defined here ^ returning this value requires that `'a` must outlive `'static` | - = help: consider replacing `'a` with `'static` +help: consider changing the `impl Trait`'s explicit `'static` bound to the lifetime of argument `x` + | +LL | fn with_bound<'a>(x: &'a i32) -> impl LifetimeTrait<'a> + 'a { x } + | ~~ +help: alternatively, add an explicit `'static` bound to this reference + | +LL | fn with_bound<'a>(x: &'static i32) -> impl LifetimeTrait<'a> + 'static { x } + | ~~~~~~~~~~~~ error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds --> $DIR/must_outlive_least_region_or_bound.rs:34:5 @@ -80,12 +110,15 @@ LL | fn move_lifetime_into_fn<'a, 'b>(x: &'a u32, y: &'b u32) -> impl Fn(&'a u32 | ++++ error[E0310]: the parameter type `T` may not live long enough - --> $DIR/must_outlive_least_region_or_bound.rs:41:5 + --> $DIR/must_outlive_least_region_or_bound.rs:40:5 | LL | x - | ^ + | ^ ...so that the type `T` will meet its required lifetime bounds + | +help: consider adding an explicit lifetime bound... | - = help: consider adding an explicit lifetime bound `T: 'static`... +LL | fn ty_param_wont_outlive_static<T:Debug + 'static>(x: T) -> impl Debug + 'static { + | +++++++++ error: aborting due to 9 previous errors diff --git a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.rs b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.rs index baa42da6446..60e4672f1b7 100644 --- a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.rs +++ b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.rs @@ -37,7 +37,6 @@ fn move_lifetime_into_fn<'a, 'b>(x: &'a u32, y: &'b u32) -> impl Fn(&'a u32) { fn ty_param_wont_outlive_static<T:Debug>(x: T) -> impl Debug + 'static { //~^ ERROR the parameter type `T` may not live long enough - //~| ERROR the parameter type `T` may not live long enough x } diff --git a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr index 1272adb35e9..dade2b91fe0 100644 --- a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr +++ b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.stderr @@ -128,22 +128,12 @@ error[E0310]: the parameter type `T` may not live long enough --> $DIR/must_outlive_least_region_or_bound.rs:38:51 | LL | fn ty_param_wont_outlive_static<T:Debug>(x: T) -> impl Debug + 'static { - | -- ^^^^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds - | | - | help: consider adding an explicit lifetime bound...: `T: 'static +` - -error[E0310]: the parameter type `T` may not live long enough - --> $DIR/must_outlive_least_region_or_bound.rs:38:72 - | -LL | fn ty_param_wont_outlive_static<T:Debug>(x: T) -> impl Debug + 'static { - | _________________________________--_____________________________________^ - | | | - | | help: consider adding an explicit lifetime bound...: `T: 'static +` -LL | | -LL | | -LL | | x -LL | | } - | |_^ ...so that the type `T` will meet its required lifetime bounds + | ^^^^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds + | +help: consider adding an explicit lifetime bound... + | +LL | fn ty_param_wont_outlive_static<T:Debug + 'static>(x: T) -> impl Debug + 'static { + | +++++++++ error[E0759]: `x` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement --> $DIR/must_outlive_least_region_or_bound.rs:16:50 @@ -231,7 +221,7 @@ help: alternatively, add an explicit `'static` bound to this reference LL | fn explicit4<'a>(x: &'static i32) -> Box<dyn Debug + 'static> { Box::new(x) } | ~~~~~~~~~~~~ -error: aborting due to 14 previous errors +error: aborting due to 13 previous errors Some errors have detailed explanations: E0310, E0621, E0700, E0759. For more information about an error, try `rustc --explain E0310`. diff --git a/src/test/ui/impl-trait/nested-return-type2-tait.rs b/src/test/ui/impl-trait/nested-return-type2-tait.rs index f2217f699fb..a2a49c5535d 100644 --- a/src/test/ui/impl-trait/nested-return-type2-tait.rs +++ b/src/test/ui/impl-trait/nested-return-type2-tait.rs @@ -24,7 +24,6 @@ type Sendable = impl Send; // type does not implement `Duh`, even if its hidden type does. So we error out. fn foo() -> impl Trait<Assoc = Sendable> { //~^ ERROR `Sendable: Duh` is not satisfied - //~| ERROR `Sendable: Duh` is not satisfied || 42 } diff --git a/src/test/ui/impl-trait/nested-return-type2-tait.stderr b/src/test/ui/impl-trait/nested-return-type2-tait.stderr index 81a75e39c91..359fb909e54 100644 --- a/src/test/ui/impl-trait/nested-return-type2-tait.stderr +++ b/src/test/ui/impl-trait/nested-return-type2-tait.stderr @@ -5,30 +5,12 @@ LL | fn foo() -> impl Trait<Assoc = Sendable> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Duh` is not implemented for `Sendable` | = help: the trait `Duh` is implemented for `i32` -note: required because of the requirements on the impl of `Trait` for `[closure@$DIR/nested-return-type2-tait.rs:28:5: 28:10]` +note: required because of the requirements on the impl of `Trait` for `[closure@$DIR/nested-return-type2-tait.rs:27:5: 27:10]` --> $DIR/nested-return-type2-tait.rs:14:31 | LL | impl<R: Duh, F: FnMut() -> R> Trait for F { | ^^^^^ ^ -error[E0277]: the trait bound `Sendable: Duh` is not satisfied - --> $DIR/nested-return-type2-tait.rs:25:42 - | -LL | fn foo() -> impl Trait<Assoc = Sendable> { - | __________________________________________^ -LL | | -LL | | -LL | | || 42 -LL | | } - | |_^ the trait `Duh` is not implemented for `Sendable` - | - = help: the trait `Duh` is implemented for `i32` -note: required because of the requirements on the impl of `Trait` for `[closure@$DIR/nested-return-type2-tait.rs:28:5: 28:10]` - --> $DIR/nested-return-type2-tait.rs:14:31 - | -LL | impl<R: Duh, F: FnMut() -> R> Trait for F { - | ^^^^^ ^ - -error: aborting due to 2 previous errors +error: aborting due to previous error For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/impl-trait/type_parameters_captured.nll.stderr b/src/test/ui/impl-trait/type_parameters_captured.nll.stderr index b1175a5952e..3050f10b205 100644 --- a/src/test/ui/impl-trait/type_parameters_captured.nll.stderr +++ b/src/test/ui/impl-trait/type_parameters_captured.nll.stderr @@ -1,10 +1,13 @@ error[E0310]: the parameter type `T` may not live long enough - --> $DIR/type_parameters_captured.rs:10:5 + --> $DIR/type_parameters_captured.rs:9:5 | LL | x - | ^ + | ^ ...so that the type `T` will meet its required lifetime bounds | - = help: consider adding an explicit lifetime bound `T: 'static`... +help: consider adding an explicit lifetime bound... + | +LL | fn foo<T: 'static>(x: T) -> impl Any + 'static { + | +++++++++ error: aborting due to previous error diff --git a/src/test/ui/impl-trait/type_parameters_captured.rs b/src/test/ui/impl-trait/type_parameters_captured.rs index bb9cab742a5..6c9c9d4a42a 100644 --- a/src/test/ui/impl-trait/type_parameters_captured.rs +++ b/src/test/ui/impl-trait/type_parameters_captured.rs @@ -6,7 +6,6 @@ impl<T> Any for T {} // Check that type parameters are captured and not considered 'static fn foo<T>(x: T) -> impl Any + 'static { //~^ ERROR the parameter type `T` may not live long enough - //~| ERROR the parameter type `T` may not live long enough x } diff --git a/src/test/ui/impl-trait/type_parameters_captured.stderr b/src/test/ui/impl-trait/type_parameters_captured.stderr index c4ca34a6ed3..9f28a8d44a7 100644 --- a/src/test/ui/impl-trait/type_parameters_captured.stderr +++ b/src/test/ui/impl-trait/type_parameters_captured.stderr @@ -2,23 +2,13 @@ error[E0310]: the parameter type `T` may not live long enough --> $DIR/type_parameters_captured.rs:7:20 | LL | fn foo<T>(x: T) -> impl Any + 'static { - | - ^^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds - | | - | help: consider adding an explicit lifetime bound...: `T: 'static` - -error[E0310]: the parameter type `T` may not live long enough - --> $DIR/type_parameters_captured.rs:7:39 + | ^^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds + | +help: consider adding an explicit lifetime bound... | -LL | fn foo<T>(x: T) -> impl Any + 'static { - | ________-______________________________^ - | | | - | | help: consider adding an explicit lifetime bound...: `T: 'static` -LL | | -LL | | -LL | | x -LL | | } - | |_^ ...so that the type `T` will meet its required lifetime bounds +LL | fn foo<T: 'static>(x: T) -> impl Any + 'static { + | +++++++++ -error: aborting due to 2 previous errors +error: aborting due to previous error For more information about this error, try `rustc --explain E0310`. diff --git a/src/test/ui/impl-trait/where-allowed-2.rs b/src/test/ui/impl-trait/where-allowed-2.rs index d5a87b5d468..1a1210d0072 100644 --- a/src/test/ui/impl-trait/where-allowed-2.rs +++ b/src/test/ui/impl-trait/where-allowed-2.rs @@ -1,7 +1,6 @@ use std::fmt::Debug; -// check-pass - fn in_adt_in_return() -> Vec<impl Debug> { panic!() } +//~^ ERROR type annotations needed fn main() {} diff --git a/src/test/ui/impl-trait/where-allowed-2.stderr b/src/test/ui/impl-trait/where-allowed-2.stderr new file mode 100644 index 00000000000..2b328c01c87 --- /dev/null +++ b/src/test/ui/impl-trait/where-allowed-2.stderr @@ -0,0 +1,9 @@ +error[E0282]: type annotations needed + --> $DIR/where-allowed-2.rs:3:30 + | +LL | fn in_adt_in_return() -> Vec<impl Debug> { panic!() } + | ^^^^^^^^^^ cannot infer type + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0282`. diff --git a/src/test/ui/inference/question-mark-type-infer.stderr b/src/test/ui/inference/question-mark-type-infer.stderr index e7d5fee1812..9b822714f82 100644 --- a/src/test/ui/inference/question-mark-type-infer.stderr +++ b/src/test/ui/inference/question-mark-type-infer.stderr @@ -1,15 +1,9 @@ -error[E0284]: type annotations needed - --> $DIR/question-mark-type-infer.rs:10:21 +error[E0282]: type annotations needed + --> $DIR/question-mark-type-infer.rs:10:30 | LL | l.iter().map(f).collect()? - | ^^^^^^^ cannot infer type - | - = note: cannot satisfy `<_ as Try>::Residual == _` -help: consider specifying the type argument in the method call - | -LL | l.iter().map(f).collect::<B>()? - | +++++ + | ^ cannot infer type error: aborting due to previous error -For more information about this error, try `rustc --explain E0284`. +For more information about this error, try `rustc --explain E0282`. diff --git a/src/test/ui/intrinsics/unchecked_math_unsafe.thir.stderr b/src/test/ui/intrinsics/unchecked_math_unsafe.thir.stderr index 26b2f9f2713..5c3728ccdf8 100644 --- a/src/test/ui/intrinsics/unchecked_math_unsafe.thir.stderr +++ b/src/test/ui/intrinsics/unchecked_math_unsafe.thir.stderr @@ -1,4 +1,4 @@ -error[E0133]: call to unsafe function is unsafe and requires unsafe function or block +error[E0133]: call to unsafe function `unchecked_add` is unsafe and requires unsafe function or block --> $DIR/unchecked_math_unsafe.rs:8:15 | LL | let add = std::intrinsics::unchecked_add(x, y); @@ -6,7 +6,7 @@ LL | let add = std::intrinsics::unchecked_add(x, y); | = note: consult the function's documentation for information on how to avoid undefined behavior -error[E0133]: call to unsafe function is unsafe and requires unsafe function or block +error[E0133]: call to unsafe function `unchecked_sub` is unsafe and requires unsafe function or block --> $DIR/unchecked_math_unsafe.rs:9:15 | LL | let sub = std::intrinsics::unchecked_sub(x, y); @@ -14,7 +14,7 @@ LL | let sub = std::intrinsics::unchecked_sub(x, y); | = note: consult the function's documentation for information on how to avoid undefined behavior -error[E0133]: call to unsafe function is unsafe and requires unsafe function or block +error[E0133]: call to unsafe function `unchecked_mul` is unsafe and requires unsafe function or block --> $DIR/unchecked_math_unsafe.rs:10:15 | LL | let mul = std::intrinsics::unchecked_mul(x, y); diff --git a/src/test/ui/issues-71798.rs b/src/test/ui/issues-71798.rs index fde59f39b1c..14b6c0f3581 100644 --- a/src/test/ui/issues-71798.rs +++ b/src/test/ui/issues-71798.rs @@ -1,6 +1,5 @@ fn test_ref(x: &u32) -> impl std::future::Future<Output = u32> + '_ { //~^ ERROR `u32` is not a future - //~| ERROR `u32` is not a future *x } diff --git a/src/test/ui/issues-71798.stderr b/src/test/ui/issues-71798.stderr index 63669c0513d..ab72c3e41af 100644 --- a/src/test/ui/issues-71798.stderr +++ b/src/test/ui/issues-71798.stderr @@ -1,5 +1,5 @@ error[E0425]: cannot find value `u` in this scope - --> $DIR/issues-71798.rs:8:24 + --> $DIR/issues-71798.rs:7:24 | LL | let _ = test_ref & u; | ^ not found in this scope @@ -13,21 +13,7 @@ LL | fn test_ref(x: &u32) -> impl std::future::Future<Output = u32> + '_ { = help: the trait `Future` is not implemented for `u32` = note: u32 must be a future or must implement `IntoFuture` to be awaited -error[E0277]: `u32` is not a future - --> $DIR/issues-71798.rs:1:69 - | -LL | fn test_ref(x: &u32) -> impl std::future::Future<Output = u32> + '_ { - | _____________________________________________________________________^ -LL | | -LL | | -LL | | *x -LL | | } - | |_^ `u32` is not a future - | - = help: the trait `Future` is not implemented for `u32` - = note: u32 must be a future or must implement `IntoFuture` to be awaited - -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors Some errors have detailed explanations: E0277, E0425. For more information about an error, try `rustc --explain E0277`. diff --git a/src/test/ui/issues/issue-16922.nll.stderr b/src/test/ui/issues/issue-16922.nll.stderr index 7f4f5b22eb3..9d9f32a97c0 100644 --- a/src/test/ui/issues/issue-16922.nll.stderr +++ b/src/test/ui/issues/issue-16922.nll.stderr @@ -5,6 +5,11 @@ LL | fn foo<T: Any>(value: &T) -> Box<dyn Any> { | - let's call the lifetime of this reference `'1` LL | Box::new(value) as Box<dyn Any> | ^^^^^^^^^^^^^^^ cast requires that `'1` must outlive `'static` + | +help: to declare that the trait object captures data from argument `value`, you can add an explicit `'_` lifetime bound + | +LL | fn foo<T: Any>(value: &T) -> Box<dyn Any + '_> { + | ++++ error: aborting due to previous error diff --git a/src/test/ui/issues/issue-28776.thir.stderr b/src/test/ui/issues/issue-28776.thir.stderr index 1d470fb5e0f..e3562810b3a 100644 --- a/src/test/ui/issues/issue-28776.thir.stderr +++ b/src/test/ui/issues/issue-28776.thir.stderr @@ -1,4 +1,4 @@ -error[E0133]: call to unsafe function is unsafe and requires unsafe function or block +error[E0133]: call to unsafe function `std::ptr::write` is unsafe and requires unsafe function or block --> $DIR/issue-28776.rs:7:5 | LL | (&ptr::write)(1 as *mut _, 42); diff --git a/src/test/ui/issues/issue-29124.stderr b/src/test/ui/issues/issue-29124.stderr index 42d89cd01a4..c5d2ec08409 100644 --- a/src/test/ui/issues/issue-29124.stderr +++ b/src/test/ui/issues/issue-29124.stderr @@ -2,17 +2,17 @@ error[E0599]: no method named `x` found for fn item `fn() -> Ret {Obj::func}` in --> $DIR/issue-29124.rs:15:15 | LL | Obj::func.x(); - | ^ method not found in `fn() -> Ret {Obj::func}` - | - = note: `Obj::func` is a function, perhaps you wish to call it + | --------- ^ method not found in `fn() -> Ret {Obj::func}` + | | + | this is a function, perhaps you wish to call it error[E0599]: no method named `x` found for fn item `fn() -> Ret {func}` in the current scope --> $DIR/issue-29124.rs:17:10 | LL | func.x(); - | ^ method not found in `fn() -> Ret {func}` - | - = note: `func` is a function, perhaps you wish to call it + | ---- ^ method not found in `fn() -> Ret {func}` + | | + | this is a function, perhaps you wish to call it error: aborting due to 2 previous errors diff --git a/src/test/ui/issues/issue-30438-c.rs b/src/test/ui/issues/issue-30438-c.rs index 813c1d3e2cc..4cf634245be 100644 --- a/src/test/ui/issues/issue-30438-c.rs +++ b/src/test/ui/issues/issue-30438-c.rs @@ -5,6 +5,7 @@ trait Trait { type Out; } struct Test<'a> { s: &'a str } fn silly<'y, 'z>(_s: &'y Test<'z>) -> &'y <Test<'z> as Trait>::Out where 'z: 'static { + //~^ WARN unnecessary lifetime parameter `'z` let x = Test { s: "this cannot last" }; &x //~^ ERROR: cannot return reference to local variable `x` diff --git a/src/test/ui/issues/issue-30438-c.stderr b/src/test/ui/issues/issue-30438-c.stderr index 7c001088097..a7a5c0500fd 100644 --- a/src/test/ui/issues/issue-30438-c.stderr +++ b/src/test/ui/issues/issue-30438-c.stderr @@ -1,9 +1,17 @@ +warning: unnecessary lifetime parameter `'z` + --> $DIR/issue-30438-c.rs:7:74 + | +LL | fn silly<'y, 'z>(_s: &'y Test<'z>) -> &'y <Test<'z> as Trait>::Out where 'z: 'static { + | ^^ + | + = help: you can use the `'static` lifetime directly, in place of `'z` + error[E0515]: cannot return reference to local variable `x` - --> $DIR/issue-30438-c.rs:9:5 + --> $DIR/issue-30438-c.rs:10:5 | LL | &x | ^^ returns a reference to data owned by the current function -error: aborting due to previous error +error: aborting due to previous error; 1 warning emitted For more information about this error, try `rustc --explain E0515`. diff --git a/src/test/ui/issues/issue-3080.thir.stderr b/src/test/ui/issues/issue-3080.thir.stderr index f395c30b815..4d8acac61d9 100644 --- a/src/test/ui/issues/issue-3080.thir.stderr +++ b/src/test/ui/issues/issue-3080.thir.stderr @@ -1,4 +1,4 @@ -error[E0133]: call to unsafe function is unsafe and requires unsafe function or block +error[E0133]: call to unsafe function `X::with` is unsafe and requires unsafe function or block --> $DIR/issue-3080.rs:10:5 | LL | X(()).with(); diff --git a/src/test/ui/issues/issue-32709.stderr b/src/test/ui/issues/issue-32709.stderr index ed5addcbec5..112cb335932 100644 --- a/src/test/ui/issues/issue-32709.stderr +++ b/src/test/ui/issues/issue-32709.stderr @@ -7,7 +7,9 @@ LL | Err(5)?; | ^ the trait `From<{integer}>` is not implemented for `()` | = note: the question mark operation (`?`) implicitly performs a conversion on the error value using the `From` trait - = help: the trait `FromResidual<Result<Infallible, E>>` is implemented for `Result<T, F>` + = help: the following other types implement trait `FromResidual<R>`: + <Result<T, F> as FromResidual<Result<Infallible, E>>> + <Result<T, F> as FromResidual<Yeet<E>>> = note: required because of the requirements on the impl of `FromResidual<Result<Infallible, {integer}>>` for `Result<i32, ()>` error: aborting due to previous error diff --git a/src/test/ui/issues/issue-35668.stderr b/src/test/ui/issues/issue-35668.stderr index 04faea9008a..07409e9834a 100644 --- a/src/test/ui/issues/issue-35668.stderr +++ b/src/test/ui/issues/issue-35668.stderr @@ -6,10 +6,10 @@ LL | a.iter().map(|a| a*a) | | | &T | -help: consider restricting type parameter `T` +help: consider introducing a `where` bound, but there might be an alternative better way to express this requirement | -LL | fn func<'a, T: std::ops::Mul<Output = &T>>(a: &'a [T]) -> impl Iterator<Item=&'a T> { - | ++++++++++++++++++++++++++++ +LL | fn func<'a, T>(a: &'a [T]) -> impl Iterator<Item=&'a T> where &T: Mul<&T> { + | +++++++++++++++++ error: aborting due to previous error diff --git a/src/test/ui/issues/issue-57362-1.stderr b/src/test/ui/issues/issue-57362-1.stderr index 5c611cd43d3..8e19f14009a 100644 --- a/src/test/ui/issues/issue-57362-1.stderr +++ b/src/test/ui/issues/issue-57362-1.stderr @@ -2,9 +2,10 @@ error[E0599]: no method named `f` found for fn pointer `fn(&u8)` in the current --> $DIR/issue-57362-1.rs:20:7 | LL | a.f(); - | ^ method not found in `fn(&u8)` + | - ^ method not found in `fn(&u8)` + | | + | this is a function, perhaps you wish to call it | - = note: `a` is a function, perhaps you wish to call it = help: items from traits can only be used if the trait is implemented and in scope note: `Trait` defines an item `f`, perhaps you need to implement it --> $DIR/issue-57362-1.rs:8:1 diff --git a/src/test/ui/issues/issue-5844.thir.stderr b/src/test/ui/issues/issue-5844.thir.stderr index 6134d6889ff..310a2b593fe 100644 --- a/src/test/ui/issues/issue-5844.thir.stderr +++ b/src/test/ui/issues/issue-5844.thir.stderr @@ -1,4 +1,4 @@ -error[E0133]: call to unsafe function is unsafe and requires unsafe function or block +error[E0133]: call to unsafe function `rand` is unsafe and requires unsafe function or block --> $DIR/issue-5844.rs:8:5 | LL | issue_5844_aux::rand(); diff --git a/src/test/ui/iterators/collect-into-array.rs b/src/test/ui/iterators/collect-into-array.rs new file mode 100644 index 00000000000..a1144c8cb8c --- /dev/null +++ b/src/test/ui/iterators/collect-into-array.rs @@ -0,0 +1,7 @@ +fn main() { + //~^ NOTE required by a bound in this + let whatever: [u32; 10] = (0..10).collect(); + //~^ ERROR an array of type `[u32; 10]` cannot be built directly from an iterator + //~| NOTE try collecting into a `Vec<{integer}>`, then using `.try_into()` + //~| NOTE required by a bound in `collect` +} diff --git a/src/test/ui/iterators/collect-into-array.stderr b/src/test/ui/iterators/collect-into-array.stderr new file mode 100644 index 00000000000..7be53a4873b --- /dev/null +++ b/src/test/ui/iterators/collect-into-array.stderr @@ -0,0 +1,16 @@ +error[E0277]: an array of type `[u32; 10]` cannot be built directly from an iterator + --> $DIR/collect-into-array.rs:3:39 + | +LL | let whatever: [u32; 10] = (0..10).collect(); + | ^^^^^^^ try collecting into a `Vec<{integer}>`, then using `.try_into()` + | + = help: the trait `FromIterator<{integer}>` is not implemented for `[u32; 10]` +note: required by a bound in `collect` + --> $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL + | +LL | fn collect<B: FromIterator<Self::Item>>(self) -> B + | ^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `collect` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/iterators/collect-into-slice.rs b/src/test/ui/iterators/collect-into-slice.rs index 905752dec74..aafa6bc8b95 100644 --- a/src/test/ui/iterators/collect-into-slice.rs +++ b/src/test/ui/iterators/collect-into-slice.rs @@ -6,7 +6,7 @@ fn process_slice(data: &[i32]) { fn main() { let some_generated_vec = (0..10).collect(); //~^ ERROR the size for values of type `[i32]` cannot be known at compilation time - //~| ERROR a value of type `[i32]` cannot be built since `[i32]` has no definite size + //~| ERROR a slice of type `[i32]` cannot be built since `[i32]` has no definite size //~| NOTE try explicitly collecting into a `Vec<{integer}>` //~| NOTE required by a bound in `collect` //~| NOTE all local variables must have a statically known size diff --git a/src/test/ui/iterators/collect-into-slice.stderr b/src/test/ui/iterators/collect-into-slice.stderr index 521f239451d..4842e65fe97 100644 --- a/src/test/ui/iterators/collect-into-slice.stderr +++ b/src/test/ui/iterators/collect-into-slice.stderr @@ -8,7 +8,7 @@ LL | let some_generated_vec = (0..10).collect(); = note: all local variables must have a statically known size = help: unsized locals are gated as an unstable feature -error[E0277]: a value of type `[i32]` cannot be built since `[i32]` has no definite size +error[E0277]: a slice of type `[i32]` cannot be built since `[i32]` has no definite size --> $DIR/collect-into-slice.rs:7:38 | LL | let some_generated_vec = (0..10).collect(); diff --git a/src/test/ui/layout/issue-96158-scalarpair-payload-might-be-uninit.rs b/src/test/ui/layout/issue-96158-scalarpair-payload-might-be-uninit.rs new file mode 100644 index 00000000000..89387e01ba5 --- /dev/null +++ b/src/test/ui/layout/issue-96158-scalarpair-payload-might-be-uninit.rs @@ -0,0 +1,54 @@ +// normalize-stderr-test "pref: Align \{\n *pow2: [1-3],\n *\}" -> "pref: $$PREF_ALIGN" +#![crate_type = "lib"] +#![feature(rustc_attrs)] + +use std::mem::MaybeUninit; + +enum HasNiche { + A, + B, + C, +} + +// This should result in ScalarPair(Initialized, Union), +// since the u8 payload will be uninit for `None`. +#[rustc_layout(debug)] +pub enum MissingPayloadField { //~ ERROR: layout_of + Some(u8), + None +} + +// This should result in ScalarPair(Initialized, Initialized), +// since the u8 field is present in all variants, +// and hence will always be initialized. +#[rustc_layout(debug)] +pub enum CommonPayloadField { //~ ERROR: layout_of + A(u8), + B(u8), +} + +// This should result in ScalarPair(Initialized, Union), +// since, though a u8-sized field is present in all variants, it might be uninit. +#[rustc_layout(debug)] +pub enum CommonPayloadFieldIsMaybeUninit { //~ ERROR: layout_of + A(u8), + B(MaybeUninit<u8>), +} + +// This should result in ScalarPair(Initialized, Union), +// since only the niche field (used for the tag) is guaranteed to be initialized. +#[rustc_layout(debug)] +pub enum NicheFirst { //~ ERROR: layout_of + A(HasNiche, u8), + B, + C +} + +// This should result in ScalarPair(Union, Initialized), +// since only the niche field (used for the tag) is guaranteed to be initialized. +#[rustc_layout(debug)] +pub enum NicheSecond { //~ ERROR: layout_of + A(u8, HasNiche), + B, + C, +} diff --git a/src/test/ui/layout/issue-96158-scalarpair-payload-might-be-uninit.stderr b/src/test/ui/layout/issue-96158-scalarpair-payload-might-be-uninit.stderr new file mode 100644 index 00000000000..46187aae304 --- /dev/null +++ b/src/test/ui/layout/issue-96158-scalarpair-payload-might-be-uninit.stderr @@ -0,0 +1,720 @@ +error: layout_of(MissingPayloadField) = Layout { + fields: Arbitrary { + offsets: [ + Size { + raw: 0, + }, + ], + memory_index: [ + 0, + ], + }, + variants: Multiple { + tag: Initialized { + value: Int( + I8, + false, + ), + valid_range: 0..=1, + }, + tag_encoding: Direct, + tag_field: 0, + variants: [ + Layout { + fields: Arbitrary { + offsets: [ + Size { + raw: 1, + }, + ], + memory_index: [ + 0, + ], + }, + variants: Single { + index: 0, + }, + abi: Aggregate { + sized: true, + }, + largest_niche: None, + align: AbiAndPrefAlign { + abi: Align { + pow2: 0, + }, + pref: $PREF_ALIGN, + }, + size: Size { + raw: 2, + }, + }, + Layout { + fields: Arbitrary { + offsets: [], + memory_index: [], + }, + variants: Single { + index: 1, + }, + abi: Aggregate { + sized: true, + }, + largest_niche: None, + align: AbiAndPrefAlign { + abi: Align { + pow2: 0, + }, + pref: $PREF_ALIGN, + }, + size: Size { + raw: 1, + }, + }, + ], + }, + abi: ScalarPair( + Initialized { + value: Int( + I8, + false, + ), + valid_range: 0..=1, + }, + Union { + value: Int( + I8, + false, + ), + }, + ), + largest_niche: Some( + Niche { + offset: Size { + raw: 0, + }, + value: Int( + I8, + false, + ), + valid_range: 0..=1, + }, + ), + align: AbiAndPrefAlign { + abi: Align { + pow2: 0, + }, + pref: $PREF_ALIGN, + }, + size: Size { + raw: 2, + }, + } + --> $DIR/issue-96158-scalarpair-payload-might-be-uninit.rs:16:1 + | +LL | / pub enum MissingPayloadField { +LL | | Some(u8), +LL | | None +LL | | } + | |_^ + +error: layout_of(CommonPayloadField) = Layout { + fields: Arbitrary { + offsets: [ + Size { + raw: 0, + }, + ], + memory_index: [ + 0, + ], + }, + variants: Multiple { + tag: Initialized { + value: Int( + I8, + false, + ), + valid_range: 0..=1, + }, + tag_encoding: Direct, + tag_field: 0, + variants: [ + Layout { + fields: Arbitrary { + offsets: [ + Size { + raw: 1, + }, + ], + memory_index: [ + 0, + ], + }, + variants: Single { + index: 0, + }, + abi: Aggregate { + sized: true, + }, + largest_niche: None, + align: AbiAndPrefAlign { + abi: Align { + pow2: 0, + }, + pref: $PREF_ALIGN, + }, + size: Size { + raw: 2, + }, + }, + Layout { + fields: Arbitrary { + offsets: [ + Size { + raw: 1, + }, + ], + memory_index: [ + 0, + ], + }, + variants: Single { + index: 1, + }, + abi: Aggregate { + sized: true, + }, + largest_niche: None, + align: AbiAndPrefAlign { + abi: Align { + pow2: 0, + }, + pref: $PREF_ALIGN, + }, + size: Size { + raw: 2, + }, + }, + ], + }, + abi: ScalarPair( + Initialized { + value: Int( + I8, + false, + ), + valid_range: 0..=1, + }, + Initialized { + value: Int( + I8, + false, + ), + valid_range: 0..=255, + }, + ), + largest_niche: Some( + Niche { + offset: Size { + raw: 0, + }, + value: Int( + I8, + false, + ), + valid_range: 0..=1, + }, + ), + align: AbiAndPrefAlign { + abi: Align { + pow2: 0, + }, + pref: $PREF_ALIGN, + }, + size: Size { + raw: 2, + }, + } + --> $DIR/issue-96158-scalarpair-payload-might-be-uninit.rs:25:1 + | +LL | / pub enum CommonPayloadField { +LL | | A(u8), +LL | | B(u8), +LL | | } + | |_^ + +error: layout_of(CommonPayloadFieldIsMaybeUninit) = Layout { + fields: Arbitrary { + offsets: [ + Size { + raw: 0, + }, + ], + memory_index: [ + 0, + ], + }, + variants: Multiple { + tag: Initialized { + value: Int( + I8, + false, + ), + valid_range: 0..=1, + }, + tag_encoding: Direct, + tag_field: 0, + variants: [ + Layout { + fields: Arbitrary { + offsets: [ + Size { + raw: 1, + }, + ], + memory_index: [ + 0, + ], + }, + variants: Single { + index: 0, + }, + abi: Aggregate { + sized: true, + }, + largest_niche: None, + align: AbiAndPrefAlign { + abi: Align { + pow2: 0, + }, + pref: $PREF_ALIGN, + }, + size: Size { + raw: 2, + }, + }, + Layout { + fields: Arbitrary { + offsets: [ + Size { + raw: 1, + }, + ], + memory_index: [ + 0, + ], + }, + variants: Single { + index: 1, + }, + abi: Aggregate { + sized: true, + }, + largest_niche: None, + align: AbiAndPrefAlign { + abi: Align { + pow2: 0, + }, + pref: $PREF_ALIGN, + }, + size: Size { + raw: 2, + }, + }, + ], + }, + abi: ScalarPair( + Initialized { + value: Int( + I8, + false, + ), + valid_range: 0..=1, + }, + Union { + value: Int( + I8, + false, + ), + }, + ), + largest_niche: Some( + Niche { + offset: Size { + raw: 0, + }, + value: Int( + I8, + false, + ), + valid_range: 0..=1, + }, + ), + align: AbiAndPrefAlign { + abi: Align { + pow2: 0, + }, + pref: $PREF_ALIGN, + }, + size: Size { + raw: 2, + }, + } + --> $DIR/issue-96158-scalarpair-payload-might-be-uninit.rs:33:1 + | +LL | / pub enum CommonPayloadFieldIsMaybeUninit { +LL | | A(u8), +LL | | B(MaybeUninit<u8>), +LL | | } + | |_^ + +error: layout_of(NicheFirst) = Layout { + fields: Arbitrary { + offsets: [ + Size { + raw: 0, + }, + ], + memory_index: [ + 0, + ], + }, + variants: Multiple { + tag: Initialized { + value: Int( + I8, + false, + ), + valid_range: 0..=4, + }, + tag_encoding: Niche { + dataful_variant: 0, + niche_variants: 1..=2, + niche_start: 3, + }, + tag_field: 0, + variants: [ + Layout { + fields: Arbitrary { + offsets: [ + Size { + raw: 0, + }, + Size { + raw: 1, + }, + ], + memory_index: [ + 0, + 1, + ], + }, + variants: Single { + index: 0, + }, + abi: ScalarPair( + Initialized { + value: Int( + I8, + false, + ), + valid_range: 0..=2, + }, + Initialized { + value: Int( + I8, + false, + ), + valid_range: 0..=255, + }, + ), + largest_niche: Some( + Niche { + offset: Size { + raw: 0, + }, + value: Int( + I8, + false, + ), + valid_range: 0..=2, + }, + ), + align: AbiAndPrefAlign { + abi: Align { + pow2: 0, + }, + pref: $PREF_ALIGN, + }, + size: Size { + raw: 2, + }, + }, + Layout { + fields: Arbitrary { + offsets: [], + memory_index: [], + }, + variants: Single { + index: 1, + }, + abi: Aggregate { + sized: true, + }, + largest_niche: None, + align: AbiAndPrefAlign { + abi: Align { + pow2: 0, + }, + pref: $PREF_ALIGN, + }, + size: Size { + raw: 0, + }, + }, + Layout { + fields: Arbitrary { + offsets: [], + memory_index: [], + }, + variants: Single { + index: 2, + }, + abi: Aggregate { + sized: true, + }, + largest_niche: None, + align: AbiAndPrefAlign { + abi: Align { + pow2: 0, + }, + pref: $PREF_ALIGN, + }, + size: Size { + raw: 0, + }, + }, + ], + }, + abi: ScalarPair( + Initialized { + value: Int( + I8, + false, + ), + valid_range: 0..=4, + }, + Union { + value: Int( + I8, + false, + ), + }, + ), + largest_niche: Some( + Niche { + offset: Size { + raw: 0, + }, + value: Int( + I8, + false, + ), + valid_range: 0..=4, + }, + ), + align: AbiAndPrefAlign { + abi: Align { + pow2: 0, + }, + pref: $PREF_ALIGN, + }, + size: Size { + raw: 2, + }, + } + --> $DIR/issue-96158-scalarpair-payload-might-be-uninit.rs:41:1 + | +LL | / pub enum NicheFirst { +LL | | A(HasNiche, u8), +LL | | B, +LL | | C +LL | | } + | |_^ + +error: layout_of(NicheSecond) = Layout { + fields: Arbitrary { + offsets: [ + Size { + raw: 1, + }, + ], + memory_index: [ + 0, + ], + }, + variants: Multiple { + tag: Initialized { + value: Int( + I8, + false, + ), + valid_range: 0..=4, + }, + tag_encoding: Niche { + dataful_variant: 0, + niche_variants: 1..=2, + niche_start: 3, + }, + tag_field: 0, + variants: [ + Layout { + fields: Arbitrary { + offsets: [ + Size { + raw: 0, + }, + Size { + raw: 1, + }, + ], + memory_index: [ + 0, + 1, + ], + }, + variants: Single { + index: 0, + }, + abi: ScalarPair( + Initialized { + value: Int( + I8, + false, + ), + valid_range: 0..=255, + }, + Initialized { + value: Int( + I8, + false, + ), + valid_range: 0..=2, + }, + ), + largest_niche: Some( + Niche { + offset: Size { + raw: 1, + }, + value: Int( + I8, + false, + ), + valid_range: 0..=2, + }, + ), + align: AbiAndPrefAlign { + abi: Align { + pow2: 0, + }, + pref: $PREF_ALIGN, + }, + size: Size { + raw: 2, + }, + }, + Layout { + fields: Arbitrary { + offsets: [], + memory_index: [], + }, + variants: Single { + index: 1, + }, + abi: Aggregate { + sized: true, + }, + largest_niche: None, + align: AbiAndPrefAlign { + abi: Align { + pow2: 0, + }, + pref: $PREF_ALIGN, + }, + size: Size { + raw: 0, + }, + }, + Layout { + fields: Arbitrary { + offsets: [], + memory_index: [], + }, + variants: Single { + index: 2, + }, + abi: Aggregate { + sized: true, + }, + largest_niche: None, + align: AbiAndPrefAlign { + abi: Align { + pow2: 0, + }, + pref: $PREF_ALIGN, + }, + size: Size { + raw: 0, + }, + }, + ], + }, + abi: ScalarPair( + Union { + value: Int( + I8, + false, + ), + }, + Initialized { + value: Int( + I8, + false, + ), + valid_range: 0..=4, + }, + ), + largest_niche: Some( + Niche { + offset: Size { + raw: 1, + }, + value: Int( + I8, + false, + ), + valid_range: 0..=4, + }, + ), + align: AbiAndPrefAlign { + abi: Align { + pow2: 0, + }, + pref: $PREF_ALIGN, + }, + size: Size { + raw: 2, + }, + } + --> $DIR/issue-96158-scalarpair-payload-might-be-uninit.rs:50:1 + | +LL | / pub enum NicheSecond { +LL | | A(u8, HasNiche), +LL | | B, +LL | | C, +LL | | } + | |_^ + +error: aborting due to 5 previous errors + diff --git a/src/test/ui/lifetimes/copy_modulo_regions.rs b/src/test/ui/lifetimes/copy_modulo_regions.rs new file mode 100644 index 00000000000..1d5d90ffcb4 --- /dev/null +++ b/src/test/ui/lifetimes/copy_modulo_regions.rs @@ -0,0 +1,19 @@ +#![feature(nll)] + +#[derive(Clone)] +struct Foo<'a>(fn(&'a ()) -> &'a ()); + +impl Copy for Foo<'static> {} + +fn mk_foo<'a>() -> Foo<'a> { + println!("mk_foo"); + Foo(|x| x) +} + +fn foo<'a>() -> [Foo<'a>; 100] { + [mk_foo::<'a>(); 100] //~ ERROR lifetime may not live long enough +} + +fn main() { + foo(); +} diff --git a/src/test/ui/lifetimes/copy_modulo_regions.stderr b/src/test/ui/lifetimes/copy_modulo_regions.stderr new file mode 100644 index 00000000000..e027bc45426 --- /dev/null +++ b/src/test/ui/lifetimes/copy_modulo_regions.stderr @@ -0,0 +1,14 @@ +error: lifetime may not live long enough + --> $DIR/copy_modulo_regions.rs:14:5 + | +LL | fn foo<'a>() -> [Foo<'a>; 100] { + | -- lifetime `'a` defined here +LL | [mk_foo::<'a>(); 100] + | ^^^^^^^^^^^^^^^^^^^^^ returning this value requires that `'a` must outlive `'static` + | + = note: requirement occurs because of the type `Foo<'_>`, which makes the generic argument `'_` invariant + = note: the struct `Foo<'a>` is invariant over the parameter `'a` + = help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance + +error: aborting due to previous error + diff --git a/src/test/ui/lifetimes/elided-lifetime-in-path-in-impl-Fn.rs b/src/test/ui/lifetimes/elided-lifetime-in-path-in-impl-Fn.rs new file mode 100644 index 00000000000..9c9965d8fb8 --- /dev/null +++ b/src/test/ui/lifetimes/elided-lifetime-in-path-in-impl-Fn.rs @@ -0,0 +1,19 @@ +// check-pass + +struct Foo<'a>(&'a ()); + +fn with_fn() -> fn(Foo) { + |_| () +} + +fn with_impl_fn() -> impl Fn(Foo) { + |_| () +} + +fn with_where_fn<T>() +where + T: Fn(Foo), +{ +} + +fn main() {} diff --git a/src/test/ui/lifetimes/issue-90170-elision-mismatch.nll.stderr b/src/test/ui/lifetimes/issue-90170-elision-mismatch.nll.stderr index a5bc7450bbf..48fb3fb4a22 100644 --- a/src/test/ui/lifetimes/issue-90170-elision-mismatch.nll.stderr +++ b/src/test/ui/lifetimes/issue-90170-elision-mismatch.nll.stderr @@ -6,6 +6,11 @@ LL | pub fn foo(x: &mut Vec<&u8>, y: &u8) { x.push(y); } | | | | | let's call the lifetime of this reference `'1` | let's call the lifetime of this reference `'2` + | +help: consider introducing a named lifetime parameter + | +LL | pub fn foo<'a>(x: &mut Vec<&'a u8>, y: &'a u8) { x.push(y); } + | ++++ ++ ++ error: lifetime may not live long enough --> $DIR/issue-90170-elision-mismatch.rs:5:44 @@ -15,6 +20,11 @@ LL | pub fn foo2(x: &mut Vec<&'_ u8>, y: &u8) { x.push(y); } | | | | | let's call the lifetime of this reference `'1` | let's call the lifetime of this reference `'2` + | +help: consider introducing a named lifetime parameter + | +LL | pub fn foo2<'a>(x: &mut Vec<&'a u8>, y: &'a u8) { x.push(y); } + | ++++ ~~ ++ error: lifetime may not live long enough --> $DIR/issue-90170-elision-mismatch.rs:7:63 @@ -24,6 +34,11 @@ LL | pub fn foo3<'a>(_other: &'a [u8], x: &mut Vec<&u8>, y: &u8) { x.push(y); } | | | | | let's call the lifetime of this reference `'1` | let's call the lifetime of this reference `'2` + | +help: consider introducing a named lifetime parameter + | +LL | pub fn foo3<'a>(_other: &'a [u8], x: &mut Vec<&'a u8>, y: &'a u8) { x.push(y); } + | ++ ++ error: aborting due to 3 previous errors diff --git a/src/test/ui/lifetimes/lifetime-doesnt-live-long-enough.stderr b/src/test/ui/lifetimes/lifetime-doesnt-live-long-enough.stderr index e5083e3a088..33f6c498b6f 100644 --- a/src/test/ui/lifetimes/lifetime-doesnt-live-long-enough.stderr +++ b/src/test/ui/lifetimes/lifetime-doesnt-live-long-enough.stderr @@ -1,18 +1,24 @@ error[E0310]: the parameter type `T` may not live long enough --> $DIR/lifetime-doesnt-live-long-enough.rs:19:10 | -LL | struct Foo<T> { - | - help: consider adding an explicit lifetime bound...: `T: 'static` LL | foo: &'static T | ^^^^^^^^^^ ...so that the reference type `&'static T` does not outlive the data it points at + | +help: consider adding an explicit lifetime bound... + | +LL | struct Foo<T: 'static> { + | +++++++++ error[E0309]: the parameter type `K` may not live long enough --> $DIR/lifetime-doesnt-live-long-enough.rs:24:19 | -LL | trait X<K>: Sized { - | - help: consider adding an explicit lifetime bound...: `K: 'a` LL | fn foo<'a, L: X<&'a Nested<K>>>(); | ^^^^^^^^^^^^^^^^ ...so that the reference type `&'a Nested<K>` does not outlive the data it points at + | +help: consider adding an explicit lifetime bound... + | +LL | trait X<K: 'a>: Sized { + | ++++ error[E0309]: the parameter type `Self` may not live long enough --> $DIR/lifetime-doesnt-live-long-enough.rs:28:19 @@ -27,25 +33,34 @@ error[E0309]: the parameter type `L` may not live long enough --> $DIR/lifetime-doesnt-live-long-enough.rs:32:22 | LL | fn baz<'a, L, M: X<&'a Nested<L>>>() { - | - ^^^^^^^^^^^^^^^^ ...so that the reference type `&'a Nested<L>` does not outlive the data it points at - | | - | help: consider adding an explicit lifetime bound...: `L: 'a` + | ^^^^^^^^^^^^^^^^ ...so that the reference type `&'a Nested<L>` does not outlive the data it points at + | +help: consider adding an explicit lifetime bound... + | +LL | fn baz<'a, L: 'a, M: X<&'a Nested<L>>>() { + | ++++ error[E0309]: the parameter type `K` may not live long enough --> $DIR/lifetime-doesnt-live-long-enough.rs:41:33 | -LL | impl<K> Nested<K> { - | - help: consider adding an explicit lifetime bound...: `K: 'a` LL | fn generic_in_parent<'a, L: X<&'a Nested<K>>>() { | ^^^^^^^^^^^^^^^^ ...so that the reference type `&'a Nested<K>` does not outlive the data it points at + | +help: consider adding an explicit lifetime bound... + | +LL | impl<K: 'a> Nested<K> { + | ++++ error[E0309]: the parameter type `M` may not live long enough --> $DIR/lifetime-doesnt-live-long-enough.rs:44:36 | LL | fn generic_in_child<'a, 'b, L: X<&'a Nested<M>>, M: 'b>() { - | ^^^^^^^^^^^^^^^^ -- help: consider adding an explicit lifetime bound...: `M: 'a +` - | | - | ...so that the reference type `&'a Nested<M>` does not outlive the data it points at + | ^^^^^^^^^^^^^^^^ ...so that the reference type `&'a Nested<M>` does not outlive the data it points at + | +help: consider adding an explicit lifetime bound... + | +LL | fn generic_in_child<'a, 'b, L: X<&'a Nested<M>>, M: 'b + 'a>() { + | ++++ error: aborting due to 6 previous errors diff --git a/src/test/ui/lifetimes/lifetime-elision-return-type-trait.rs b/src/test/ui/lifetimes/lifetime-elision-return-type-trait.rs index 133679f30f8..5168cb20d9e 100644 --- a/src/test/ui/lifetimes/lifetime-elision-return-type-trait.rs +++ b/src/test/ui/lifetimes/lifetime-elision-return-type-trait.rs @@ -7,7 +7,6 @@ use std::error::Error; fn foo() -> impl Future<Item=(), Error=Box<dyn Error>> { //~^ ERROR not satisfied - //~| ERROR not satisfied Ok(()) } diff --git a/src/test/ui/lifetimes/lifetime-elision-return-type-trait.stderr b/src/test/ui/lifetimes/lifetime-elision-return-type-trait.stderr index a3badd7b25a..ef1127c59ac 100644 --- a/src/test/ui/lifetimes/lifetime-elision-return-type-trait.stderr +++ b/src/test/ui/lifetimes/lifetime-elision-return-type-trait.stderr @@ -4,17 +4,6 @@ error[E0277]: the trait bound `Result<(), _>: Future` is not satisfied LL | fn foo() -> impl Future<Item=(), Error=Box<dyn Error>> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Future` is not implemented for `Result<(), _>` -error[E0277]: the trait bound `Result<(), _>: Future` is not satisfied - --> $DIR/lifetime-elision-return-type-trait.rs:8:56 - | -LL | fn foo() -> impl Future<Item=(), Error=Box<dyn Error>> { - | ________________________________________________________^ -LL | | -LL | | -LL | | Ok(()) -LL | | } - | |_^ the trait `Future` is not implemented for `Result<(), _>` - -error: aborting due to 2 previous errors +error: aborting due to previous error For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-2.nll.stderr b/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-2.nll.stderr index a94f9a79906..5a23f1e0e9d 100644 --- a/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-2.nll.stderr +++ b/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-2.nll.stderr @@ -7,6 +7,11 @@ LL | fn foo(&mut (ref mut v, w): &mut (&u8, &u8), x: &u8) { | let's call the lifetime of this reference `'2` LL | *v = x; | ^^^^^^ assignment requires that `'1` must outlive `'2` + | +help: consider introducing a named lifetime parameter + | +LL | fn foo<'a>(&mut (ref mut v, w): &mut (&'a u8, &u8), x: &'a u8) { + | ++++ ++ ++ error: aborting due to previous error diff --git a/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-3.nll.stderr b/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-3.nll.stderr index 2ed4d6d4401..6ba130308a3 100644 --- a/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-3.nll.stderr +++ b/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-3.nll.stderr @@ -7,6 +7,11 @@ LL | fn foo(z: &mut Vec<(&u8,&u8)>, (x, y): (&u8, &u8)) { | let's call the lifetime of this reference `'2` LL | z.push((x,y)); | ^^^^^^^^^^^^^ argument requires that `'1` must outlive `'2` + | +help: consider introducing a named lifetime parameter + | +LL | fn foo<'a>(z: &mut Vec<(&'a u8,&u8)>, (x, y): (&'a u8, &u8)) { + | ++++ ++ ++ error: lifetime may not live long enough --> $DIR/ex3-both-anon-regions-3.rs:2:5 @@ -17,6 +22,11 @@ LL | fn foo(z: &mut Vec<(&u8,&u8)>, (x, y): (&u8, &u8)) { | let's call the lifetime of this reference `'4` LL | z.push((x,y)); | ^^^^^^^^^^^^^ argument requires that `'3` must outlive `'4` + | +help: consider introducing a named lifetime parameter + | +LL | fn foo<'a>(z: &mut Vec<(&u8,&'a u8)>, (x, y): (&u8, &'a u8)) { + | ++++ ++ ++ error: aborting due to 2 previous errors diff --git a/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-return-type-is-anon.nll.stderr b/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-return-type-is-anon.nll.stderr index 1a19e81f235..5601335d275 100644 --- a/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-return-type-is-anon.nll.stderr +++ b/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-return-type-is-anon.nll.stderr @@ -7,6 +7,11 @@ LL | fn foo<'a>(&self, x: &i32) -> &i32 { | let's call the lifetime of this reference `'2` LL | x | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | +help: consider introducing a named lifetime parameter and update trait if needed + | +LL | fn foo<'a>(&'a self, x: &'a i32) -> &i32 { + | ++ ++ error: aborting due to previous error diff --git a/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-self-is-anon.nll.stderr b/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-self-is-anon.nll.stderr index 87b13dc1591..e221902c4a9 100644 --- a/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-self-is-anon.nll.stderr +++ b/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-self-is-anon.nll.stderr @@ -7,6 +7,11 @@ LL | fn foo<'a>(&self, x: &Foo) -> &Foo { | let's call the lifetime of this reference `'2` LL | if true { x } else { self } | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | +help: consider introducing a named lifetime parameter and update trait if needed + | +LL | fn foo<'a>(&'a self, x: &'a Foo) -> &Foo { + | ++ ++ error: aborting due to previous error diff --git a/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-using-fn-items.nll.stderr b/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-using-fn-items.nll.stderr index 825c45b2434..a909c5fa823 100644 --- a/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-using-fn-items.nll.stderr +++ b/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-using-fn-items.nll.stderr @@ -7,6 +7,11 @@ LL | fn foo(x:fn(&u8, &u8), y: Vec<&u8>, z: &u8) { | let's call the lifetime of this reference `'2` LL | y.push(z); | ^^^^^^^^^ argument requires that `'1` must outlive `'2` + | +help: consider introducing a named lifetime parameter + | +LL | fn foo<'a>(x:fn(&u8, &u8), y: Vec<&'a u8>, z: &'a u8) { + | ++++ ++ ++ error[E0596]: cannot borrow `y` as mutable, as it is not declared as mutable --> $DIR/ex3-both-anon-regions-using-fn-items.rs:2:3 diff --git a/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-using-impl-items.nll.stderr b/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-using-impl-items.nll.stderr index f3502674849..9661f1e5144 100644 --- a/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-using-impl-items.nll.stderr +++ b/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-using-impl-items.nll.stderr @@ -7,6 +7,11 @@ LL | fn foo(x: &mut Vec<&u8>, y: &u8) { | let's call the lifetime of this reference `'2` LL | x.push(y); | ^^^^^^^^^ argument requires that `'1` must outlive `'2` + | +help: consider introducing a named lifetime parameter and update trait if needed + | +LL | fn foo<'a>(x: &mut Vec<&'a u8>, y: &'a u8) { + | ++++ ++ ++ error: aborting due to previous error diff --git a/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-using-trait-objects.nll.stderr b/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-using-trait-objects.nll.stderr index 78a828dde86..cce0a31bfbb 100644 --- a/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-using-trait-objects.nll.stderr +++ b/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions-using-trait-objects.nll.stderr @@ -7,6 +7,11 @@ LL | fn foo(x:Box<dyn Fn(&u8, &u8)> , y: Vec<&u8>, z: &u8) { | let's call the lifetime of this reference `'2` LL | y.push(z); | ^^^^^^^^^ argument requires that `'1` must outlive `'2` + | +help: consider introducing a named lifetime parameter + | +LL | fn foo<'a>(x:Box<dyn Fn(&'a u8, &'a u8)> , y: Vec<&u8>, z: &u8) { + | ++++ ++ ++ error[E0596]: cannot borrow `y` as mutable, as it is not declared as mutable --> $DIR/ex3-both-anon-regions-using-trait-objects.rs:2:3 diff --git a/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions.nll.stderr b/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions.nll.stderr index 6989acfa196..ec9fac0c288 100644 --- a/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions.nll.stderr +++ b/src/test/ui/lifetimes/lifetime-errors/ex3-both-anon-regions.nll.stderr @@ -7,6 +7,11 @@ LL | fn foo(x: &mut Vec<&u8>, y: &u8) { | let's call the lifetime of this reference `'2` LL | x.push(y); | ^^^^^^^^^ argument requires that `'1` must outlive `'2` + | +help: consider introducing a named lifetime parameter + | +LL | fn foo<'a>(x: &mut Vec<&'a u8>, y: &'a u8) { + | ++++ ++ ++ error: aborting due to previous error diff --git a/src/test/ui/lifetimes/lifetime-errors/issue_74400.nll.stderr b/src/test/ui/lifetimes/lifetime-errors/issue_74400.nll.stderr index 5509226cb1c..2906c05864b 100644 --- a/src/test/ui/lifetimes/lifetime-errors/issue_74400.nll.stderr +++ b/src/test/ui/lifetimes/lifetime-errors/issue_74400.nll.stderr @@ -2,9 +2,12 @@ error[E0310]: the parameter type `T` may not live long enough --> $DIR/issue_74400.rs:12:5 | LL | f(data, identity) - | ^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds | - = help: consider adding an explicit lifetime bound `T: 'static`... +help: consider adding an explicit lifetime bound... + | +LL | fn g<T: 'static>(data: &[T]) { + | +++++++++ error[E0308]: mismatched types --> $DIR/issue_74400.rs:12:5 diff --git a/src/test/ui/issues/issue-1866.rs b/src/test/ui/lint/issue-1866.rs index caac0c50414..caac0c50414 100644 --- a/src/test/ui/issues/issue-1866.rs +++ b/src/test/ui/lint/issue-1866.rs diff --git a/src/test/ui/issues/issue-1866.stderr b/src/test/ui/lint/issue-1866.stderr index 5edae48a10f..5edae48a10f 100644 --- a/src/test/ui/issues/issue-1866.stderr +++ b/src/test/ui/lint/issue-1866.stderr diff --git a/src/test/ui/issues/issue-20343.rs b/src/test/ui/lint/issue-20343.rs index 000b6398442..000b6398442 100644 --- a/src/test/ui/issues/issue-20343.rs +++ b/src/test/ui/lint/issue-20343.rs diff --git a/src/test/ui/lint/unreachable_pub-pub_crate.rs b/src/test/ui/lint/unreachable_pub-pub_crate.rs index 27c31c22311..4dc951985ae 100644 --- a/src/test/ui/lint/unreachable_pub-pub_crate.rs +++ b/src/test/ui/lint/unreachable_pub-pub_crate.rs @@ -26,6 +26,11 @@ mod private_mod { pub fn count_neutrons(&self) -> usize { self.neutrons } //~ WARNING unreachable_pub pub(crate) fn count_electrons(&self) -> usize { self.electrons } } + impl Clone for Hydrogen { + fn clone(&self) -> Hydrogen { + Hydrogen { neutrons: self.neutrons, electrons: self.electrons } + } + } pub enum Helium {} //~ WARNING unreachable_pub pub union Lithium { c1: usize, c2: u8 } //~ WARNING unreachable_pub diff --git a/src/test/ui/lint/unreachable_pub-pub_crate.stderr b/src/test/ui/lint/unreachable_pub-pub_crate.stderr index f284db80ff9..6c05a030138 100644 --- a/src/test/ui/lint/unreachable_pub-pub_crate.stderr +++ b/src/test/ui/lint/unreachable_pub-pub_crate.stderr @@ -50,7 +50,7 @@ LL | pub fn count_neutrons(&self) -> usize { self.neutrons } | help: consider restricting its visibility: `pub(crate)` warning: unreachable `pub` item - --> $DIR/unreachable_pub-pub_crate.rs:30:5 + --> $DIR/unreachable_pub-pub_crate.rs:35:5 | LL | pub enum Helium {} | ---^^^^^^^^^^^^ @@ -60,7 +60,7 @@ LL | pub enum Helium {} = help: or consider exporting it for use by other crates warning: unreachable `pub` item - --> $DIR/unreachable_pub-pub_crate.rs:31:5 + --> $DIR/unreachable_pub-pub_crate.rs:36:5 | LL | pub union Lithium { c1: usize, c2: u8 } | ---^^^^^^^^^^^^^^ @@ -70,7 +70,7 @@ LL | pub union Lithium { c1: usize, c2: u8 } = help: or consider exporting it for use by other crates warning: unreachable `pub` item - --> $DIR/unreachable_pub-pub_crate.rs:32:5 + --> $DIR/unreachable_pub-pub_crate.rs:37:5 | LL | pub fn beryllium() {} | ---^^^^^^^^^^^^^^^ @@ -80,7 +80,7 @@ LL | pub fn beryllium() {} = help: or consider exporting it for use by other crates warning: unreachable `pub` item - --> $DIR/unreachable_pub-pub_crate.rs:33:5 + --> $DIR/unreachable_pub-pub_crate.rs:38:5 | LL | pub trait Boron {} | ---^^^^^^^^^^^^ @@ -90,7 +90,7 @@ LL | pub trait Boron {} = help: or consider exporting it for use by other crates warning: unreachable `pub` item - --> $DIR/unreachable_pub-pub_crate.rs:34:5 + --> $DIR/unreachable_pub-pub_crate.rs:39:5 | LL | pub const CARBON: usize = 1; | ---^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -100,7 +100,7 @@ LL | pub const CARBON: usize = 1; = help: or consider exporting it for use by other crates warning: unreachable `pub` item - --> $DIR/unreachable_pub-pub_crate.rs:35:5 + --> $DIR/unreachable_pub-pub_crate.rs:40:5 | LL | pub static NITROGEN: usize = 2; | ---^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -110,7 +110,7 @@ LL | pub static NITROGEN: usize = 2; = help: or consider exporting it for use by other crates warning: unreachable `pub` item - --> $DIR/unreachable_pub-pub_crate.rs:36:5 + --> $DIR/unreachable_pub-pub_crate.rs:41:5 | LL | pub type Oxygen = bool; | ---^^^^^^^^^^^^^^^^^^^^ @@ -120,7 +120,7 @@ LL | pub type Oxygen = bool; = help: or consider exporting it for use by other crates warning: unreachable `pub` item - --> $DIR/unreachable_pub-pub_crate.rs:39:47 + --> $DIR/unreachable_pub-pub_crate.rs:44:47 | LL | ($visibility: vis, $name: ident) => { $visibility struct $name {} } | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -135,7 +135,7 @@ LL | define_empty_struct_with_visibility!(pub, Fluorine); = note: this warning originates in the macro `define_empty_struct_with_visibility` (in Nightly builds, run with -Z macro-backtrace for more info) warning: unreachable `pub` item - --> $DIR/unreachable_pub-pub_crate.rs:45:9 + --> $DIR/unreachable_pub-pub_crate.rs:50:9 | LL | pub fn catalyze() -> bool; | ---^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/lint/unreachable_pub.rs b/src/test/ui/lint/unreachable_pub.rs index 6bfec0ec5e8..39e2b596156 100644 --- a/src/test/ui/lint/unreachable_pub.rs +++ b/src/test/ui/lint/unreachable_pub.rs @@ -22,6 +22,11 @@ mod private_mod { pub fn count_neutrons(&self) -> usize { self.neutrons } //~ WARNING unreachable_pub crate fn count_electrons(&self) -> usize { self.electrons } } + impl Clone for Hydrogen { + fn clone(&self) -> Hydrogen { + Hydrogen { neutrons: self.neutrons, electrons: self.electrons } + } + } pub enum Helium {} //~ WARNING unreachable_pub pub union Lithium { c1: usize, c2: u8 } //~ WARNING unreachable_pub diff --git a/src/test/ui/lint/unreachable_pub.stderr b/src/test/ui/lint/unreachable_pub.stderr index 61c9582287c..e8e55be5a47 100644 --- a/src/test/ui/lint/unreachable_pub.stderr +++ b/src/test/ui/lint/unreachable_pub.stderr @@ -50,7 +50,7 @@ LL | pub fn count_neutrons(&self) -> usize { self.neutrons } | help: consider restricting its visibility: `crate` warning: unreachable `pub` item - --> $DIR/unreachable_pub.rs:26:5 + --> $DIR/unreachable_pub.rs:31:5 | LL | pub enum Helium {} | ---^^^^^^^^^^^^ @@ -60,7 +60,7 @@ LL | pub enum Helium {} = help: or consider exporting it for use by other crates warning: unreachable `pub` item - --> $DIR/unreachable_pub.rs:27:5 + --> $DIR/unreachable_pub.rs:32:5 | LL | pub union Lithium { c1: usize, c2: u8 } | ---^^^^^^^^^^^^^^ @@ -70,7 +70,7 @@ LL | pub union Lithium { c1: usize, c2: u8 } = help: or consider exporting it for use by other crates warning: unreachable `pub` item - --> $DIR/unreachable_pub.rs:28:5 + --> $DIR/unreachable_pub.rs:33:5 | LL | pub fn beryllium() {} | ---^^^^^^^^^^^^^^^ @@ -80,7 +80,7 @@ LL | pub fn beryllium() {} = help: or consider exporting it for use by other crates warning: unreachable `pub` item - --> $DIR/unreachable_pub.rs:29:5 + --> $DIR/unreachable_pub.rs:34:5 | LL | pub trait Boron {} | ---^^^^^^^^^^^^ @@ -90,7 +90,7 @@ LL | pub trait Boron {} = help: or consider exporting it for use by other crates warning: unreachable `pub` item - --> $DIR/unreachable_pub.rs:30:5 + --> $DIR/unreachable_pub.rs:35:5 | LL | pub const CARBON: usize = 1; | ---^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -100,7 +100,7 @@ LL | pub const CARBON: usize = 1; = help: or consider exporting it for use by other crates warning: unreachable `pub` item - --> $DIR/unreachable_pub.rs:31:5 + --> $DIR/unreachable_pub.rs:36:5 | LL | pub static NITROGEN: usize = 2; | ---^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -110,7 +110,7 @@ LL | pub static NITROGEN: usize = 2; = help: or consider exporting it for use by other crates warning: unreachable `pub` item - --> $DIR/unreachable_pub.rs:32:5 + --> $DIR/unreachable_pub.rs:37:5 | LL | pub type Oxygen = bool; | ---^^^^^^^^^^^^^^^^^^^^ @@ -120,7 +120,7 @@ LL | pub type Oxygen = bool; = help: or consider exporting it for use by other crates warning: unreachable `pub` item - --> $DIR/unreachable_pub.rs:35:47 + --> $DIR/unreachable_pub.rs:40:47 | LL | ($visibility: vis, $name: ident) => { $visibility struct $name {} } | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -135,7 +135,7 @@ LL | define_empty_struct_with_visibility!(pub, Fluorine); = note: this warning originates in the macro `define_empty_struct_with_visibility` (in Nightly builds, run with -Z macro-backtrace for more info) warning: unreachable `pub` item - --> $DIR/unreachable_pub.rs:41:9 + --> $DIR/unreachable_pub.rs:46:9 | LL | pub fn catalyze() -> bool; | ---^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/issues/issue-41776.rs b/src/test/ui/macros/issue-41776.rs index 24696d86d0f..24696d86d0f 100644 --- a/src/test/ui/issues/issue-41776.rs +++ b/src/test/ui/macros/issue-41776.rs diff --git a/src/test/ui/issues/issue-41776.stderr b/src/test/ui/macros/issue-41776.stderr index e06873b5026..e06873b5026 100644 --- a/src/test/ui/issues/issue-41776.stderr +++ b/src/test/ui/macros/issue-41776.stderr diff --git a/src/test/ui/issues/issue-44127.rs b/src/test/ui/macros/issue-44127.rs index 21b2e68264a..21b2e68264a 100644 --- a/src/test/ui/issues/issue-44127.rs +++ b/src/test/ui/macros/issue-44127.rs diff --git a/src/test/ui/macros/trace-macro.stderr b/src/test/ui/macros/trace-macro.stderr index c8a0fd68430..43272248c28 100644 --- a/src/test/ui/macros/trace-macro.stderr +++ b/src/test/ui/macros/trace-macro.stderr @@ -5,5 +5,5 @@ LL | println!("Hello, World!"); | ^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: expanding `println! { "Hello, World!" }` - = note: to `$crate :: io :: _print($crate :: format_args_nl! ("Hello, World!"))` + = note: to `{ $crate :: io :: _print($crate :: format_args_nl! ("Hello, World!")) ; }` diff --git a/src/test/ui/match/issue-82392.stdout b/src/test/ui/match/issue-82392.stdout index bcab76b7c6b..ffe73074324 100644 --- a/src/test/ui/match/issue-82392.stdout +++ b/src/test/ui/match/issue-82392.stdout @@ -6,7 +6,7 @@ extern crate std; // compile-flags: -Zunpretty=hir,typed // check-pass -pub fn main() ({ +fn main() ({ (if (true as bool) ({ } as ()) else if (let Some(a) = diff --git a/src/test/ui/methods/issues/issue-90315.rs b/src/test/ui/methods/issues/issue-90315.rs new file mode 100644 index 00000000000..01bf9f48402 --- /dev/null +++ b/src/test/ui/methods/issues/issue-90315.rs @@ -0,0 +1,7 @@ +fn main() { + let arr = &[0,1,2,3]; + for _i in 0..arr.len().rev() { //~ERROR not an iterator + // The above error used to say “the method `rev` exists for type `usize`”. + // This regression test ensures it doesn't say that any more. + } +} diff --git a/src/test/ui/methods/issues/issue-90315.stderr b/src/test/ui/methods/issues/issue-90315.stderr new file mode 100644 index 00000000000..c6a76c9e790 --- /dev/null +++ b/src/test/ui/methods/issues/issue-90315.stderr @@ -0,0 +1,13 @@ +error[E0599]: `usize` is not an iterator + --> $DIR/issue-90315.rs:3:26 + | +LL | for _i in 0..arr.len().rev() { + | ^^^ `usize` is not an iterator + | + = note: the following trait bounds were not satisfied: + `usize: Iterator` + which is required by `&mut usize: Iterator` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0599`. diff --git a/src/test/ui/moves/use_of_moved_value_copy_suggestions.fixed b/src/test/ui/moves/use_of_moved_value_copy_suggestions.fixed index fb6cf7e8996..ba1b745ba84 100644 --- a/src/test/ui/moves/use_of_moved_value_copy_suggestions.fixed +++ b/src/test/ui/moves/use_of_moved_value_copy_suggestions.fixed @@ -54,17 +54,17 @@ where fn duplicate_custom_3<T>(t: S<T>) -> (S<T>, S<T>) where - T: A, - T: B, T: Trait, T: Copy - //~^ HELP consider further restricting type parameter `T` + T: A + Trait + Copy, + //~^ HELP consider further restricting this bound + T: B, { (t, t) //~ use of moved value: `t` } -fn duplicate_custom_4<T: A>(t: S<T>) -> (S<T>, S<T>) +fn duplicate_custom_4<T: A + Trait + Copy>(t: S<T>) -> (S<T>, S<T>) +//~^ HELP consider further restricting this bound where - T: B + Trait + Copy, - //~^ HELP consider further restricting this bound + T: B, { (t, t) //~ use of moved value: `t` } @@ -77,8 +77,8 @@ fn existing_colon<T: Copy>(t: T) { fn existing_colon_in_where<T>(t: T) where - T: Copy, - //~^ HELP consider further restricting this bound + T:, T: Copy + //~^ HELP consider further restricting type parameter `T` { [t, t]; //~ use of moved value: `t` } diff --git a/src/test/ui/moves/use_of_moved_value_copy_suggestions.rs b/src/test/ui/moves/use_of_moved_value_copy_suggestions.rs index cadbf2a54cc..0a43dd1a9a3 100644 --- a/src/test/ui/moves/use_of_moved_value_copy_suggestions.rs +++ b/src/test/ui/moves/use_of_moved_value_copy_suggestions.rs @@ -55,16 +55,16 @@ where fn duplicate_custom_3<T>(t: S<T>) -> (S<T>, S<T>) where T: A, + //~^ HELP consider further restricting this bound T: B, - //~^ HELP consider further restricting type parameter `T` { (t, t) //~ use of moved value: `t` } fn duplicate_custom_4<T: A>(t: S<T>) -> (S<T>, S<T>) +//~^ HELP consider further restricting this bound where T: B, - //~^ HELP consider further restricting this bound { (t, t) //~ use of moved value: `t` } @@ -78,7 +78,7 @@ fn existing_colon<T:>(t: T) { fn existing_colon_in_where<T>(t: T) where T:, - //~^ HELP consider further restricting this bound + //~^ HELP consider further restricting type parameter `T` { [t, t]; //~ use of moved value: `t` } diff --git a/src/test/ui/moves/use_of_moved_value_copy_suggestions.stderr b/src/test/ui/moves/use_of_moved_value_copy_suggestions.stderr index f5252084d68..2353cd079a3 100644 --- a/src/test/ui/moves/use_of_moved_value_copy_suggestions.stderr +++ b/src/test/ui/moves/use_of_moved_value_copy_suggestions.stderr @@ -121,10 +121,10 @@ LL | (t, t) | | | value moved here | -help: consider further restricting type parameter `T` +help: consider further restricting this bound | -LL | T: B, T: Trait, T: Copy - | ~~~~~~~~~~~~~~~~~~~ +LL | T: A + Trait + Copy, + | ++++++++++++++ error[E0382]: use of moved value: `t` --> $DIR/use_of_moved_value_copy_suggestions.rs:69:9 @@ -139,8 +139,8 @@ LL | (t, t) | help: consider further restricting this bound | -LL | T: B + Trait + Copy, - | ++++++++++++++ +LL | fn duplicate_custom_4<T: A + Trait + Copy>(t: S<T>) -> (S<T>, S<T>) + | ++++++++++++++ error[E0382]: use of moved value: `t` --> $DIR/use_of_moved_value_copy_suggestions.rs:83:9 @@ -153,10 +153,10 @@ LL | [t, t]; | | | value moved here | -help: consider further restricting this bound +help: consider further restricting type parameter `T` | -LL | T: Copy, - | ++++ +LL | T:, T: Copy + | ~~~~~~~~~ error[E0382]: use of moved value: `t` --> $DIR/use_of_moved_value_copy_suggestions.rs:75:9 diff --git a/src/test/ui/never_type/issue-52443.stderr b/src/test/ui/never_type/issue-52443.stderr index 8c1755205f0..c2079a19d0a 100644 --- a/src/test/ui/never_type/issue-52443.stderr +++ b/src/test/ui/never_type/issue-52443.stderr @@ -47,8 +47,8 @@ LL | [(); { for _ in 0usize.. {}; 0}]; note: impl defined here, but it is not `const` --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL | -LL | impl<I: Iterator> IntoIterator for I { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | impl<I: ~const Iterator> const IntoIterator for I { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: calls in constants are limited to constant functions, tuple structs and tuple variants error[E0658]: mutable references are not allowed in constants diff --git a/src/test/ui/never_type/issue-96335.rs b/src/test/ui/never_type/issue-96335.rs new file mode 100644 index 00000000000..411a7c9df65 --- /dev/null +++ b/src/test/ui/never_type/issue-96335.rs @@ -0,0 +1,5 @@ +fn main() { + 0.....{loop{}1}; + //~^ ERROR unexpected token + //~| ERROR mismatched types +} diff --git a/src/test/ui/never_type/issue-96335.stderr b/src/test/ui/never_type/issue-96335.stderr new file mode 100644 index 00000000000..168cf2f8353 --- /dev/null +++ b/src/test/ui/never_type/issue-96335.stderr @@ -0,0 +1,35 @@ +error: unexpected token: `...` + --> $DIR/issue-96335.rs:2:6 + | +LL | 0.....{loop{}1}; + | ^^^ + | +help: use `..` for an exclusive range + | +LL | 0....{loop{}1}; + | ~~ +help: or `..=` for an inclusive range + | +LL | 0..=..{loop{}1}; + | ~~~ + +error[E0308]: mismatched types + --> $DIR/issue-96335.rs:2:9 + | +LL | 0.....{loop{}1}; + | ----^^^^^^^^^^^ + | | | + | | expected integer, found struct `RangeTo` + | arguments to this function are incorrect + | + = note: expected type `{integer}` + found struct `RangeTo<{integer}>` +note: associated function defined here + --> $SRC_DIR/core/src/ops/range.rs:LL:COL + | +LL | pub const fn new(start: Idx, end: Idx) -> Self { + | ^^^ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/nll/closure-requirements/propagate-from-trait-match.stderr b/src/test/ui/nll/closure-requirements/propagate-from-trait-match.stderr index 4b860a55057..08605efa2ea 100644 --- a/src/test/ui/nll/closure-requirements/propagate-from-trait-match.stderr +++ b/src/test/ui/nll/closure-requirements/propagate-from-trait-match.stderr @@ -44,9 +44,12 @@ LL | | // This function call requires that ... | LL | | require(value); LL | | }); - | |_____^ + | |_____^ ...so that the type `T` will meet its required lifetime bounds + | +help: consider adding an explicit lifetime bound... | - = help: consider adding an explicit lifetime bound `T: 'a`... +LL | T: Trait<'a> + 'a, + | ++++ error: aborting due to previous error diff --git a/src/test/ui/issues/issue-45696-no-variant-box-recur.rs b/src/test/ui/nll/issue-45696-no-variant-box-recur.rs index c688261fa1c..c688261fa1c 100644 --- a/src/test/ui/issues/issue-45696-no-variant-box-recur.rs +++ b/src/test/ui/nll/issue-45696-no-variant-box-recur.rs diff --git a/src/test/ui/nll/mir_check_cast_unsize.stderr b/src/test/ui/nll/mir_check_cast_unsize.stderr index 364d6c17ea7..8d02ef71d1b 100644 --- a/src/test/ui/nll/mir_check_cast_unsize.stderr +++ b/src/test/ui/nll/mir_check_cast_unsize.stderr @@ -5,6 +5,11 @@ LL | fn bar<'a>(x: &'a u32) -> &'static dyn Debug { | -- lifetime `'a` defined here LL | x | ^ returning this value requires that `'a` must outlive `'static` + | +help: to declare that the trait object captures data from argument `x`, you can add an explicit `'a` lifetime bound + | +LL | fn bar<'a>(x: &'a u32) -> &'static dyn Debug + 'a { + | ++++ error: aborting due to previous error diff --git a/src/test/ui/nll/ty-outlives/impl-trait-outlives.stderr b/src/test/ui/nll/ty-outlives/impl-trait-outlives.stderr index 31ee540cce9..64b08a9b32f 100644 --- a/src/test/ui/nll/ty-outlives/impl-trait-outlives.stderr +++ b/src/test/ui/nll/ty-outlives/impl-trait-outlives.stderr @@ -2,17 +2,23 @@ error[E0309]: the parameter type `T` may not live long enough --> $DIR/impl-trait-outlives.rs:11:5 | LL | x - | ^ + | ^ ...so that the type `T` will meet its required lifetime bounds | - = help: consider adding an explicit lifetime bound `T: 'a`... +help: consider adding an explicit lifetime bound... + | +LL | T: Debug + 'a, + | ++++ error[E0309]: the parameter type `T` may not live long enough --> $DIR/impl-trait-outlives.rs:26:5 | LL | x - | ^ + | ^ ...so that the type `T` will meet its required lifetime bounds + | +help: consider adding an explicit lifetime bound... | - = help: consider adding an explicit lifetime bound `T: 'a`... +LL | T: 'b + Debug + 'a, + | ++++ error: aborting due to 2 previous errors diff --git a/src/test/ui/nll/ty-outlives/projection-implied-bounds.stderr b/src/test/ui/nll/ty-outlives/projection-implied-bounds.stderr index 9f0c60c1e17..3b9b2956c51 100644 --- a/src/test/ui/nll/ty-outlives/projection-implied-bounds.stderr +++ b/src/test/ui/nll/ty-outlives/projection-implied-bounds.stderr @@ -2,9 +2,12 @@ error[E0310]: the parameter type `T` may not live long enough --> $DIR/projection-implied-bounds.rs:30:18 | LL | twice(value, |value_ref, item| invoke2(value_ref, item)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds | - = help: consider adding an explicit lifetime bound `T: 'static`... +help: consider adding an explicit lifetime bound... + | +LL | fn generic2<T: Iterator + 'static>(value: T) { + | +++++++++ error: aborting due to previous error diff --git a/src/test/ui/nll/ty-outlives/projection-no-regions-closure.stderr b/src/test/ui/nll/ty-outlives/projection-no-regions-closure.stderr index 983d6a06afa..8fe25181da1 100644 --- a/src/test/ui/nll/ty-outlives/projection-no-regions-closure.stderr +++ b/src/test/ui/nll/ty-outlives/projection-no-regions-closure.stderr @@ -33,6 +33,7 @@ LL | with_signature(x, |mut y| Box::new(y.next())) | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: consider adding an explicit lifetime bound `<T as Iterator>::Item: 'a`... + = note: ...so that the type `<T as Iterator>::Item` will meet its required lifetime bounds note: external requirements --> $DIR/projection-no-regions-closure.rs:34:23 @@ -96,6 +97,7 @@ LL | with_signature(x, |mut y| Box::new(y.next())) | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: consider adding an explicit lifetime bound `<T as Iterator>::Item: 'a`... + = note: ...so that the type `<T as Iterator>::Item` will meet its required lifetime bounds note: external requirements --> $DIR/projection-no-regions-closure.rs:52:23 diff --git a/src/test/ui/nll/ty-outlives/projection-no-regions-fn.stderr b/src/test/ui/nll/ty-outlives/projection-no-regions-fn.stderr index c4df04b99b5..e0ff544fe47 100644 --- a/src/test/ui/nll/ty-outlives/projection-no-regions-fn.stderr +++ b/src/test/ui/nll/ty-outlives/projection-no-regions-fn.stderr @@ -5,6 +5,7 @@ LL | Box::new(x.next()) | ^^^^^^^^^^^^^^^^^^ | = help: consider adding an explicit lifetime bound `<T as Iterator>::Item: 'a`... + = note: ...so that the type `<T as Iterator>::Item` will meet its required lifetime bounds error[E0309]: the associated type `<T as Iterator>::Item` may not live long enough --> $DIR/projection-no-regions-fn.rs:28:5 @@ -13,6 +14,7 @@ LL | Box::new(x.next()) | ^^^^^^^^^^^^^^^^^^ | = help: consider adding an explicit lifetime bound `<T as Iterator>::Item: 'a`... + = note: ...so that the type `<T as Iterator>::Item` will meet its required lifetime bounds error: aborting due to 2 previous errors diff --git a/src/test/ui/nll/ty-outlives/projection-one-region-closure.stderr b/src/test/ui/nll/ty-outlives/projection-one-region-closure.stderr index 2513b0bfccb..caf2e3c4747 100644 --- a/src/test/ui/nll/ty-outlives/projection-one-region-closure.stderr +++ b/src/test/ui/nll/ty-outlives/projection-one-region-closure.stderr @@ -32,9 +32,12 @@ error[E0309]: the parameter type `T` may not live long enough --> $DIR/projection-one-region-closure.rs:45:29 | LL | with_signature(cell, t, |cell, t| require(cell, t)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds + | +help: consider adding an explicit lifetime bound... | - = help: consider adding an explicit lifetime bound `T: 'a`... +LL | T: Anything<'b> + 'a, + | ++++ error: lifetime may not live long enough --> $DIR/projection-one-region-closure.rs:45:39 @@ -82,9 +85,12 @@ error[E0309]: the parameter type `T` may not live long enough --> $DIR/projection-one-region-closure.rs:56:29 | LL | with_signature(cell, t, |cell, t| require(cell, t)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds + | +help: consider adding an explicit lifetime bound... | - = help: consider adding an explicit lifetime bound `T: 'a`... +LL | T: Anything<'b> + 'a, + | ++++ error: lifetime may not live long enough --> $DIR/projection-one-region-closure.rs:56:39 diff --git a/src/test/ui/nll/ty-outlives/projection-two-region-trait-bound-closure.stderr b/src/test/ui/nll/ty-outlives/projection-two-region-trait-bound-closure.stderr index 4e0155bdf2c..1ee788b40ab 100644 --- a/src/test/ui/nll/ty-outlives/projection-two-region-trait-bound-closure.stderr +++ b/src/test/ui/nll/ty-outlives/projection-two-region-trait-bound-closure.stderr @@ -34,6 +34,7 @@ LL | with_signature(cell, t, |cell, t| require(cell, t)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: consider adding an explicit lifetime bound `<T as Anything<ReEarlyBound(0, 'b), ReEarlyBound(1, 'c)>>::AssocType: 'a`... + = note: ...so that the type `<T as Anything<ReEarlyBound(0, 'b), ReEarlyBound(1, 'c)>>::AssocType` will meet its required lifetime bounds note: external requirements --> $DIR/projection-two-region-trait-bound-closure.rs:48:29 @@ -70,6 +71,7 @@ LL | with_signature(cell, t, |cell, t| require(cell, t)); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: consider adding an explicit lifetime bound `<T as Anything<ReEarlyBound(1, 'b), ReEarlyBound(2, 'c)>>::AssocType: 'a`... + = note: ...so that the type `<T as Anything<ReEarlyBound(1, 'b), ReEarlyBound(2, 'c)>>::AssocType` will meet its required lifetime bounds note: external requirements --> $DIR/projection-two-region-trait-bound-closure.rs:61:29 diff --git a/src/test/ui/nll/ty-outlives/projection-where-clause-env-wrong-bound.nll.stderr b/src/test/ui/nll/ty-outlives/projection-where-clause-env-wrong-bound.nll.stderr index 3a84cbfbedc..b4435fe06bc 100644 --- a/src/test/ui/nll/ty-outlives/projection-where-clause-env-wrong-bound.nll.stderr +++ b/src/test/ui/nll/ty-outlives/projection-where-clause-env-wrong-bound.nll.stderr @@ -5,6 +5,7 @@ LL | bar::<T::Output>() | ^^^^^^^^^^^^^^^^ | = help: consider adding an explicit lifetime bound `<T as MyTrait<'_>>::Output: 'a`... + = note: ...so that the type `<T as MyTrait<'_>>::Output` will meet its required lifetime bounds error: aborting due to previous error diff --git a/src/test/ui/nll/ty-outlives/projection-where-clause-env-wrong-lifetime.nll.stderr b/src/test/ui/nll/ty-outlives/projection-where-clause-env-wrong-lifetime.nll.stderr index 58bfb600452..ddeaf3c1f9e 100644 --- a/src/test/ui/nll/ty-outlives/projection-where-clause-env-wrong-lifetime.nll.stderr +++ b/src/test/ui/nll/ty-outlives/projection-where-clause-env-wrong-lifetime.nll.stderr @@ -5,6 +5,7 @@ LL | bar::<<T as MyTrait<'a>>::Output>() | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: consider adding an explicit lifetime bound `<T as MyTrait<'_>>::Output: 'a`... + = note: ...so that the type `<T as MyTrait<'_>>::Output` will meet its required lifetime bounds error: aborting due to previous error diff --git a/src/test/ui/nll/ty-outlives/projection-where-clause-none.stderr b/src/test/ui/nll/ty-outlives/projection-where-clause-none.stderr index 8175c302155..e28b89580bc 100644 --- a/src/test/ui/nll/ty-outlives/projection-where-clause-none.stderr +++ b/src/test/ui/nll/ty-outlives/projection-where-clause-none.stderr @@ -2,9 +2,12 @@ error[E0309]: the parameter type `T` may not live long enough --> $DIR/projection-where-clause-none.rs:16:5 | LL | bar::<T::Output>() - | ^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds | - = help: consider adding an explicit lifetime bound `T: 'a`... +help: consider adding an explicit lifetime bound... + | +LL | T: MyTrait<'a> + 'a, + | ++++ error: aborting due to previous error diff --git a/src/test/ui/nll/ty-outlives/ty-param-closure-approximate-lower-bound.stderr b/src/test/ui/nll/ty-outlives/ty-param-closure-approximate-lower-bound.stderr index baf223b786b..a4588730b3f 100644 --- a/src/test/ui/nll/ty-outlives/ty-param-closure-approximate-lower-bound.stderr +++ b/src/test/ui/nll/ty-outlives/ty-param-closure-approximate-lower-bound.stderr @@ -53,9 +53,12 @@ error[E0309]: the parameter type `T` may not live long enough --> $DIR/ty-param-closure-approximate-lower-bound.rs:29:24 | LL | twice(cell, value, |a, b| invoke(a, b)); - | ^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds + | +help: consider adding an explicit lifetime bound... | - = help: consider adding an explicit lifetime bound `T: 'a`... +LL | fn generic_fail<'a, T: 'a>(cell: Cell<&'a ()>, value: T) { + | ++++ error: aborting due to previous error diff --git a/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-return-type.stderr b/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-return-type.stderr index 88d73e7a729..084dd93cb86 100644 --- a/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-return-type.stderr +++ b/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-return-type.stderr @@ -30,17 +30,23 @@ error[E0309]: the parameter type `T` may not live long enough --> $DIR/ty-param-closure-outlives-from-return-type.rs:26:23 | LL | with_signature(x, |y| y) - | ^^^^^ + | ^^^^^ ...so that the type `T` will meet its required lifetime bounds + | +help: consider adding an explicit lifetime bound... | - = help: consider adding an explicit lifetime bound `T: 'a`... +LL | T: Debug + 'a, + | ++++ error[E0309]: the parameter type `T` may not live long enough --> $DIR/ty-param-closure-outlives-from-return-type.rs:41:5 | LL | x - | ^ + | ^ ...so that the type `T` will meet its required lifetime bounds + | +help: consider adding an explicit lifetime bound... | - = help: consider adding an explicit lifetime bound `T: 'a`... +LL | T: 'b + Debug + 'a, + | ++++ error: aborting due to 2 previous errors diff --git a/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-where-clause.stderr b/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-where-clause.stderr index 5b175aac1e1..11a737ba291 100644 --- a/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-where-clause.stderr +++ b/src/test/ui/nll/ty-outlives/ty-param-closure-outlives-from-where-clause.stderr @@ -45,9 +45,12 @@ LL | | // See `correct_region`, which explains the point of this ... | LL | | require(&x, &y) LL | | }) - | |_____^ + | |_____^ ...so that the type `T` will meet its required lifetime bounds + | +help: consider adding an explicit lifetime bound... | - = help: consider adding an explicit lifetime bound `T: 'a`... +LL | fn no_region<'a, T: 'a>(a: Cell<&'a ()>, b: T) { + | ++++ note: external requirements --> $DIR/ty-param-closure-outlives-from-where-clause.rs:43:26 @@ -127,9 +130,12 @@ LL | | LL | | // See `correct_region` LL | | require(&x, &y) LL | | }) - | |_____^ + | |_____^ ...so that the type `T` will meet its required lifetime bounds + | +help: consider adding an explicit lifetime bound... | - = help: consider adding an explicit lifetime bound `T: 'a`... +LL | T: 'b + 'a, + | ++++ note: external requirements --> $DIR/ty-param-closure-outlives-from-where-clause.rs:77:26 diff --git a/src/test/ui/nll/ty-outlives/ty-param-fn-body.stderr b/src/test/ui/nll/ty-outlives/ty-param-fn-body.stderr index 9a023a0e58e..ba79137d18d 100644 --- a/src/test/ui/nll/ty-outlives/ty-param-fn-body.stderr +++ b/src/test/ui/nll/ty-outlives/ty-param-fn-body.stderr @@ -2,9 +2,12 @@ error[E0309]: the parameter type `T` may not live long enough --> $DIR/ty-param-fn-body.rs:19:5 | LL | outlives(cell, t) - | ^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds | - = help: consider adding an explicit lifetime bound `T: 'a`... +help: consider adding an explicit lifetime bound... + | +LL | fn region_static<'a, T: 'a>(cell: Cell<&'a usize>, t: T) { + | ++++ error: aborting due to previous error diff --git a/src/test/ui/nll/ty-outlives/ty-param-fn.stderr b/src/test/ui/nll/ty-outlives/ty-param-fn.stderr index 8c8529620d5..729f14d84ad 100644 --- a/src/test/ui/nll/ty-outlives/ty-param-fn.stderr +++ b/src/test/ui/nll/ty-outlives/ty-param-fn.stderr @@ -2,17 +2,23 @@ error[E0309]: the parameter type `T` may not live long enough --> $DIR/ty-param-fn.rs:11:5 | LL | x - | ^ + | ^ ...so that the type `T` will meet its required lifetime bounds | - = help: consider adding an explicit lifetime bound `T: 'a`... +help: consider adding an explicit lifetime bound... + | +LL | T: Debug + 'a, + | ++++ error[E0309]: the parameter type `T` may not live long enough --> $DIR/ty-param-fn.rs:26:5 | LL | x - | ^ + | ^ ...so that the type `T` will meet its required lifetime bounds + | +help: consider adding an explicit lifetime bound... | - = help: consider adding an explicit lifetime bound `T: 'a`... +LL | T: 'b + Debug + 'a, + | ++++ error: aborting due to 2 previous errors diff --git a/src/test/ui/object-lifetime/object-lifetime-default-from-box-error.nll.stderr b/src/test/ui/object-lifetime/object-lifetime-default-from-box-error.nll.stderr index ae02c58d080..43695a7511d 100644 --- a/src/test/ui/object-lifetime/object-lifetime-default-from-box-error.nll.stderr +++ b/src/test/ui/object-lifetime/object-lifetime-default-from-box-error.nll.stderr @@ -6,6 +6,11 @@ LL | fn load(ss: &mut SomeStruct) -> Box<dyn SomeTrait> { ... LL | ss.r | ^^^^ returning this value requires that `'1` must outlive `'static` + | +help: to declare that the trait object captures data from argument `ss`, you can add an explicit `'_` lifetime bound + | +LL | fn load(ss: &mut SomeStruct) -> Box<dyn SomeTrait + '_> { + | ++++ error[E0507]: cannot move out of `ss.r` which is behind a mutable reference --> $DIR/object-lifetime-default-from-box-error.rs:18:5 diff --git a/src/test/ui/issues/issue-19538.rs b/src/test/ui/object-safety/issue-19538.rs index 7054ef41b1c..7054ef41b1c 100644 --- a/src/test/ui/issues/issue-19538.rs +++ b/src/test/ui/object-safety/issue-19538.rs diff --git a/src/test/ui/issues/issue-19538.stderr b/src/test/ui/object-safety/issue-19538.stderr index 7b37e1f95dc..7b37e1f95dc 100644 --- a/src/test/ui/issues/issue-19538.stderr +++ b/src/test/ui/object-safety/issue-19538.stderr diff --git a/src/test/ui/or-patterns/missing-bindings.stderr b/src/test/ui/or-patterns/missing-bindings.stderr index c173a3a9aba..8fafa275b5c 100644 --- a/src/test/ui/or-patterns/missing-bindings.stderr +++ b/src/test/ui/or-patterns/missing-bindings.stderr @@ -103,6 +103,22 @@ LL | let (A(A(a, b) | B(c), d) | B(e)) = Y; | | | pattern doesn't bind `c` +error[E0408]: variable `d` is not bound in all patterns + --> $DIR/missing-bindings.rs:45:33 + | +LL | let (A(A(a, b) | B(c), d) | B(e)) = Y; + | - ^^^^ pattern doesn't bind `d` + | | + | variable not in all patterns + +error[E0408]: variable `e` is not bound in all patterns + --> $DIR/missing-bindings.rs:45:10 + | +LL | let (A(A(a, b) | B(c), d) | B(e)) = Y; + | ^^^^^^^^^^^^^^^^^^^^ - variable not in all patterns + | | + | pattern doesn't bind `e` + error[E0408]: variable `a` is not bound in all patterns --> $DIR/missing-bindings.rs:45:33 | @@ -127,22 +143,6 @@ LL | let (A(A(a, b) | B(c), d) | B(e)) = Y; | | | variable not in all patterns -error[E0408]: variable `d` is not bound in all patterns - --> $DIR/missing-bindings.rs:45:33 - | -LL | let (A(A(a, b) | B(c), d) | B(e)) = Y; - | - ^^^^ pattern doesn't bind `d` - | | - | variable not in all patterns - -error[E0408]: variable `e` is not bound in all patterns - --> $DIR/missing-bindings.rs:45:10 - | -LL | let (A(A(a, b) | B(c), d) | B(e)) = Y; - | ^^^^^^^^^^^^^^^^^^^^ - variable not in all patterns - | | - | pattern doesn't bind `e` - error[E0408]: variable `a` is not bound in all patterns --> $DIR/missing-bindings.rs:61:29 | diff --git a/src/test/ui/issues/issue-61858.rs b/src/test/ui/parser/issue-61858.rs index 6c3b56586c4..6c3b56586c4 100644 --- a/src/test/ui/issues/issue-61858.rs +++ b/src/test/ui/parser/issue-61858.rs diff --git a/src/test/ui/issues/issue-61858.stderr b/src/test/ui/parser/issue-61858.stderr index 8b95d9c6ae4..8b95d9c6ae4 100644 --- a/src/test/ui/issues/issue-61858.stderr +++ b/src/test/ui/parser/issue-61858.stderr diff --git a/src/test/ui/parser/raw/raw-str-unbalanced.rs b/src/test/ui/parser/raw/raw-str-unbalanced.rs index 35f118f5ce6..38537f8b31e 100644 --- a/src/test/ui/parser/raw/raw-str-unbalanced.rs +++ b/src/test/ui/parser/raw/raw-str-unbalanced.rs @@ -1,4 +1,22 @@ static s: &'static str = + r#""## //~ ERROR too many `#` when terminating raw string +; + +static s2: &'static str = r#" - "## //~ too many `#` when terminating raw string + "#### //~ ERROR too many `#` when terminating raw string ; + +const A: &'static str = r"" //~ ERROR expected `;`, found `#` + +// Test +#[test] +fn test() {} + +const B: &'static str = r""## //~ ERROR too many `#` when terminating raw string + +// Test +#[test] +fn test2() {} + +fn main() {} diff --git a/src/test/ui/parser/raw/raw-str-unbalanced.stderr b/src/test/ui/parser/raw/raw-str-unbalanced.stderr index bf8f3a7a5a4..eac8c06c1df 100644 --- a/src/test/ui/parser/raw/raw-str-unbalanced.stderr +++ b/src/test/ui/parser/raw/raw-str-unbalanced.stderr @@ -1,10 +1,36 @@ error: too many `#` when terminating raw string - --> $DIR/raw-str-unbalanced.rs:3:9 + --> $DIR/raw-str-unbalanced.rs:2:10 | -LL | "## - | ^ help: remove the extra `#` +LL | r#""## + | -----^ help: remove the extra `#` + | | + | this raw string started with 1 `#` + +error: too many `#` when terminating raw string + --> $DIR/raw-str-unbalanced.rs:7:9 + | +LL | / r#" +LL | | "#### + | | -^^^ help: remove the extra `#`s + | |________| + | this raw string started with 1 `#` + +error: expected `;`, found `#` + --> $DIR/raw-str-unbalanced.rs:10:28 + | +LL | const A: &'static str = r"" + | ^ help: add `;` here +... +LL | #[test] + | - unexpected token + +error: too many `#` when terminating raw string + --> $DIR/raw-str-unbalanced.rs:16:28 | - = note: the raw string started with 1 `#`s +LL | const B: &'static str = r""## + | ---^^ help: remove the extra `#`s + | | + | this raw string started with 0 `#`s -error: aborting due to previous error +error: aborting due to 4 previous errors diff --git a/src/test/ui/issues/issue-72574-1.rs b/src/test/ui/pattern/issue-72574-1.rs index 1b80a21793a..1b80a21793a 100644 --- a/src/test/ui/issues/issue-72574-1.rs +++ b/src/test/ui/pattern/issue-72574-1.rs diff --git a/src/test/ui/issues/issue-72574-1.stderr b/src/test/ui/pattern/issue-72574-1.stderr index 653869a237d..653869a237d 100644 --- a/src/test/ui/issues/issue-72574-1.stderr +++ b/src/test/ui/pattern/issue-72574-1.stderr diff --git a/src/test/ui/pattern/usefulness/tuple-struct-nonexhaustive.stderr b/src/test/ui/pattern/usefulness/tuple-struct-nonexhaustive.stderr index e2a65ff8524..fc0430d06fa 100644 --- a/src/test/ui/pattern/usefulness/tuple-struct-nonexhaustive.stderr +++ b/src/test/ui/pattern/usefulness/tuple-struct-nonexhaustive.stderr @@ -12,7 +12,7 @@ LL | struct Foo(isize, isize); = note: the matched value is of type `Foo` help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown | -LL ~ Foo(2, b) => println!("{}", b), +LL ~ Foo(2, b) => println!("{}", b) LL + Foo(_, _) => todo!() | diff --git a/src/test/ui/polymorphization/generators.stderr b/src/test/ui/polymorphization/generators.stderr index 9cabb21e784..5edbb119f78 100644 --- a/src/test/ui/polymorphization/generators.stderr +++ b/src/test/ui/polymorphization/generators.stderr @@ -19,6 +19,12 @@ LL | | 2 LL | | } | |_____^ +note: the above error was encountered while instantiating `fn finish::<[generator@$DIR/generators.rs:35:5: 39:6], u32, u32>` + --> $DIR/generators.rs:86:5 + | +LL | finish(unused_type::<u32>()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + error: item has unused generic parameters --> $DIR/generators.rs:60:5 | @@ -31,5 +37,11 @@ LL | | 2 LL | | } | |_____^ +note: the above error was encountered while instantiating `fn finish::<[generator@$DIR/generators.rs:60:5: 64:6], u32, u32>` + --> $DIR/generators.rs:89:5 + | +LL | finish(unused_const::<1u32>()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + error: aborting due to 2 previous errors; 1 warning emitted diff --git a/src/test/ui/polymorphization/predicates.stderr b/src/test/ui/polymorphization/predicates.stderr index 5fc51e58d72..dc6ebceae21 100644 --- a/src/test/ui/polymorphization/predicates.stderr +++ b/src/test/ui/polymorphization/predicates.stderr @@ -41,5 +41,11 @@ error: item has unused generic parameters LL | fn bar<I>() { | ^^^ - generic parameter `I` is unused +note: the above error was encountered while instantiating `fn foo::<std::slice::Iter<u32>, T>` + --> $DIR/predicates.rs:85:5 + | +LL | foo(x.iter()); + | ^^^^^^^^^^^^^ + error: aborting due to 6 previous errors diff --git a/src/test/ui/proc-macro/nodelim-groups.rs b/src/test/ui/proc-macro/nodelim-groups.rs index db2a879f405..ec301990281 100644 --- a/src/test/ui/proc-macro/nodelim-groups.rs +++ b/src/test/ui/proc-macro/nodelim-groups.rs @@ -3,7 +3,7 @@ // compile-flags: -Z span-debug // edition:2018 // -// Tests the pretty-printing behavior of inserting `NoDelim` groups +// Tests the pretty-printing behavior of inserting `Invisible`-delimited groups #![no_std] // Don't load unnecessary hygiene information from std extern crate std; diff --git a/src/test/ui/regions/issue-28848.stderr b/src/test/ui/regions/issue-28848.base.stderr index afa0c9c76b2..f10b19738c4 100644 --- a/src/test/ui/regions/issue-28848.stderr +++ b/src/test/ui/regions/issue-28848.base.stderr @@ -1,16 +1,16 @@ error[E0478]: lifetime bound not satisfied - --> $DIR/issue-28848.rs:10:5 + --> $DIR/issue-28848.rs:14:5 | LL | Foo::<'a, 'b>::xmute(u) | ^^^^^^^^^^^^^ | note: lifetime parameter instantiated with the lifetime `'b` as defined here - --> $DIR/issue-28848.rs:9:16 + --> $DIR/issue-28848.rs:13:16 | LL | pub fn foo<'a, 'b>(u: &'b ()) -> &'a () { | ^^ note: but lifetime parameter must outlive the lifetime `'a` as defined here - --> $DIR/issue-28848.rs:9:12 + --> $DIR/issue-28848.rs:13:12 | LL | pub fn foo<'a, 'b>(u: &'b ()) -> &'a () { | ^^ diff --git a/src/test/ui/regions/issue-28848.nll.stderr b/src/test/ui/regions/issue-28848.nll.stderr index a29dac4c9c8..f9de8948272 100644 --- a/src/test/ui/regions/issue-28848.nll.stderr +++ b/src/test/ui/regions/issue-28848.nll.stderr @@ -1,5 +1,5 @@ error: lifetime may not live long enough - --> $DIR/issue-28848.rs:10:5 + --> $DIR/issue-28848.rs:14:5 | LL | pub fn foo<'a, 'b>(u: &'b ()) -> &'a () { | -- -- lifetime `'b` defined here diff --git a/src/test/ui/regions/issue-28848.rs b/src/test/ui/regions/issue-28848.rs index a6250239030..d8ab42a08d4 100644 --- a/src/test/ui/regions/issue-28848.rs +++ b/src/test/ui/regions/issue-28848.rs @@ -1,3 +1,7 @@ +// revisions: base nll +// ignore-compare-mode-nll +//[nll] compile-flags: -Z borrowck=mir + struct Foo<'a, 'b: 'a>(&'a &'b ()); impl<'a, 'b> Foo<'a, 'b> { @@ -7,7 +11,9 @@ impl<'a, 'b> Foo<'a, 'b> { } pub fn foo<'a, 'b>(u: &'b ()) -> &'a () { - Foo::<'a, 'b>::xmute(u) //~ ERROR lifetime bound not satisfied + Foo::<'a, 'b>::xmute(u) + //[base]~^ ERROR lifetime bound not satisfied + //[nll]~^^ ERROR lifetime may not live long enough } fn main() {} diff --git a/src/test/ui/regions/region-invariant-static-error-reporting.stderr b/src/test/ui/regions/region-invariant-static-error-reporting.base.stderr index 34287070eec..ce21751a95a 100644 --- a/src/test/ui/regions/region-invariant-static-error-reporting.stderr +++ b/src/test/ui/regions/region-invariant-static-error-reporting.base.stderr @@ -1,5 +1,5 @@ error[E0308]: `if` and `else` have incompatible types - --> $DIR/region-invariant-static-error-reporting.rs:17:9 + --> $DIR/region-invariant-static-error-reporting.rs:21:9 | LL | let bad = if x.is_some() { | _______________- @@ -14,7 +14,7 @@ LL | | }; = note: expected struct `Invariant<'a>` found struct `Invariant<'static>` note: the lifetime `'a` as defined here... - --> $DIR/region-invariant-static-error-reporting.rs:13:10 + --> $DIR/region-invariant-static-error-reporting.rs:17:10 | LL | fn unify<'a>(x: Option<Invariant<'a>>, f: fn(Invariant<'a>)) { | ^^ diff --git a/src/test/ui/regions/region-invariant-static-error-reporting.nll.stderr b/src/test/ui/regions/region-invariant-static-error-reporting.nll.stderr index 6e7eb734a50..6905fd008c5 100644 --- a/src/test/ui/regions/region-invariant-static-error-reporting.nll.stderr +++ b/src/test/ui/regions/region-invariant-static-error-reporting.nll.stderr @@ -1,5 +1,5 @@ error[E0521]: borrowed data escapes outside of function - --> $DIR/region-invariant-static-error-reporting.rs:15:9 + --> $DIR/region-invariant-static-error-reporting.rs:19:9 | LL | fn unify<'a>(x: Option<Invariant<'a>>, f: fn(Invariant<'a>)) { | -- - `x` is a reference that is only valid in the function body diff --git a/src/test/ui/regions/region-invariant-static-error-reporting.rs b/src/test/ui/regions/region-invariant-static-error-reporting.rs index 911904813d0..b81022ca4b4 100644 --- a/src/test/ui/regions/region-invariant-static-error-reporting.rs +++ b/src/test/ui/regions/region-invariant-static-error-reporting.rs @@ -3,8 +3,12 @@ // over time, but this test used to exhibit some pretty bogus messages // that were not remotely helpful. -// error-pattern:the lifetime `'a` -// error-pattern:the static lifetime +// revisions: base nll +// ignore-compare-mode-nll +//[base] error-pattern:the lifetime `'a` +//[base] error-pattern:the static lifetime +//[nll] compile-flags: -Z borrowck=mir +//[nll] error-pattern:argument requires that `'a` must outlive `'static` struct Invariant<'a>(Option<&'a mut &'a mut ()>); @@ -12,9 +16,9 @@ fn mk_static() -> Invariant<'static> { Invariant(None) } fn unify<'a>(x: Option<Invariant<'a>>, f: fn(Invariant<'a>)) { let bad = if x.is_some() { - x.unwrap() + x.unwrap() //[nll]~ ERROR borrowed data escapes outside of function [E0521] } else { - mk_static() + mk_static() //[base]~ ERROR `if` and `else` have incompatible types [E0308] }; f(bad); } diff --git a/src/test/ui/regions/region-lifetime-bounds-on-fns-where-clause.stderr b/src/test/ui/regions/region-lifetime-bounds-on-fns-where-clause.base.stderr index b83e07663fa..2ba4f4f5d9f 100644 --- a/src/test/ui/regions/region-lifetime-bounds-on-fns-where-clause.stderr +++ b/src/test/ui/regions/region-lifetime-bounds-on-fns-where-clause.base.stderr @@ -1,5 +1,5 @@ error[E0623]: lifetime mismatch - --> $DIR/region-lifetime-bounds-on-fns-where-clause.rs:8:10 + --> $DIR/region-lifetime-bounds-on-fns-where-clause.rs:12:10 | LL | fn b<'a, 'b>(x: &mut &'a isize, y: &mut &'b isize) { | --------- --------- these two types are declared with different lifetimes... @@ -8,7 +8,7 @@ LL | *x = *y; | ^^ ...but data from `y` flows into `x` here error[E0623]: lifetime mismatch - --> $DIR/region-lifetime-bounds-on-fns-where-clause.rs:14:7 + --> $DIR/region-lifetime-bounds-on-fns-where-clause.rs:20:7 | LL | fn c<'a,'b>(x: &mut &'a isize, y: &mut &'b isize) { | --------- --------- these two types are declared with different lifetimes... @@ -17,7 +17,7 @@ LL | a(x, y); | ^ ...but data from `y` flows into `x` here error[E0308]: mismatched types - --> $DIR/region-lifetime-bounds-on-fns-where-clause.rs:20:43 + --> $DIR/region-lifetime-bounds-on-fns-where-clause.rs:28:43 | LL | let _: fn(&mut &isize, &mut &isize) = a; | ^ one type is more general than the other diff --git a/src/test/ui/regions/region-lifetime-bounds-on-fns-where-clause.nll.stderr b/src/test/ui/regions/region-lifetime-bounds-on-fns-where-clause.nll.stderr index 233a040491c..c6430974334 100644 --- a/src/test/ui/regions/region-lifetime-bounds-on-fns-where-clause.nll.stderr +++ b/src/test/ui/regions/region-lifetime-bounds-on-fns-where-clause.nll.stderr @@ -1,5 +1,5 @@ error: lifetime may not live long enough - --> $DIR/region-lifetime-bounds-on-fns-where-clause.rs:8:5 + --> $DIR/region-lifetime-bounds-on-fns-where-clause.rs:12:5 | LL | fn b<'a, 'b>(x: &mut &'a isize, y: &mut &'b isize) { | -- -- lifetime `'b` defined here @@ -12,7 +12,7 @@ LL | *x = *y; = help: consider adding the following bound: `'b: 'a` error: lifetime may not live long enough - --> $DIR/region-lifetime-bounds-on-fns-where-clause.rs:14:5 + --> $DIR/region-lifetime-bounds-on-fns-where-clause.rs:20:5 | LL | fn c<'a,'b>(x: &mut &'a isize, y: &mut &'b isize) { | -- -- lifetime `'b` defined here @@ -28,7 +28,7 @@ LL | a(x, y); = help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance error[E0308]: mismatched types - --> $DIR/region-lifetime-bounds-on-fns-where-clause.rs:20:12 + --> $DIR/region-lifetime-bounds-on-fns-where-clause.rs:28:12 | LL | let _: fn(&mut &isize, &mut &isize) = a; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other @@ -37,7 +37,7 @@ LL | let _: fn(&mut &isize, &mut &isize) = a; found fn pointer `for<'r, 's> fn(&'r mut &isize, &'s mut &isize)` error[E0308]: mismatched types - --> $DIR/region-lifetime-bounds-on-fns-where-clause.rs:20:12 + --> $DIR/region-lifetime-bounds-on-fns-where-clause.rs:28:12 | LL | let _: fn(&mut &isize, &mut &isize) = a; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other diff --git a/src/test/ui/regions/region-lifetime-bounds-on-fns-where-clause.rs b/src/test/ui/regions/region-lifetime-bounds-on-fns-where-clause.rs index ab4c6d9cf91..ec91d179808 100644 --- a/src/test/ui/regions/region-lifetime-bounds-on-fns-where-clause.rs +++ b/src/test/ui/regions/region-lifetime-bounds-on-fns-where-clause.rs @@ -1,3 +1,7 @@ +// revisions: base nll +// ignore-compare-mode-nll +//[nll] compile-flags: -Z borrowck=mir + fn a<'a, 'b>(x: &mut &'a isize, y: &mut &'b isize) where 'b: 'a { // Note: this is legal because of the `'b:'a` declaration. *x = *y; @@ -5,19 +9,25 @@ fn a<'a, 'b>(x: &mut &'a isize, y: &mut &'b isize) where 'b: 'a { fn b<'a, 'b>(x: &mut &'a isize, y: &mut &'b isize) { // Illegal now because there is no `'b:'a` declaration. - *x = *y; //~ ERROR E0623 + *x = *y; + //[base]~^ ERROR E0623 + //[nll]~^^ ERROR lifetime may not live long enough } fn c<'a,'b>(x: &mut &'a isize, y: &mut &'b isize) { // Here we try to call `foo` but do not know that `'a` and `'b` are // related as required. - a(x, y); //~ ERROR lifetime mismatch [E0623] + a(x, y); + //[base]~^ ERROR lifetime mismatch [E0623] + //[nll]~^^ ERROR lifetime may not live long enough } fn d() { // 'a and 'b are early bound in the function `a` because they appear // inconstraints: - let _: fn(&mut &isize, &mut &isize) = a; //~ ERROR mismatched types + let _: fn(&mut &isize, &mut &isize) = a; + //~^ ERROR mismatched types [E0308] + //[nll]~^^ ERROR mismatched types [E0308] } fn e() { diff --git a/src/test/ui/regions/region-multiple-lifetime-bounds-on-fns-where-clause.stderr b/src/test/ui/regions/region-multiple-lifetime-bounds-on-fns-where-clause.base.stderr index c93f2890f11..537a1fb98a5 100644 --- a/src/test/ui/regions/region-multiple-lifetime-bounds-on-fns-where-clause.stderr +++ b/src/test/ui/regions/region-multiple-lifetime-bounds-on-fns-where-clause.base.stderr @@ -1,5 +1,5 @@ error[E0623]: lifetime mismatch - --> $DIR/region-multiple-lifetime-bounds-on-fns-where-clause.rs:9:10 + --> $DIR/region-multiple-lifetime-bounds-on-fns-where-clause.rs:13:10 | LL | fn b<'a, 'b, 'c>(x: &mut &'a isize, y: &mut &'b isize, z: &mut &'c isize) { | --------- --------- these two types are declared with different lifetimes... @@ -8,7 +8,7 @@ LL | *x = *y; | ^^ ...but data from `y` flows into `x` here error[E0623]: lifetime mismatch - --> $DIR/region-multiple-lifetime-bounds-on-fns-where-clause.rs:10:10 + --> $DIR/region-multiple-lifetime-bounds-on-fns-where-clause.rs:16:10 | LL | fn b<'a, 'b, 'c>(x: &mut &'a isize, y: &mut &'b isize, z: &mut &'c isize) { | --------- --------- @@ -19,7 +19,7 @@ LL | *z = *y; | ^^ ...but data from `y` flows into `z` here error[E0623]: lifetime mismatch - --> $DIR/region-multiple-lifetime-bounds-on-fns-where-clause.rs:16:7 + --> $DIR/region-multiple-lifetime-bounds-on-fns-where-clause.rs:22:7 | LL | fn c<'a,'b, 'c>(x: &mut &'a isize, y: &mut &'b isize, z: &mut &'c isize) { | --------- --------- these two types are declared with different lifetimes... @@ -28,7 +28,7 @@ LL | a(x, y, z); | ^ ...but data from `y` flows into `x` here error[E0308]: mismatched types - --> $DIR/region-multiple-lifetime-bounds-on-fns-where-clause.rs:22:56 + --> $DIR/region-multiple-lifetime-bounds-on-fns-where-clause.rs:30:56 | LL | let _: fn(&mut &isize, &mut &isize, &mut &isize) = a; | ^ one type is more general than the other diff --git a/src/test/ui/regions/region-multiple-lifetime-bounds-on-fns-where-clause.nll.stderr b/src/test/ui/regions/region-multiple-lifetime-bounds-on-fns-where-clause.nll.stderr index 00119743acd..053078f58df 100644 --- a/src/test/ui/regions/region-multiple-lifetime-bounds-on-fns-where-clause.nll.stderr +++ b/src/test/ui/regions/region-multiple-lifetime-bounds-on-fns-where-clause.nll.stderr @@ -1,5 +1,5 @@ error: lifetime may not live long enough - --> $DIR/region-multiple-lifetime-bounds-on-fns-where-clause.rs:9:5 + --> $DIR/region-multiple-lifetime-bounds-on-fns-where-clause.rs:13:5 | LL | fn b<'a, 'b, 'c>(x: &mut &'a isize, y: &mut &'b isize, z: &mut &'c isize) { | -- -- lifetime `'b` defined here @@ -12,7 +12,7 @@ LL | *x = *y; = help: consider adding the following bound: `'b: 'a` error: lifetime may not live long enough - --> $DIR/region-multiple-lifetime-bounds-on-fns-where-clause.rs:16:5 + --> $DIR/region-multiple-lifetime-bounds-on-fns-where-clause.rs:22:5 | LL | fn c<'a,'b, 'c>(x: &mut &'a isize, y: &mut &'b isize, z: &mut &'c isize) { | -- -- lifetime `'b` defined here @@ -28,7 +28,7 @@ LL | a(x, y, z); = help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance error[E0308]: mismatched types - --> $DIR/region-multiple-lifetime-bounds-on-fns-where-clause.rs:22:12 + --> $DIR/region-multiple-lifetime-bounds-on-fns-where-clause.rs:30:12 | LL | let _: fn(&mut &isize, &mut &isize, &mut &isize) = a; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other @@ -37,7 +37,7 @@ LL | let _: fn(&mut &isize, &mut &isize, &mut &isize) = a; found fn pointer `for<'r, 's, 't0> fn(&'r mut &isize, &'s mut &isize, &'t0 mut &isize)` error[E0308]: mismatched types - --> $DIR/region-multiple-lifetime-bounds-on-fns-where-clause.rs:22:12 + --> $DIR/region-multiple-lifetime-bounds-on-fns-where-clause.rs:30:12 | LL | let _: fn(&mut &isize, &mut &isize, &mut &isize) = a; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other @@ -46,7 +46,7 @@ LL | let _: fn(&mut &isize, &mut &isize, &mut &isize) = a; found fn pointer `for<'r, 's, 't0> fn(&'r mut &isize, &'s mut &isize, &'t0 mut &isize)` error[E0308]: mismatched types - --> $DIR/region-multiple-lifetime-bounds-on-fns-where-clause.rs:22:12 + --> $DIR/region-multiple-lifetime-bounds-on-fns-where-clause.rs:30:12 | LL | let _: fn(&mut &isize, &mut &isize, &mut &isize) = a; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other diff --git a/src/test/ui/regions/region-multiple-lifetime-bounds-on-fns-where-clause.polonius.stderr b/src/test/ui/regions/region-multiple-lifetime-bounds-on-fns-where-clause.polonius.stderr deleted file mode 100644 index 13741664ef2..00000000000 --- a/src/test/ui/regions/region-multiple-lifetime-bounds-on-fns-where-clause.polonius.stderr +++ /dev/null @@ -1,82 +0,0 @@ -error: lifetime may not live long enough - --> $DIR/region-multiple-lifetime-bounds-on-fns-where-clause.rs:9:5 - | -LL | fn b<'a, 'b, 'c>(x: &mut &'a isize, y: &mut &'b isize, z: &mut &'c isize) { - | -- -- lifetime `'b` defined here - | | - | lifetime `'a` defined here -LL | // Illegal now because there is no `'b:'a` declaration. -LL | *x = *y; - | ^^^^^^^ assignment requires that `'b` must outlive `'a` - | - = help: consider adding the following bound: `'b: 'a` - -error: lifetime may not live long enough - --> $DIR/region-multiple-lifetime-bounds-on-fns-where-clause.rs:10:5 - | -LL | fn b<'a, 'b, 'c>(x: &mut &'a isize, y: &mut &'b isize, z: &mut &'c isize) { - | -- -- lifetime `'c` defined here - | | - | lifetime `'b` defined here -... -LL | *z = *y; - | ^^^^^^^ assignment requires that `'b` must outlive `'c` - | - = help: consider adding the following bound: `'b: 'c` - -help: add bound `'b: 'a + 'c` - -error: lifetime may not live long enough - --> $DIR/region-multiple-lifetime-bounds-on-fns-where-clause.rs:16:5 - | -LL | fn c<'a,'b, 'c>(x: &mut &'a isize, y: &mut &'b isize, z: &mut &'c isize) { - | -- -- lifetime `'b` defined here - | | - | lifetime `'a` defined here -... -LL | a(x, y, z); - | ^^^^^^^^^^ argument requires that `'b` must outlive `'a` - | - = help: consider adding the following bound: `'b: 'a` - = note: requirement occurs because of a mutable reference to &isize - = note: mutable references are invariant over their type parameter - = help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance - -error: lifetime may not live long enough - --> $DIR/region-multiple-lifetime-bounds-on-fns-where-clause.rs:16:5 - | -LL | fn c<'a,'b, 'c>(x: &mut &'a isize, y: &mut &'b isize, z: &mut &'c isize) { - | -- -- lifetime `'c` defined here - | | - | lifetime `'b` defined here -... -LL | a(x, y, z); - | ^^^^^^^^^^ argument requires that `'b` must outlive `'c` - | - = help: consider adding the following bound: `'b: 'c` - = note: requirement occurs because of a mutable reference to &isize - = note: mutable references are invariant over their type parameter - = help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance - -help: add bound `'b: 'a + 'c` - -error: higher-ranked subtype error - --> $DIR/region-multiple-lifetime-bounds-on-fns-where-clause.rs:22:12 - | -LL | let _: fn(&mut &isize, &mut &isize, &mut &isize) = a; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: higher-ranked subtype error - --> $DIR/region-multiple-lifetime-bounds-on-fns-where-clause.rs:22:12 - | -LL | let _: fn(&mut &isize, &mut &isize, &mut &isize) = a; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: higher-ranked subtype error - --> $DIR/region-multiple-lifetime-bounds-on-fns-where-clause.rs:22:12 - | -LL | let _: fn(&mut &isize, &mut &isize, &mut &isize) = a; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: aborting due to 7 previous errors - diff --git a/src/test/ui/regions/region-multiple-lifetime-bounds-on-fns-where-clause.rs b/src/test/ui/regions/region-multiple-lifetime-bounds-on-fns-where-clause.rs index 066522548ad..8b5c1d47ec6 100644 --- a/src/test/ui/regions/region-multiple-lifetime-bounds-on-fns-where-clause.rs +++ b/src/test/ui/regions/region-multiple-lifetime-bounds-on-fns-where-clause.rs @@ -1,3 +1,7 @@ +// revisions: base nll +// ignore-compare-mode-nll +//[nll] compile-flags: -Z borrowck=mir + fn a<'a, 'b, 'c>(x: &mut &'a isize, y: &mut &'b isize, z: &mut &'c isize) where 'b: 'a + 'c { // Note: this is legal because of the `'b:'a` declaration. *x = *y; @@ -6,20 +10,27 @@ fn a<'a, 'b, 'c>(x: &mut &'a isize, y: &mut &'b isize, z: &mut &'c isize) where fn b<'a, 'b, 'c>(x: &mut &'a isize, y: &mut &'b isize, z: &mut &'c isize) { // Illegal now because there is no `'b:'a` declaration. - *x = *y; //~ ERROR E0623 - *z = *y; //~ ERROR E0623 + *x = *y; + //[base]~^ ERROR E0623 + //[nll]~^^ ERROR lifetime may not live long enough + *z = *y; //[base]~ ERROR E0623 } fn c<'a,'b, 'c>(x: &mut &'a isize, y: &mut &'b isize, z: &mut &'c isize) { // Here we try to call `foo` but do not know that `'a` and `'b` are // related as required. - a(x, y, z); //~ ERROR lifetime mismatch [E0623] + a(x, y, z); + //[base]~^ ERROR lifetime mismatch [E0623] + //[nll]~^^ ERROR lifetime may not live long enough } fn d() { // 'a and 'b are early bound in the function `a` because they appear // inconstraints: - let _: fn(&mut &isize, &mut &isize, &mut &isize) = a; //~ ERROR E0308 + let _: fn(&mut &isize, &mut &isize, &mut &isize) = a; + //~^ ERROR E0308 + //[nll]~^^ ERROR mismatched types [E0308] + //[nll]~| ERROR mismatched types [E0308] } fn e() { diff --git a/src/test/ui/regions/region-object-lifetime-2.stderr b/src/test/ui/regions/region-object-lifetime-2.base.stderr index 380e27ab0e0..118fe476500 100644 --- a/src/test/ui/regions/region-object-lifetime-2.stderr +++ b/src/test/ui/regions/region-object-lifetime-2.base.stderr @@ -1,26 +1,26 @@ error[E0495]: cannot infer an appropriate lifetime for autoref due to conflicting requirements - --> $DIR/region-object-lifetime-2.rs:10:7 + --> $DIR/region-object-lifetime-2.rs:14:7 | LL | x.borrowed() | ^^^^^^^^ | note: first, the lifetime cannot outlive the lifetime `'a` as defined here... - --> $DIR/region-object-lifetime-2.rs:9:42 + --> $DIR/region-object-lifetime-2.rs:13:42 | LL | fn borrowed_receiver_different_lifetimes<'a,'b>(x: &'a dyn Foo) -> &'b () { | ^^ note: ...so that reference does not outlive borrowed content - --> $DIR/region-object-lifetime-2.rs:10:5 + --> $DIR/region-object-lifetime-2.rs:14:5 | LL | x.borrowed() | ^ note: but, the lifetime must be valid for the lifetime `'b` as defined here... - --> $DIR/region-object-lifetime-2.rs:9:45 + --> $DIR/region-object-lifetime-2.rs:13:45 | LL | fn borrowed_receiver_different_lifetimes<'a,'b>(x: &'a dyn Foo) -> &'b () { | ^^ note: ...so that reference does not outlive borrowed content - --> $DIR/region-object-lifetime-2.rs:10:5 + --> $DIR/region-object-lifetime-2.rs:14:5 | LL | x.borrowed() | ^^^^^^^^^^^^ diff --git a/src/test/ui/regions/region-object-lifetime-2.nll.stderr b/src/test/ui/regions/region-object-lifetime-2.nll.stderr index d95289f3f9d..c0b09ebb6f5 100644 --- a/src/test/ui/regions/region-object-lifetime-2.nll.stderr +++ b/src/test/ui/regions/region-object-lifetime-2.nll.stderr @@ -1,5 +1,5 @@ error: lifetime may not live long enough - --> $DIR/region-object-lifetime-2.rs:10:5 + --> $DIR/region-object-lifetime-2.rs:14:5 | LL | fn borrowed_receiver_different_lifetimes<'a,'b>(x: &'a dyn Foo) -> &'b () { | -- -- lifetime `'b` defined here diff --git a/src/test/ui/regions/region-object-lifetime-2.rs b/src/test/ui/regions/region-object-lifetime-2.rs index 42798487893..e12b9822f60 100644 --- a/src/test/ui/regions/region-object-lifetime-2.rs +++ b/src/test/ui/regions/region-object-lifetime-2.rs @@ -1,13 +1,19 @@ // Various tests related to testing how region inference works // with respect to the object receivers. +// revisions: base nll +// ignore-compare-mode-nll +//[nll] compile-flags: -Z borrowck=mir + trait Foo { fn borrowed<'a>(&'a self) -> &'a (); } // Borrowed receiver but two distinct lifetimes, we get an error. fn borrowed_receiver_different_lifetimes<'a,'b>(x: &'a dyn Foo) -> &'b () { - x.borrowed() //~ ERROR cannot infer + x.borrowed() + //[base]~^ ERROR cannot infer + //[nll]~^^ ERROR lifetime may not live long enough } fn main() {} diff --git a/src/test/ui/regions/region-object-lifetime-4.stderr b/src/test/ui/regions/region-object-lifetime-4.base.stderr index b59163ef13b..3765076a9c5 100644 --- a/src/test/ui/regions/region-object-lifetime-4.stderr +++ b/src/test/ui/regions/region-object-lifetime-4.base.stderr @@ -1,26 +1,26 @@ error[E0495]: cannot infer an appropriate lifetime for autoref due to conflicting requirements - --> $DIR/region-object-lifetime-4.rs:12:7 + --> $DIR/region-object-lifetime-4.rs:16:7 | LL | x.borrowed() | ^^^^^^^^ | note: first, the lifetime cannot outlive the lifetime `'a` as defined here... - --> $DIR/region-object-lifetime-4.rs:11:41 + --> $DIR/region-object-lifetime-4.rs:15:41 | LL | fn borrowed_receiver_related_lifetimes2<'a,'b>(x: &'a (dyn Foo + 'b)) -> &'b () { | ^^ note: ...so that reference does not outlive borrowed content - --> $DIR/region-object-lifetime-4.rs:12:5 + --> $DIR/region-object-lifetime-4.rs:16:5 | LL | x.borrowed() | ^ note: but, the lifetime must be valid for the lifetime `'b` as defined here... - --> $DIR/region-object-lifetime-4.rs:11:44 + --> $DIR/region-object-lifetime-4.rs:15:44 | LL | fn borrowed_receiver_related_lifetimes2<'a,'b>(x: &'a (dyn Foo + 'b)) -> &'b () { | ^^ note: ...so that reference does not outlive borrowed content - --> $DIR/region-object-lifetime-4.rs:12:5 + --> $DIR/region-object-lifetime-4.rs:16:5 | LL | x.borrowed() | ^^^^^^^^^^^^ diff --git a/src/test/ui/regions/region-object-lifetime-4.nll.stderr b/src/test/ui/regions/region-object-lifetime-4.nll.stderr index fda66a2412c..a2a958f90b2 100644 --- a/src/test/ui/regions/region-object-lifetime-4.nll.stderr +++ b/src/test/ui/regions/region-object-lifetime-4.nll.stderr @@ -1,5 +1,5 @@ error: lifetime may not live long enough - --> $DIR/region-object-lifetime-4.rs:12:5 + --> $DIR/region-object-lifetime-4.rs:16:5 | LL | fn borrowed_receiver_related_lifetimes2<'a,'b>(x: &'a (dyn Foo + 'b)) -> &'b () { | -- -- lifetime `'b` defined here diff --git a/src/test/ui/regions/region-object-lifetime-4.rs b/src/test/ui/regions/region-object-lifetime-4.rs index 4fe12b2acfc..aad9c2c9521 100644 --- a/src/test/ui/regions/region-object-lifetime-4.rs +++ b/src/test/ui/regions/region-object-lifetime-4.rs @@ -1,6 +1,10 @@ // Various tests related to testing how region inference works // with respect to the object receivers. +// revisions: base nll +// ignore-compare-mode-nll +//[nll] compile-flags: -Z borrowck=mir + trait Foo { fn borrowed<'a>(&'a self) -> &'a (); } @@ -9,7 +13,9 @@ trait Foo { // with the longer lifetime when (from the signature) we only know // that it lives as long as the shorter lifetime. Therefore, error. fn borrowed_receiver_related_lifetimes2<'a,'b>(x: &'a (dyn Foo + 'b)) -> &'b () { - x.borrowed() //~ ERROR cannot infer + x.borrowed() + //[base]~^ ERROR cannot infer + //[nll]~^^ ERROR lifetime may not live long enough } fn main() {} diff --git a/src/test/ui/regions/region-object-lifetime-in-coercion.stderr b/src/test/ui/regions/region-object-lifetime-in-coercion.base.stderr index d8932c067ac..85bfa16b3d3 100644 --- a/src/test/ui/regions/region-object-lifetime-in-coercion.stderr +++ b/src/test/ui/regions/region-object-lifetime-in-coercion.base.stderr @@ -1,5 +1,5 @@ error[E0759]: `v` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement - --> $DIR/region-object-lifetime-in-coercion.rs:8:46 + --> $DIR/region-object-lifetime-in-coercion.rs:12:46 | LL | fn a(v: &[u8]) -> Box<dyn Foo + 'static> { | ----- this data with an anonymous lifetime `'_`... @@ -16,7 +16,7 @@ LL | fn a(v: &'static [u8]) -> Box<dyn Foo + 'static> { | ~~~~~~~~~~~~~ error[E0759]: `v` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement - --> $DIR/region-object-lifetime-in-coercion.rs:13:14 + --> $DIR/region-object-lifetime-in-coercion.rs:19:14 | LL | fn b(v: &[u8]) -> Box<dyn Foo + 'static> { | ----- this data with an anonymous lifetime `'_`... @@ -24,7 +24,7 @@ LL | Box::new(v) | ^ ...is used and required to live as long as `'static` here | note: `'static` lifetime requirement introduced by the return type - --> $DIR/region-object-lifetime-in-coercion.rs:12:33 + --> $DIR/region-object-lifetime-in-coercion.rs:18:33 | LL | fn b(v: &[u8]) -> Box<dyn Foo + 'static> { | ^^^^^^^ `'static` requirement introduced here @@ -40,7 +40,7 @@ LL | fn b(v: &'static [u8]) -> Box<dyn Foo + 'static> { | ~~~~~~~~~~~~~ error[E0759]: `v` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement - --> $DIR/region-object-lifetime-in-coercion.rs:19:14 + --> $DIR/region-object-lifetime-in-coercion.rs:27:14 | LL | fn c(v: &[u8]) -> Box<dyn Foo> { | ----- this data with an anonymous lifetime `'_`... @@ -49,7 +49,7 @@ LL | Box::new(v) | ^ ...is used and required to live as long as `'static` here | note: `'static` lifetime requirement introduced by the return type - --> $DIR/region-object-lifetime-in-coercion.rs:16:23 + --> $DIR/region-object-lifetime-in-coercion.rs:24:23 | LL | fn c(v: &[u8]) -> Box<dyn Foo> { | ^^^^^^^ `'static` requirement introduced here @@ -62,30 +62,30 @@ LL | fn c(v: &[u8]) -> Box<dyn Foo + '_> { | ++++ error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements - --> $DIR/region-object-lifetime-in-coercion.rs:23:14 + --> $DIR/region-object-lifetime-in-coercion.rs:33:14 | LL | Box::new(v) | ^ | note: first, the lifetime cannot outlive the lifetime `'a` as defined here... - --> $DIR/region-object-lifetime-in-coercion.rs:22:6 + --> $DIR/region-object-lifetime-in-coercion.rs:32:6 | LL | fn d<'a,'b>(v: &'a [u8]) -> Box<dyn Foo+'b> { | ^^ note: ...so that the expression is assignable - --> $DIR/region-object-lifetime-in-coercion.rs:23:14 + --> $DIR/region-object-lifetime-in-coercion.rs:33:14 | LL | Box::new(v) | ^ = note: expected `&[u8]` found `&'a [u8]` note: but, the lifetime must be valid for the lifetime `'b` as defined here... - --> $DIR/region-object-lifetime-in-coercion.rs:22:9 + --> $DIR/region-object-lifetime-in-coercion.rs:32:9 | LL | fn d<'a,'b>(v: &'a [u8]) -> Box<dyn Foo+'b> { | ^^ note: ...so that the types are compatible - --> $DIR/region-object-lifetime-in-coercion.rs:23:5 + --> $DIR/region-object-lifetime-in-coercion.rs:33:5 | LL | Box::new(v) | ^^^^^^^^^^^ diff --git a/src/test/ui/regions/region-object-lifetime-in-coercion.nll.stderr b/src/test/ui/regions/region-object-lifetime-in-coercion.nll.stderr index 92588819076..724b06ce8b1 100644 --- a/src/test/ui/regions/region-object-lifetime-in-coercion.nll.stderr +++ b/src/test/ui/regions/region-object-lifetime-in-coercion.nll.stderr @@ -1,30 +1,53 @@ error: lifetime may not live long enough - --> $DIR/region-object-lifetime-in-coercion.rs:8:12 + --> $DIR/region-object-lifetime-in-coercion.rs:12:12 | LL | fn a(v: &[u8]) -> Box<dyn Foo + 'static> { | - let's call the lifetime of this reference `'1` LL | let x: Box<dyn Foo + 'static> = Box::new(v); | ^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'1` must outlive `'static` + | +help: consider changing the trait object's explicit `'static` bound to the lifetime of argument `v` + | +LL | fn a(v: &[u8]) -> Box<dyn Foo + '_> { + | ~~ +help: alternatively, add an explicit `'static` bound to this reference + | +LL | fn a(v: &'static [u8]) -> Box<dyn Foo + 'static> { + | ~~~~~~~~~~~~~ error: lifetime may not live long enough - --> $DIR/region-object-lifetime-in-coercion.rs:13:5 + --> $DIR/region-object-lifetime-in-coercion.rs:19:5 | LL | fn b(v: &[u8]) -> Box<dyn Foo + 'static> { | - let's call the lifetime of this reference `'1` LL | Box::new(v) | ^^^^^^^^^^^ returning this value requires that `'1` must outlive `'static` + | +help: consider changing the trait object's explicit `'static` bound to the lifetime of argument `v` + | +LL | fn b(v: &[u8]) -> Box<dyn Foo + '_> { + | ~~ +help: alternatively, add an explicit `'static` bound to this reference + | +LL | fn b(v: &'static [u8]) -> Box<dyn Foo + 'static> { + | ~~~~~~~~~~~~~ error: lifetime may not live long enough - --> $DIR/region-object-lifetime-in-coercion.rs:19:5 + --> $DIR/region-object-lifetime-in-coercion.rs:27:5 | LL | fn c(v: &[u8]) -> Box<dyn Foo> { | - let's call the lifetime of this reference `'1` ... LL | Box::new(v) | ^^^^^^^^^^^ returning this value requires that `'1` must outlive `'static` + | +help: to declare that the trait object captures data from argument `v`, you can add an explicit `'_` lifetime bound + | +LL | fn c(v: &[u8]) -> Box<dyn Foo + '_> { + | ++++ error: lifetime may not live long enough - --> $DIR/region-object-lifetime-in-coercion.rs:23:5 + --> $DIR/region-object-lifetime-in-coercion.rs:33:5 | LL | fn d<'a,'b>(v: &'a [u8]) -> Box<dyn Foo+'b> { | -- -- lifetime `'b` defined here diff --git a/src/test/ui/regions/region-object-lifetime-in-coercion.rs b/src/test/ui/regions/region-object-lifetime-in-coercion.rs index 9d3f485e314..ed28d6c0ff1 100644 --- a/src/test/ui/regions/region-object-lifetime-in-coercion.rs +++ b/src/test/ui/regions/region-object-lifetime-in-coercion.rs @@ -1,26 +1,38 @@ // Test that attempts to implicitly coerce a value into an // object respect the lifetime bound on the object type. +// revisions: base nll +// ignore-compare-mode-nll +//[nll] compile-flags: -Z borrowck=mir + trait Foo {} impl<'a> Foo for &'a [u8] {} fn a(v: &[u8]) -> Box<dyn Foo + 'static> { - let x: Box<dyn Foo + 'static> = Box::new(v); //~ ERROR E0759 + let x: Box<dyn Foo + 'static> = Box::new(v); + //[base]~^ ERROR E0759 + //[nll]~^^ ERROR lifetime may not live long enough x } fn b(v: &[u8]) -> Box<dyn Foo + 'static> { - Box::new(v) //~ ERROR E0759 + Box::new(v) + //[base]~^ ERROR E0759 + //[nll]~^^ ERROR lifetime may not live long enough } fn c(v: &[u8]) -> Box<dyn Foo> { // same as previous case due to RFC 599 - Box::new(v) //~ ERROR E0759 + Box::new(v) + //[base]~^ ERROR E0759 + //[nll]~^^ ERROR lifetime may not live long enough } fn d<'a,'b>(v: &'a [u8]) -> Box<dyn Foo+'b> { - Box::new(v) //~ ERROR cannot infer an appropriate lifetime due to conflicting + Box::new(v) + //[base]~^ ERROR cannot infer an appropriate lifetime due to conflicting + //[nll]~^^ ERROR lifetime may not live long enough } fn e<'a:'b,'b>(v: &'a [u8]) -> Box<dyn Foo+'b> { diff --git a/src/test/ui/regions/regions-addr-of-self.stderr b/src/test/ui/regions/regions-addr-of-self.base.stderr index 3453c6458f1..3167c2f2107 100644 --- a/src/test/ui/regions/regions-addr-of-self.stderr +++ b/src/test/ui/regions/regions-addr-of-self.base.stderr @@ -1,5 +1,5 @@ error[E0759]: `self` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement - --> $DIR/regions-addr-of-self.rs:7:37 + --> $DIR/regions-addr-of-self.rs:11:37 | LL | pub fn chase_cat(&mut self) { | --------- this data with an anonymous lifetime `'_`... diff --git a/src/test/ui/regions/regions-addr-of-self.nll.stderr b/src/test/ui/regions/regions-addr-of-self.nll.stderr index 3d7aac74bd4..1f720520f6b 100644 --- a/src/test/ui/regions/regions-addr-of-self.nll.stderr +++ b/src/test/ui/regions/regions-addr-of-self.nll.stderr @@ -1,5 +1,5 @@ error: lifetime may not live long enough - --> $DIR/regions-addr-of-self.rs:7:16 + --> $DIR/regions-addr-of-self.rs:11:16 | LL | pub fn chase_cat(&mut self) { | - let's call the lifetime of this reference `'1` diff --git a/src/test/ui/regions/regions-addr-of-self.rs b/src/test/ui/regions/regions-addr-of-self.rs index 4eb1b275f16..698433c71b3 100644 --- a/src/test/ui/regions/regions-addr-of-self.rs +++ b/src/test/ui/regions/regions-addr-of-self.rs @@ -1,10 +1,16 @@ +// revisions: base nll +// ignore-compare-mode-nll +//[nll] compile-flags: -Z borrowck=mir + struct Dog { cats_chased: usize, } impl Dog { pub fn chase_cat(&mut self) { - let p: &'static mut usize = &mut self.cats_chased; //~ ERROR E0759 + let p: &'static mut usize = &mut self.cats_chased; + //[base]~^ ERROR E0759 + //[nll]~^^ ERROR lifetime may not live long enough *p += 1; } diff --git a/src/test/ui/regions/regions-addr-of-upvar-self.stderr b/src/test/ui/regions/regions-addr-of-upvar-self.base.stderr index f638064ef83..42d0638e8b7 100644 --- a/src/test/ui/regions/regions-addr-of-upvar-self.stderr +++ b/src/test/ui/regions/regions-addr-of-upvar-self.base.stderr @@ -1,22 +1,22 @@ error[E0495]: cannot infer an appropriate lifetime for borrow expression due to conflicting requirements - --> $DIR/regions-addr-of-upvar-self.rs:8:41 + --> $DIR/regions-addr-of-upvar-self.rs:12:41 | LL | let p: &'static mut usize = &mut self.food; | ^^^^^^^^^^^^^^ | note: first, the lifetime cannot outlive the lifetime `'_` as defined here... - --> $DIR/regions-addr-of-upvar-self.rs:7:18 + --> $DIR/regions-addr-of-upvar-self.rs:11:18 | LL | let _f = || { | ^^ note: ...so that closure can access `self` - --> $DIR/regions-addr-of-upvar-self.rs:8:41 + --> $DIR/regions-addr-of-upvar-self.rs:12:41 | LL | let p: &'static mut usize = &mut self.food; | ^^^^^^^^^^^^^^ = note: but, the lifetime must be valid for the static lifetime... note: ...so that reference does not outlive borrowed content - --> $DIR/regions-addr-of-upvar-self.rs:8:41 + --> $DIR/regions-addr-of-upvar-self.rs:12:41 | LL | let p: &'static mut usize = &mut self.food; | ^^^^^^^^^^^^^^ diff --git a/src/test/ui/regions/regions-addr-of-upvar-self.nll.stderr b/src/test/ui/regions/regions-addr-of-upvar-self.nll.stderr index c16a6f8585b..b8e37e92316 100644 --- a/src/test/ui/regions/regions-addr-of-upvar-self.nll.stderr +++ b/src/test/ui/regions/regions-addr-of-upvar-self.nll.stderr @@ -1,5 +1,5 @@ error: lifetime may not live long enough - --> $DIR/regions-addr-of-upvar-self.rs:8:20 + --> $DIR/regions-addr-of-upvar-self.rs:12:20 | LL | let _f = || { | -- lifetime `'1` represents this closure's body @@ -9,7 +9,7 @@ LL | let p: &'static mut usize = &mut self.food; = note: closure implements `FnMut`, so references to captured variables can't escape the closure error: lifetime may not live long enough - --> $DIR/regions-addr-of-upvar-self.rs:8:20 + --> $DIR/regions-addr-of-upvar-self.rs:12:20 | LL | pub fn chase_cat(&mut self) { | - let's call the lifetime of this reference `'1` @@ -18,7 +18,7 @@ LL | let p: &'static mut usize = &mut self.food; | ^^^^^^^^^^^^^^^^^^ type annotation requires that `'1` must outlive `'static` error[E0597]: `self` does not live long enough - --> $DIR/regions-addr-of-upvar-self.rs:8:46 + --> $DIR/regions-addr-of-upvar-self.rs:12:46 | LL | let _f = || { | -- value captured here diff --git a/src/test/ui/regions/regions-addr-of-upvar-self.rs b/src/test/ui/regions/regions-addr-of-upvar-self.rs index 6159ab02d3d..36cc592d47c 100644 --- a/src/test/ui/regions/regions-addr-of-upvar-self.rs +++ b/src/test/ui/regions/regions-addr-of-upvar-self.rs @@ -1,3 +1,7 @@ +// revisions: base nll +// ignore-compare-mode-nll +//[nll] compile-flags: -Z borrowck=mir + struct Dog { food: usize, } @@ -5,7 +9,11 @@ struct Dog { impl Dog { pub fn chase_cat(&mut self) { let _f = || { - let p: &'static mut usize = &mut self.food; //~ ERROR cannot infer + let p: &'static mut usize = &mut self.food; + //[base]~^ ERROR cannot infer + //[nll]~^^ ERROR lifetime may not live long enough + //[nll]~^^^ ERROR lifetime may not live long enough + //[nll]~^^^^ ERROR E0597 *p = 3; }; } diff --git a/src/test/ui/regions/regions-bounded-by-trait-requiring-static.stderr b/src/test/ui/regions/regions-bounded-by-trait-requiring-static.base.stderr index 68b90eee72d..9b45dcfd95a 100644 --- a/src/test/ui/regions/regions-bounded-by-trait-requiring-static.stderr +++ b/src/test/ui/regions/regions-bounded-by-trait-requiring-static.base.stderr @@ -1,71 +1,71 @@ error[E0477]: the type `&'a isize` does not fulfill the required lifetime - --> $DIR/regions-bounded-by-trait-requiring-static.rs:22:5 + --> $DIR/regions-bounded-by-trait-requiring-static.rs:26:5 | LL | assert_send::<&'a isize>(); | ^^^^^^^^^^^^^^^^^^^^^^^^ | note: type must satisfy the static lifetime as required by this binding - --> $DIR/regions-bounded-by-trait-requiring-static.rs:6:18 + --> $DIR/regions-bounded-by-trait-requiring-static.rs:10:18 | LL | fn assert_send<T:'static>() { } | ^^^^^^^ error[E0477]: the type `&'a str` does not fulfill the required lifetime - --> $DIR/regions-bounded-by-trait-requiring-static.rs:26:5 + --> $DIR/regions-bounded-by-trait-requiring-static.rs:32:5 | LL | assert_send::<&'a str>(); | ^^^^^^^^^^^^^^^^^^^^^^ | note: type must satisfy the static lifetime as required by this binding - --> $DIR/regions-bounded-by-trait-requiring-static.rs:6:18 + --> $DIR/regions-bounded-by-trait-requiring-static.rs:10:18 | LL | fn assert_send<T:'static>() { } | ^^^^^^^ error[E0477]: the type `&'a [isize]` does not fulfill the required lifetime - --> $DIR/regions-bounded-by-trait-requiring-static.rs:30:5 + --> $DIR/regions-bounded-by-trait-requiring-static.rs:38:5 | LL | assert_send::<&'a [isize]>(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: type must satisfy the static lifetime as required by this binding - --> $DIR/regions-bounded-by-trait-requiring-static.rs:6:18 + --> $DIR/regions-bounded-by-trait-requiring-static.rs:10:18 | LL | fn assert_send<T:'static>() { } | ^^^^^^^ error[E0477]: the type `Box<&'a isize>` does not fulfill the required lifetime - --> $DIR/regions-bounded-by-trait-requiring-static.rs:44:5 + --> $DIR/regions-bounded-by-trait-requiring-static.rs:54:5 | LL | assert_send::<Box<&'a isize>>(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: type must satisfy the static lifetime as required by this binding - --> $DIR/regions-bounded-by-trait-requiring-static.rs:6:18 + --> $DIR/regions-bounded-by-trait-requiring-static.rs:10:18 | LL | fn assert_send<T:'static>() { } | ^^^^^^^ error[E0477]: the type `*const &'a isize` does not fulfill the required lifetime - --> $DIR/regions-bounded-by-trait-requiring-static.rs:55:5 + --> $DIR/regions-bounded-by-trait-requiring-static.rs:67:5 | LL | assert_send::<*const &'a isize>(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: type must satisfy the static lifetime as required by this binding - --> $DIR/regions-bounded-by-trait-requiring-static.rs:6:18 + --> $DIR/regions-bounded-by-trait-requiring-static.rs:10:18 | LL | fn assert_send<T:'static>() { } | ^^^^^^^ error[E0477]: the type `*mut &'a isize` does not fulfill the required lifetime - --> $DIR/regions-bounded-by-trait-requiring-static.rs:59:5 + --> $DIR/regions-bounded-by-trait-requiring-static.rs:73:5 | LL | assert_send::<*mut &'a isize>(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: type must satisfy the static lifetime as required by this binding - --> $DIR/regions-bounded-by-trait-requiring-static.rs:6:18 + --> $DIR/regions-bounded-by-trait-requiring-static.rs:10:18 | LL | fn assert_send<T:'static>() { } | ^^^^^^^ diff --git a/src/test/ui/regions/regions-bounded-by-trait-requiring-static.nll.stderr b/src/test/ui/regions/regions-bounded-by-trait-requiring-static.nll.stderr index 86bd100538d..558a77516bb 100644 --- a/src/test/ui/regions/regions-bounded-by-trait-requiring-static.nll.stderr +++ b/src/test/ui/regions/regions-bounded-by-trait-requiring-static.nll.stderr @@ -1,5 +1,5 @@ error: lifetime may not live long enough - --> $DIR/regions-bounded-by-trait-requiring-static.rs:22:5 + --> $DIR/regions-bounded-by-trait-requiring-static.rs:26:5 | LL | fn param_not_ok<'a>(x: &'a isize) { | -- lifetime `'a` defined here @@ -7,7 +7,7 @@ LL | assert_send::<&'a isize>(); | ^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'static` error: lifetime may not live long enough - --> $DIR/regions-bounded-by-trait-requiring-static.rs:26:5 + --> $DIR/regions-bounded-by-trait-requiring-static.rs:32:5 | LL | fn param_not_ok1<'a>(_: &'a isize) { | -- lifetime `'a` defined here @@ -15,7 +15,7 @@ LL | assert_send::<&'a str>(); | ^^^^^^^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'static` error: lifetime may not live long enough - --> $DIR/regions-bounded-by-trait-requiring-static.rs:30:5 + --> $DIR/regions-bounded-by-trait-requiring-static.rs:38:5 | LL | fn param_not_ok2<'a>(_: &'a isize) { | -- lifetime `'a` defined here @@ -23,7 +23,7 @@ LL | assert_send::<&'a [isize]>(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'static` error: lifetime may not live long enough - --> $DIR/regions-bounded-by-trait-requiring-static.rs:44:5 + --> $DIR/regions-bounded-by-trait-requiring-static.rs:54:5 | LL | fn box_with_region_not_ok<'a>() { | -- lifetime `'a` defined here @@ -31,7 +31,7 @@ LL | assert_send::<Box<&'a isize>>(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'static` error: lifetime may not live long enough - --> $DIR/regions-bounded-by-trait-requiring-static.rs:55:5 + --> $DIR/regions-bounded-by-trait-requiring-static.rs:67:5 | LL | fn unsafe_ok2<'a>(_: &'a isize) { | -- lifetime `'a` defined here @@ -39,7 +39,7 @@ LL | assert_send::<*const &'a isize>(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'static` error: lifetime may not live long enough - --> $DIR/regions-bounded-by-trait-requiring-static.rs:59:5 + --> $DIR/regions-bounded-by-trait-requiring-static.rs:73:5 | LL | fn unsafe_ok3<'a>(_: &'a isize) { | -- lifetime `'a` defined here diff --git a/src/test/ui/regions/regions-bounded-by-trait-requiring-static.rs b/src/test/ui/regions/regions-bounded-by-trait-requiring-static.rs index c583f43638a..37dc1300d39 100644 --- a/src/test/ui/regions/regions-bounded-by-trait-requiring-static.rs +++ b/src/test/ui/regions/regions-bounded-by-trait-requiring-static.rs @@ -2,6 +2,10 @@ // in this file all test region bound and lifetime violations that are // detected during type check. +// revisions: base nll +// ignore-compare-mode-nll +//[nll] compile-flags: -Z borrowck=mir + trait Dummy : 'static { } fn assert_send<T:'static>() { } @@ -19,15 +23,21 @@ fn static_lifime_ok<'a,T,U:Send>(_: &'a isize) { // otherwise lifetime pointers are not ok fn param_not_ok<'a>(x: &'a isize) { - assert_send::<&'a isize>(); //~ ERROR does not fulfill the required lifetime + assert_send::<&'a isize>(); + //[base]~^ ERROR does not fulfill the required lifetime + //[nll]~^^ ERROR lifetime may not live long enough } fn param_not_ok1<'a>(_: &'a isize) { - assert_send::<&'a str>(); //~ ERROR does not fulfill the required lifetime + assert_send::<&'a str>(); + //[base]~^ ERROR does not fulfill the required lifetime + //[nll]~^^ ERROR lifetime may not live long enough } fn param_not_ok2<'a>(_: &'a isize) { - assert_send::<&'a [isize]>(); //~ ERROR does not fulfill the required lifetime + assert_send::<&'a [isize]>(); + //[base]~^ ERROR does not fulfill the required lifetime + //[nll]~^^ ERROR lifetime may not live long enough } // boxes are ok @@ -41,7 +51,9 @@ fn box_ok() { // but not if they own a bad thing fn box_with_region_not_ok<'a>() { - assert_send::<Box<&'a isize>>(); //~ ERROR does not fulfill the required lifetime + assert_send::<Box<&'a isize>>(); + //[base]~^ ERROR does not fulfill the required lifetime + //[nll]~^^ ERROR lifetime may not live long enough } // raw pointers are ok unless they point at unsendable things @@ -52,11 +64,15 @@ fn unsafe_ok1<'a>(_: &'a isize) { } fn unsafe_ok2<'a>(_: &'a isize) { - assert_send::<*const &'a isize>(); //~ ERROR does not fulfill the required lifetime + assert_send::<*const &'a isize>(); + //[base]~^ ERROR does not fulfill the required lifetime + //[nll]~^^ ERROR lifetime may not live long enough } fn unsafe_ok3<'a>(_: &'a isize) { - assert_send::<*mut &'a isize>(); //~ ERROR does not fulfill the required lifetime + assert_send::<*mut &'a isize>(); + //[base]~^ ERROR does not fulfill the required lifetime + //[nll]~^^ ERROR lifetime may not live long enough } fn main() { diff --git a/src/test/ui/regions/regions-bounded-method-type-parameters-cross-crate.stderr b/src/test/ui/regions/regions-bounded-method-type-parameters-cross-crate.base.stderr index eb205a303db..e031f0db412 100644 --- a/src/test/ui/regions/regions-bounded-method-type-parameters-cross-crate.stderr +++ b/src/test/ui/regions/regions-bounded-method-type-parameters-cross-crate.base.stderr @@ -1,5 +1,5 @@ error[E0623]: lifetime mismatch - --> $DIR/regions-bounded-method-type-parameters-cross-crate.rs:20:7 + --> $DIR/regions-bounded-method-type-parameters-cross-crate.rs:23:7 | LL | fn call_bigger_region<'x, 'y>(a: Inv<'x>, b: Inv<'y>) { | ------- ------- these two types are declared with different lifetimes... diff --git a/src/test/ui/regions/regions-bounded-method-type-parameters-cross-crate.nll.stderr b/src/test/ui/regions/regions-bounded-method-type-parameters-cross-crate.nll.stderr index 6193bf02f6d..4f5d747be71 100644 --- a/src/test/ui/regions/regions-bounded-method-type-parameters-cross-crate.nll.stderr +++ b/src/test/ui/regions/regions-bounded-method-type-parameters-cross-crate.nll.stderr @@ -1,5 +1,5 @@ error: lifetime may not live long enough - --> $DIR/regions-bounded-method-type-parameters-cross-crate.rs:20:5 + --> $DIR/regions-bounded-method-type-parameters-cross-crate.rs:23:5 | LL | fn call_bigger_region<'x, 'y>(a: Inv<'x>, b: Inv<'y>) { | -- -- lifetime `'y` defined here diff --git a/src/test/ui/regions/regions-bounded-method-type-parameters-cross-crate.rs b/src/test/ui/regions/regions-bounded-method-type-parameters-cross-crate.rs index a7987d0e1fe..e0965613f1d 100644 --- a/src/test/ui/regions/regions-bounded-method-type-parameters-cross-crate.rs +++ b/src/test/ui/regions/regions-bounded-method-type-parameters-cross-crate.rs @@ -1,4 +1,7 @@ // aux-build:rbmtp_cross_crate_lib.rs +// revisions: base nll +// ignore-compare-mode-nll +//[nll] compile-flags: -Z borrowck=mir // Check explicit region bounds on methods in the cross crate case. @@ -17,7 +20,9 @@ fn call_into_maybe_owned<'x,F:IntoMaybeOwned<'x>>(f: F) { fn call_bigger_region<'x, 'y>(a: Inv<'x>, b: Inv<'y>) { // Here the value provided for 'y is 'y, and hence 'y:'x does not hold. - a.bigger_region(b) //~ ERROR lifetime mismatch [E0623] + a.bigger_region(b) + //[base]~^ ERROR lifetime mismatch [E0623] + //[nll]~^^ ERROR lifetime may not live long enough } fn main() { } diff --git a/src/test/ui/regions/regions-bounded-method-type-parameters-trait-bound.stderr b/src/test/ui/regions/regions-bounded-method-type-parameters-trait-bound.base.stderr index de1073cd1d9..0a213e3f779 100644 --- a/src/test/ui/regions/regions-bounded-method-type-parameters-trait-bound.stderr +++ b/src/test/ui/regions/regions-bounded-method-type-parameters-trait-bound.base.stderr @@ -1,5 +1,5 @@ error[E0623]: lifetime mismatch - --> $DIR/regions-bounded-method-type-parameters-trait-bound.rs:20:7 + --> $DIR/regions-bounded-method-type-parameters-trait-bound.rs:24:7 | LL | fn caller2<'a,'b,F:Foo<'a>>(a: Inv<'a>, b: Inv<'b>, f: F) { | ------- ------- these two types are declared with different lifetimes... diff --git a/src/test/ui/regions/regions-bounded-method-type-parameters-trait-bound.nll.stderr b/src/test/ui/regions/regions-bounded-method-type-parameters-trait-bound.nll.stderr index 0e0086be9ea..1c2f46a5fc1 100644 --- a/src/test/ui/regions/regions-bounded-method-type-parameters-trait-bound.nll.stderr +++ b/src/test/ui/regions/regions-bounded-method-type-parameters-trait-bound.nll.stderr @@ -1,5 +1,5 @@ error: lifetime may not live long enough - --> $DIR/regions-bounded-method-type-parameters-trait-bound.rs:20:5 + --> $DIR/regions-bounded-method-type-parameters-trait-bound.rs:24:5 | LL | fn caller2<'a,'b,F:Foo<'a>>(a: Inv<'a>, b: Inv<'b>, f: F) { | -- -- lifetime `'b` defined here diff --git a/src/test/ui/regions/regions-bounded-method-type-parameters-trait-bound.rs b/src/test/ui/regions/regions-bounded-method-type-parameters-trait-bound.rs index 8adf496b230..8a52a1549ab 100644 --- a/src/test/ui/regions/regions-bounded-method-type-parameters-trait-bound.rs +++ b/src/test/ui/regions/regions-bounded-method-type-parameters-trait-bound.rs @@ -2,6 +2,10 @@ // nominal types (but not on other types) and that they are type // checked. +// revisions: base nll +// ignore-compare-mode-nll +//[nll] compile-flags: -Z borrowck=mir + struct Inv<'a> { // invariant w/r/t 'a x: &'a mut &'a isize } @@ -17,7 +21,9 @@ fn caller1<'a,'b,F:Foo<'a>>(a: Inv<'a>, b: Inv<'b>, f: F) { fn caller2<'a,'b,F:Foo<'a>>(a: Inv<'a>, b: Inv<'b>, f: F) { // Here the value provided for 'y is 'b, and hence 'b:'a does not hold. - f.method(b); //~ ERROR lifetime mismatch [E0623] + f.method(b); + //[base]~^ ERROR lifetime mismatch [E0623] + //[nll]~^^ ERROR lifetime may not live long enough } fn caller3<'a,'b:'a,F:Foo<'a>>(a: Inv<'a>, b: Inv<'b>, f: F) { diff --git a/src/test/ui/regions/regions-bounded-method-type-parameters.stderr b/src/test/ui/regions/regions-bounded-method-type-parameters.base.stderr index 318e9d006a1..3d37a1ba47b 100644 --- a/src/test/ui/regions/regions-bounded-method-type-parameters.stderr +++ b/src/test/ui/regions/regions-bounded-method-type-parameters.base.stderr @@ -1,11 +1,11 @@ error[E0477]: the type `&'a isize` does not fulfill the required lifetime - --> $DIR/regions-bounded-method-type-parameters.rs:12:9 + --> $DIR/regions-bounded-method-type-parameters.rs:16:9 | LL | Foo.some_method::<&'a isize>(); | ^^^^^^^^^^^ | note: type must satisfy the static lifetime as required by this binding - --> $DIR/regions-bounded-method-type-parameters.rs:8:22 + --> $DIR/regions-bounded-method-type-parameters.rs:12:22 | LL | fn some_method<A:'static>(self) { } | ^^^^^^^ diff --git a/src/test/ui/regions/regions-bounded-method-type-parameters.nll.stderr b/src/test/ui/regions/regions-bounded-method-type-parameters.nll.stderr index b6d7b8aac5f..05c3fa58ea3 100644 --- a/src/test/ui/regions/regions-bounded-method-type-parameters.nll.stderr +++ b/src/test/ui/regions/regions-bounded-method-type-parameters.nll.stderr @@ -1,5 +1,5 @@ error: lifetime may not live long enough - --> $DIR/regions-bounded-method-type-parameters.rs:12:9 + --> $DIR/regions-bounded-method-type-parameters.rs:16:9 | LL | fn caller<'a>(x: &isize) { | -- lifetime `'a` defined here diff --git a/src/test/ui/regions/regions-bounded-method-type-parameters.rs b/src/test/ui/regions/regions-bounded-method-type-parameters.rs index 90af120f052..06bc1544a38 100644 --- a/src/test/ui/regions/regions-bounded-method-type-parameters.rs +++ b/src/test/ui/regions/regions-bounded-method-type-parameters.rs @@ -2,6 +2,10 @@ // nominal types (but not on other types) and that they are type // checked. +// revisions: base nll +// ignore-compare-mode-nll +//[nll] compile-flags: -Z borrowck=mir + struct Foo; impl Foo { @@ -10,7 +14,8 @@ impl Foo { fn caller<'a>(x: &isize) { Foo.some_method::<&'a isize>(); - //~^ ERROR does not fulfill the required lifetime + //[base]~^ ERROR does not fulfill the required lifetime + //[nll]~^^ ERROR lifetime may not live long enough } fn main() { } diff --git a/src/test/ui/regions/regions-bounds.stderr b/src/test/ui/regions/regions-bounds.base.stderr index 90227e574ad..d853cdde336 100644 --- a/src/test/ui/regions/regions-bounds.stderr +++ b/src/test/ui/regions/regions-bounds.base.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/regions-bounds.rs:9:12 + --> $DIR/regions-bounds.rs:13:12 | LL | return e; | ^ lifetime mismatch @@ -7,18 +7,18 @@ LL | return e; = note: expected struct `TupleStruct<'b>` found struct `TupleStruct<'a>` note: the lifetime `'a` as defined here... - --> $DIR/regions-bounds.rs:8:10 + --> $DIR/regions-bounds.rs:12:10 | LL | fn a_fn1<'a,'b>(e: TupleStruct<'a>) -> TupleStruct<'b> { | ^^ note: ...does not necessarily outlive the lifetime `'b` as defined here - --> $DIR/regions-bounds.rs:8:13 + --> $DIR/regions-bounds.rs:12:13 | LL | fn a_fn1<'a,'b>(e: TupleStruct<'a>) -> TupleStruct<'b> { | ^^ error[E0308]: mismatched types - --> $DIR/regions-bounds.rs:13:12 + --> $DIR/regions-bounds.rs:19:12 | LL | return e; | ^ lifetime mismatch @@ -26,12 +26,12 @@ LL | return e; = note: expected struct `Struct<'b>` found struct `Struct<'a>` note: the lifetime `'a` as defined here... - --> $DIR/regions-bounds.rs:12:10 + --> $DIR/regions-bounds.rs:18:10 | LL | fn a_fn3<'a,'b>(e: Struct<'a>) -> Struct<'b> { | ^^ note: ...does not necessarily outlive the lifetime `'b` as defined here - --> $DIR/regions-bounds.rs:12:13 + --> $DIR/regions-bounds.rs:18:13 | LL | fn a_fn3<'a,'b>(e: Struct<'a>) -> Struct<'b> { | ^^ diff --git a/src/test/ui/regions/regions-bounds.nll.stderr b/src/test/ui/regions/regions-bounds.nll.stderr index 84226a57553..7109220165f 100644 --- a/src/test/ui/regions/regions-bounds.nll.stderr +++ b/src/test/ui/regions/regions-bounds.nll.stderr @@ -1,5 +1,5 @@ error: lifetime may not live long enough - --> $DIR/regions-bounds.rs:9:12 + --> $DIR/regions-bounds.rs:13:12 | LL | fn a_fn1<'a,'b>(e: TupleStruct<'a>) -> TupleStruct<'b> { | -- -- lifetime `'b` defined here @@ -11,7 +11,7 @@ LL | return e; = help: consider adding the following bound: `'a: 'b` error: lifetime may not live long enough - --> $DIR/regions-bounds.rs:13:12 + --> $DIR/regions-bounds.rs:19:12 | LL | fn a_fn3<'a,'b>(e: Struct<'a>) -> Struct<'b> { | -- -- lifetime `'b` defined here diff --git a/src/test/ui/regions/regions-bounds.rs b/src/test/ui/regions/regions-bounds.rs index d3e4e6e8712..b13dac49f8c 100644 --- a/src/test/ui/regions/regions-bounds.rs +++ b/src/test/ui/regions/regions-bounds.rs @@ -2,15 +2,23 @@ // nominal types (but not on other types) and that they are type // checked. +// revisions: base nll +// ignore-compare-mode-nll +//[nll] compile-flags: -Z borrowck=mir + struct TupleStruct<'a>(&'a isize); struct Struct<'a> { x:&'a isize } fn a_fn1<'a,'b>(e: TupleStruct<'a>) -> TupleStruct<'b> { - return e; //~ ERROR mismatched types + return e; + //[base]~^ ERROR mismatched types + //[nll]~^^ ERROR lifetime may not live long enough } fn a_fn3<'a,'b>(e: Struct<'a>) -> Struct<'b> { - return e; //~ ERROR mismatched types + return e; + //[base]~^ ERROR mismatched types + //[nll]~^^ ERROR lifetime may not live long enough } fn main() { } diff --git a/src/test/ui/regions/regions-close-associated-type-into-object.stderr b/src/test/ui/regions/regions-close-associated-type-into-object.base.stderr index 536a1b5e359..fbbb5980401 100644 --- a/src/test/ui/regions/regions-close-associated-type-into-object.stderr +++ b/src/test/ui/regions/regions-close-associated-type-into-object.base.stderr @@ -1,5 +1,5 @@ error[E0310]: the associated type `<T as Iter>::Item` may not live long enough - --> $DIR/regions-close-associated-type-into-object.rs:15:5 + --> $DIR/regions-close-associated-type-into-object.rs:19:5 | LL | Box::new(item) | ^^^^^^^^^^^^^^ @@ -8,7 +8,7 @@ LL | Box::new(item) = note: ...so that the type `<T as Iter>::Item` will meet its required lifetime bounds error[E0310]: the associated type `<T as Iter>::Item` may not live long enough - --> $DIR/regions-close-associated-type-into-object.rs:22:5 + --> $DIR/regions-close-associated-type-into-object.rs:26:5 | LL | Box::new(item) | ^^^^^^^^^^^^^^ @@ -17,7 +17,7 @@ LL | Box::new(item) = note: ...so that the type `Box<<T as Iter>::Item>` will meet its required lifetime bounds error[E0309]: the associated type `<T as Iter>::Item` may not live long enough - --> $DIR/regions-close-associated-type-into-object.rs:28:5 + --> $DIR/regions-close-associated-type-into-object.rs:32:5 | LL | Box::new(item) | ^^^^^^^^^^^^^^ @@ -26,7 +26,7 @@ LL | Box::new(item) = note: ...so that the type `<T as Iter>::Item` will meet its required lifetime bounds error[E0309]: the associated type `<T as Iter>::Item` may not live long enough - --> $DIR/regions-close-associated-type-into-object.rs:35:5 + --> $DIR/regions-close-associated-type-into-object.rs:39:5 | LL | Box::new(item) | ^^^^^^^^^^^^^^ diff --git a/src/test/ui/regions/regions-close-associated-type-into-object.nll.stderr b/src/test/ui/regions/regions-close-associated-type-into-object.nll.stderr index 92c4956da02..dd4b97aa562 100644 --- a/src/test/ui/regions/regions-close-associated-type-into-object.nll.stderr +++ b/src/test/ui/regions/regions-close-associated-type-into-object.nll.stderr @@ -1,34 +1,38 @@ error[E0310]: the associated type `<T as Iter>::Item` may not live long enough - --> $DIR/regions-close-associated-type-into-object.rs:15:5 + --> $DIR/regions-close-associated-type-into-object.rs:19:5 | LL | Box::new(item) | ^^^^^^^^^^^^^^ | = help: consider adding an explicit lifetime bound `<T as Iter>::Item: 'static`... + = note: ...so that the type `<T as Iter>::Item` will meet its required lifetime bounds error[E0310]: the associated type `<T as Iter>::Item` may not live long enough - --> $DIR/regions-close-associated-type-into-object.rs:22:5 + --> $DIR/regions-close-associated-type-into-object.rs:26:5 | LL | Box::new(item) | ^^^^^^^^^^^^^^ | = help: consider adding an explicit lifetime bound `<T as Iter>::Item: 'static`... + = note: ...so that the type `<T as Iter>::Item` will meet its required lifetime bounds error[E0309]: the associated type `<T as Iter>::Item` may not live long enough - --> $DIR/regions-close-associated-type-into-object.rs:28:5 + --> $DIR/regions-close-associated-type-into-object.rs:32:5 | LL | Box::new(item) | ^^^^^^^^^^^^^^ | = help: consider adding an explicit lifetime bound `<T as Iter>::Item: 'a`... + = note: ...so that the type `<T as Iter>::Item` will meet its required lifetime bounds error[E0309]: the associated type `<T as Iter>::Item` may not live long enough - --> $DIR/regions-close-associated-type-into-object.rs:35:5 + --> $DIR/regions-close-associated-type-into-object.rs:39:5 | LL | Box::new(item) | ^^^^^^^^^^^^^^ | = help: consider adding an explicit lifetime bound `<T as Iter>::Item: 'a`... + = note: ...so that the type `<T as Iter>::Item` will meet its required lifetime bounds error: aborting due to 4 previous errors diff --git a/src/test/ui/regions/regions-close-associated-type-into-object.rs b/src/test/ui/regions/regions-close-associated-type-into-object.rs index 428477e2489..94199f56212 100644 --- a/src/test/ui/regions/regions-close-associated-type-into-object.rs +++ b/src/test/ui/regions/regions-close-associated-type-into-object.rs @@ -1,3 +1,7 @@ +// revisions: base nll +// ignore-compare-mode-nll +//[nll] compile-flags: -Z borrowck=mir + trait X {} diff --git a/src/test/ui/regions/regions-close-object-into-object-2.stderr b/src/test/ui/regions/regions-close-object-into-object-2.base.stderr index 4153f4f29bc..ddf168ffd10 100644 --- a/src/test/ui/regions/regions-close-object-into-object-2.stderr +++ b/src/test/ui/regions/regions-close-object-into-object-2.base.stderr @@ -1,5 +1,5 @@ error[E0759]: `v` has lifetime `'a` but it needs to satisfy a `'static` lifetime requirement - --> $DIR/regions-close-object-into-object-2.rs:9:16 + --> $DIR/regions-close-object-into-object-2.rs:13:16 | LL | fn g<'a, T: 'static>(v: Box<dyn A<T> + 'a>) -> Box<dyn X + 'static> { | ------------------ this data with lifetime `'a`... @@ -7,7 +7,7 @@ LL | Box::new(B(&*v)) as Box<dyn X> | ^^^ ...is used and required to live as long as `'static` here | note: `'static` lifetime requirement introduced by the return type - --> $DIR/regions-close-object-into-object-2.rs:8:60 + --> $DIR/regions-close-object-into-object-2.rs:12:60 | LL | fn g<'a, T: 'static>(v: Box<dyn A<T> + 'a>) -> Box<dyn X + 'static> { | ^^^^^^^ `'static` requirement introduced here diff --git a/src/test/ui/regions/regions-close-object-into-object-2.nll.stderr b/src/test/ui/regions/regions-close-object-into-object-2.nll.stderr index 6a0e9586161..473c99b672f 100644 --- a/src/test/ui/regions/regions-close-object-into-object-2.nll.stderr +++ b/src/test/ui/regions/regions-close-object-into-object-2.nll.stderr @@ -1,13 +1,22 @@ error: lifetime may not live long enough - --> $DIR/regions-close-object-into-object-2.rs:9:5 + --> $DIR/regions-close-object-into-object-2.rs:13:5 | LL | fn g<'a, T: 'static>(v: Box<dyn A<T> + 'a>) -> Box<dyn X + 'static> { | -- lifetime `'a` defined here LL | Box::new(B(&*v)) as Box<dyn X> | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ returning this value requires that `'a` must outlive `'static` + | +help: consider changing the trait object's explicit `'static` bound to the lifetime of argument `v` + | +LL | fn g<'a, T: 'static>(v: Box<dyn A<T> + 'a>) -> Box<dyn X + 'a> { + | ~~ +help: alternatively, add an explicit `'static` bound to this reference + | +LL | fn g<'a, T: 'static>(v: Box<(dyn A<T> + 'static)>) -> Box<dyn X + 'static> { + | ~~~~~~~~~~~~~~~~~~~~~~~~~ error[E0515]: cannot return value referencing local data `*v` - --> $DIR/regions-close-object-into-object-2.rs:9:5 + --> $DIR/regions-close-object-into-object-2.rs:13:5 | LL | Box::new(B(&*v)) as Box<dyn X> | ^^^^^^^^^^^---^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/regions/regions-close-object-into-object-2.rs b/src/test/ui/regions/regions-close-object-into-object-2.rs index 9c41174e24d..33ea03f061e 100644 --- a/src/test/ui/regions/regions-close-object-into-object-2.rs +++ b/src/test/ui/regions/regions-close-object-into-object-2.rs @@ -1,3 +1,7 @@ +// revisions: base nll +// ignore-compare-mode-nll +//[nll] compile-flags: -Z borrowck=mir + trait A<T> { } struct B<'a, T:'a>(&'a (dyn A<T> + 'a)); @@ -6,7 +10,10 @@ trait X { } impl<'a, T> X for B<'a, T> {} fn g<'a, T: 'static>(v: Box<dyn A<T> + 'a>) -> Box<dyn X + 'static> { - Box::new(B(&*v)) as Box<dyn X> //~ ERROR E0759 + Box::new(B(&*v)) as Box<dyn X> + //[base]~^ ERROR E0759 + //[nll]~^^ ERROR lifetime may not live long enough + //[nll]~| ERROR cannot return value referencing local data `*v` [E0515] } fn main() { } diff --git a/src/test/ui/regions/regions-close-object-into-object-4.stderr b/src/test/ui/regions/regions-close-object-into-object-4.base.stderr index 2ea4b431b38..33d4df3d194 100644 --- a/src/test/ui/regions/regions-close-object-into-object-4.stderr +++ b/src/test/ui/regions/regions-close-object-into-object-4.base.stderr @@ -1,5 +1,5 @@ error[E0759]: `v` has lifetime `'a` but it needs to satisfy a `'static` lifetime requirement - --> $DIR/regions-close-object-into-object-4.rs:9:16 + --> $DIR/regions-close-object-into-object-4.rs:13:16 | LL | fn i<'a, T, U>(v: Box<dyn A<U>+'a>) -> Box<dyn X + 'static> { | ---------------- this data with lifetime `'a`... @@ -7,7 +7,7 @@ LL | Box::new(B(&*v)) as Box<dyn X> | ^^^ ...is used and required to live as long as `'static` here | note: `'static` lifetime requirement introduced by the return type - --> $DIR/regions-close-object-into-object-4.rs:8:52 + --> $DIR/regions-close-object-into-object-4.rs:12:52 | LL | fn i<'a, T, U>(v: Box<dyn A<U>+'a>) -> Box<dyn X + 'static> { | ^^^^^^^ `'static` requirement introduced here diff --git a/src/test/ui/regions/regions-close-object-into-object-4.nll.stderr b/src/test/ui/regions/regions-close-object-into-object-4.nll.stderr index b30626830ad..66d3102225e 100644 --- a/src/test/ui/regions/regions-close-object-into-object-4.nll.stderr +++ b/src/test/ui/regions/regions-close-object-into-object-4.nll.stderr @@ -1,37 +1,55 @@ error[E0310]: the parameter type `U` may not live long enough - --> $DIR/regions-close-object-into-object-4.rs:9:5 + --> $DIR/regions-close-object-into-object-4.rs:13:5 | LL | Box::new(B(&*v)) as Box<dyn X> - | ^^^^^^^^ + | ^^^^^^^^ ...so that the type `U` will meet its required lifetime bounds | - = help: consider adding an explicit lifetime bound `U: 'static`... +help: consider adding an explicit lifetime bound... + | +LL | fn i<'a, T, U: 'static>(v: Box<dyn A<U>+'a>) -> Box<dyn X + 'static> { + | +++++++++ error[E0310]: the parameter type `U` may not live long enough - --> $DIR/regions-close-object-into-object-4.rs:9:5 + --> $DIR/regions-close-object-into-object-4.rs:13:5 | LL | Box::new(B(&*v)) as Box<dyn X> - | ^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^ ...so that the type `U` will meet its required lifetime bounds + | +help: consider adding an explicit lifetime bound... | - = help: consider adding an explicit lifetime bound `U: 'static`... +LL | fn i<'a, T, U: 'static>(v: Box<dyn A<U>+'a>) -> Box<dyn X + 'static> { + | +++++++++ error[E0310]: the parameter type `U` may not live long enough - --> $DIR/regions-close-object-into-object-4.rs:9:5 + --> $DIR/regions-close-object-into-object-4.rs:13:5 | LL | Box::new(B(&*v)) as Box<dyn X> - | ^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^ ...so that the type `U` will meet its required lifetime bounds | - = help: consider adding an explicit lifetime bound `U: 'static`... +help: consider adding an explicit lifetime bound... + | +LL | fn i<'a, T, U: 'static>(v: Box<dyn A<U>+'a>) -> Box<dyn X + 'static> { + | +++++++++ error: lifetime may not live long enough - --> $DIR/regions-close-object-into-object-4.rs:9:5 + --> $DIR/regions-close-object-into-object-4.rs:13:5 | LL | fn i<'a, T, U>(v: Box<dyn A<U>+'a>) -> Box<dyn X + 'static> { | -- lifetime `'a` defined here LL | Box::new(B(&*v)) as Box<dyn X> | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ returning this value requires that `'a` must outlive `'static` + | +help: consider changing the trait object's explicit `'static` bound to the lifetime of argument `v` + | +LL | fn i<'a, T, U>(v: Box<dyn A<U>+'a>) -> Box<dyn X + 'a> { + | ~~ +help: alternatively, add an explicit `'static` bound to this reference + | +LL | fn i<'a, T, U>(v: Box<(dyn A<U> + 'static)>) -> Box<dyn X + 'static> { + | ~~~~~~~~~~~~~~~~~~~~~~~~~ error[E0515]: cannot return value referencing local data `*v` - --> $DIR/regions-close-object-into-object-4.rs:9:5 + --> $DIR/regions-close-object-into-object-4.rs:13:5 | LL | Box::new(B(&*v)) as Box<dyn X> | ^^^^^^^^^^^---^^^^^^^^^^^^^^^^ @@ -40,12 +58,15 @@ LL | Box::new(B(&*v)) as Box<dyn X> | returns a value referencing data owned by the current function error[E0310]: the parameter type `U` may not live long enough - --> $DIR/regions-close-object-into-object-4.rs:9:14 + --> $DIR/regions-close-object-into-object-4.rs:13:14 | LL | Box::new(B(&*v)) as Box<dyn X> - | ^^^^^^ + | ^^^^^^ ...so that the type `U` will meet its required lifetime bounds + | +help: consider adding an explicit lifetime bound... | - = help: consider adding an explicit lifetime bound `U: 'static`... +LL | fn i<'a, T, U: 'static>(v: Box<dyn A<U>+'a>) -> Box<dyn X + 'static> { + | +++++++++ error: aborting due to 6 previous errors diff --git a/src/test/ui/regions/regions-close-object-into-object-4.rs b/src/test/ui/regions/regions-close-object-into-object-4.rs index 2a06a2b7c05..5a852b7329a 100644 --- a/src/test/ui/regions/regions-close-object-into-object-4.rs +++ b/src/test/ui/regions/regions-close-object-into-object-4.rs @@ -1,3 +1,7 @@ +// revisions: base nll +// ignore-compare-mode-nll +//[nll] compile-flags: -Z borrowck=mir + trait A<T> { } struct B<'a, T:'a>(&'a (dyn A<T> + 'a)); @@ -6,7 +10,15 @@ trait X { } impl<'a, T> X for B<'a, T> {} fn i<'a, T, U>(v: Box<dyn A<U>+'a>) -> Box<dyn X + 'static> { - Box::new(B(&*v)) as Box<dyn X> //~ ERROR E0759 + Box::new(B(&*v)) as Box<dyn X> + //[base]~^ ERROR E0759 + //[nll]~^^ ERROR the parameter type `U` may not live long enough [E0310] + //[nll]~| ERROR the parameter type `U` may not live long enough [E0310] + //[nll]~| ERROR the parameter type `U` may not live long enough [E0310] + //[nll]~| ERROR lifetime may not live long enough + //[nll]~| ERROR cannot return value referencing local data `*v` [E0515] + //[nll]~| ERROR the parameter type `U` may not live long enough [E0310] + } fn main() {} diff --git a/src/test/ui/regions/regions-close-object-into-object-5.stderr b/src/test/ui/regions/regions-close-object-into-object-5.base.stderr index 512a7ab35fb..1a78079b638 100644 --- a/src/test/ui/regions/regions-close-object-into-object-5.stderr +++ b/src/test/ui/regions/regions-close-object-into-object-5.base.stderr @@ -1,83 +1,94 @@ error[E0310]: the parameter type `T` may not live long enough - --> $DIR/regions-close-object-into-object-5.rs:17:5 + --> $DIR/regions-close-object-into-object-5.rs:21:5 | -LL | fn f<'a, T, U>(v: Box<A<T> + 'static>) -> Box<X + 'static> { - | - help: consider adding an explicit lifetime bound...: `T: 'static` -LL | // oh dear! LL | Box::new(B(&*v)) as Box<dyn X> | ^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds... | note: ...that is required by this bound - --> $DIR/regions-close-object-into-object-5.rs:9:17 + --> $DIR/regions-close-object-into-object-5.rs:13:17 | LL | struct B<'a, T: 'a>(&'a (A<T> + 'a)); | ^^ +help: consider adding an explicit lifetime bound... + | +LL | fn f<'a, T: 'static, U>(v: Box<A<T> + 'static>) -> Box<X + 'static> { + | +++++++++ error[E0310]: the parameter type `T` may not live long enough - --> $DIR/regions-close-object-into-object-5.rs:17:5 + --> $DIR/regions-close-object-into-object-5.rs:21:5 | -LL | fn f<'a, T, U>(v: Box<A<T> + 'static>) -> Box<X + 'static> { - | - help: consider adding an explicit lifetime bound...: `T: 'static` -LL | // oh dear! LL | Box::new(B(&*v)) as Box<dyn X> | ^^^^^^^^^^^^^^^^ ...so that the type `B<'_, T>` will meet its required lifetime bounds + | +help: consider adding an explicit lifetime bound... + | +LL | fn f<'a, T: 'static, U>(v: Box<A<T> + 'static>) -> Box<X + 'static> { + | +++++++++ error[E0310]: the parameter type `T` may not live long enough - --> $DIR/regions-close-object-into-object-5.rs:17:14 + --> $DIR/regions-close-object-into-object-5.rs:21:14 | -LL | fn f<'a, T, U>(v: Box<A<T> + 'static>) -> Box<X + 'static> { - | - help: consider adding an explicit lifetime bound...: `T: 'static` -LL | // oh dear! LL | Box::new(B(&*v)) as Box<dyn X> | ^ ...so that the type `T` will meet its required lifetime bounds... | note: ...that is required by this bound - --> $DIR/regions-close-object-into-object-5.rs:9:17 + --> $DIR/regions-close-object-into-object-5.rs:13:17 | LL | struct B<'a, T: 'a>(&'a (A<T> + 'a)); | ^^ +help: consider adding an explicit lifetime bound... + | +LL | fn f<'a, T: 'static, U>(v: Box<A<T> + 'static>) -> Box<X + 'static> { + | +++++++++ error[E0310]: the parameter type `T` may not live long enough - --> $DIR/regions-close-object-into-object-5.rs:17:14 + --> $DIR/regions-close-object-into-object-5.rs:21:14 | -LL | fn f<'a, T, U>(v: Box<A<T> + 'static>) -> Box<X + 'static> { - | - help: consider adding an explicit lifetime bound...: `T: 'static` -LL | // oh dear! LL | Box::new(B(&*v)) as Box<dyn X> | ^^^^^^ ...so that the type `T` will meet its required lifetime bounds... | note: ...that is required by this bound - --> $DIR/regions-close-object-into-object-5.rs:9:17 + --> $DIR/regions-close-object-into-object-5.rs:13:17 | LL | struct B<'a, T: 'a>(&'a (A<T> + 'a)); | ^^ +help: consider adding an explicit lifetime bound... + | +LL | fn f<'a, T: 'static, U>(v: Box<A<T> + 'static>) -> Box<X + 'static> { + | +++++++++ error[E0310]: the parameter type `T` may not live long enough - --> $DIR/regions-close-object-into-object-5.rs:17:16 + --> $DIR/regions-close-object-into-object-5.rs:21:16 | -LL | fn f<'a, T, U>(v: Box<A<T> + 'static>) -> Box<X + 'static> { - | - help: consider adding an explicit lifetime bound...: `T: 'static` -LL | // oh dear! LL | Box::new(B(&*v)) as Box<dyn X> | ^^^ ...so that the reference type `&dyn A<T>` does not outlive the data it points at + | +help: consider adding an explicit lifetime bound... + | +LL | fn f<'a, T: 'static, U>(v: Box<A<T> + 'static>) -> Box<X + 'static> { + | +++++++++ error[E0310]: the parameter type `T` may not live long enough - --> $DIR/regions-close-object-into-object-5.rs:17:16 + --> $DIR/regions-close-object-into-object-5.rs:21:16 | -LL | fn f<'a, T, U>(v: Box<A<T> + 'static>) -> Box<X + 'static> { - | - help: consider adding an explicit lifetime bound...: `T: 'static` -LL | // oh dear! LL | Box::new(B(&*v)) as Box<dyn X> | ^^^ ...so that the type `(dyn A<T> + 'static)` is not borrowed for too long + | +help: consider adding an explicit lifetime bound... + | +LL | fn f<'a, T: 'static, U>(v: Box<A<T> + 'static>) -> Box<X + 'static> { + | +++++++++ error[E0310]: the parameter type `T` may not live long enough - --> $DIR/regions-close-object-into-object-5.rs:17:16 + --> $DIR/regions-close-object-into-object-5.rs:21:16 | -LL | fn f<'a, T, U>(v: Box<A<T> + 'static>) -> Box<X + 'static> { - | - help: consider adding an explicit lifetime bound...: `T: 'static` -LL | // oh dear! LL | Box::new(B(&*v)) as Box<dyn X> | ^^^ ...so that the type `(dyn A<T> + 'static)` is not borrowed for too long + | +help: consider adding an explicit lifetime bound... + | +LL | fn f<'a, T: 'static, U>(v: Box<A<T> + 'static>) -> Box<X + 'static> { + | +++++++++ error: aborting due to 7 previous errors diff --git a/src/test/ui/regions/regions-close-object-into-object-5.nll.stderr b/src/test/ui/regions/regions-close-object-into-object-5.nll.stderr index 7486e73e66a..cb06326130e 100644 --- a/src/test/ui/regions/regions-close-object-into-object-5.nll.stderr +++ b/src/test/ui/regions/regions-close-object-into-object-5.nll.stderr @@ -1,29 +1,38 @@ error[E0310]: the parameter type `T` may not live long enough - --> $DIR/regions-close-object-into-object-5.rs:17:5 + --> $DIR/regions-close-object-into-object-5.rs:21:5 | LL | Box::new(B(&*v)) as Box<dyn X> - | ^^^^^^^^ + | ^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds | - = help: consider adding an explicit lifetime bound `T: 'static`... +help: consider adding an explicit lifetime bound... + | +LL | fn f<'a, T: 'static, U>(v: Box<A<T> + 'static>) -> Box<X + 'static> { + | +++++++++ error[E0310]: the parameter type `T` may not live long enough - --> $DIR/regions-close-object-into-object-5.rs:17:5 + --> $DIR/regions-close-object-into-object-5.rs:21:5 | LL | Box::new(B(&*v)) as Box<dyn X> - | ^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds + | +help: consider adding an explicit lifetime bound... | - = help: consider adding an explicit lifetime bound `T: 'static`... +LL | fn f<'a, T: 'static, U>(v: Box<A<T> + 'static>) -> Box<X + 'static> { + | +++++++++ error[E0310]: the parameter type `T` may not live long enough - --> $DIR/regions-close-object-into-object-5.rs:17:5 + --> $DIR/regions-close-object-into-object-5.rs:21:5 | LL | Box::new(B(&*v)) as Box<dyn X> - | ^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds | - = help: consider adding an explicit lifetime bound `T: 'static`... +help: consider adding an explicit lifetime bound... + | +LL | fn f<'a, T: 'static, U>(v: Box<A<T> + 'static>) -> Box<X + 'static> { + | +++++++++ error[E0515]: cannot return value referencing local data `*v` - --> $DIR/regions-close-object-into-object-5.rs:17:5 + --> $DIR/regions-close-object-into-object-5.rs:21:5 | LL | Box::new(B(&*v)) as Box<dyn X> | ^^^^^^^^^^^---^^^^^^^^^^^^^^^^ @@ -32,12 +41,15 @@ LL | Box::new(B(&*v)) as Box<dyn X> | returns a value referencing data owned by the current function error[E0310]: the parameter type `T` may not live long enough - --> $DIR/regions-close-object-into-object-5.rs:17:14 + --> $DIR/regions-close-object-into-object-5.rs:21:14 | LL | Box::new(B(&*v)) as Box<dyn X> - | ^^^^^^ + | ^^^^^^ ...so that the type `T` will meet its required lifetime bounds + | +help: consider adding an explicit lifetime bound... | - = help: consider adding an explicit lifetime bound `T: 'static`... +LL | fn f<'a, T: 'static, U>(v: Box<A<T> + 'static>) -> Box<X + 'static> { + | +++++++++ error: aborting due to 5 previous errors diff --git a/src/test/ui/regions/regions-close-object-into-object-5.rs b/src/test/ui/regions/regions-close-object-into-object-5.rs index 5471c375b49..0e5fec28d19 100644 --- a/src/test/ui/regions/regions-close-object-into-object-5.rs +++ b/src/test/ui/regions/regions-close-object-into-object-5.rs @@ -1,3 +1,7 @@ +// revisions: base nll +// ignore-compare-mode-nll +//[nll] compile-flags: -Z borrowck=mir + #![allow(warnings)] @@ -19,9 +23,10 @@ fn f<'a, T, U>(v: Box<A<T> + 'static>) -> Box<X + 'static> { //~| ERROR the parameter type `T` may not live long enough //~| ERROR the parameter type `T` may not live long enough //~| ERROR the parameter type `T` may not live long enough - //~| ERROR the parameter type `T` may not live long enough - //~| ERROR the parameter type `T` may not live long enough - //~| ERROR the parameter type `T` may not live long enough + //[base]~| ERROR the parameter type `T` may not live long enough + //[base]~| ERROR the parameter type `T` may not live long enough + //[base]~| ERROR the parameter type `T` may not live long enough + //[nll]~| ERROR cannot return value referencing local data `*v` [E0515] } fn main() {} diff --git a/src/test/ui/regions/regions-close-over-type-parameter-1.stderr b/src/test/ui/regions/regions-close-over-type-parameter-1.base.stderr index 063c3b19a19..d8f77ad85c9 100644 --- a/src/test/ui/regions/regions-close-over-type-parameter-1.stderr +++ b/src/test/ui/regions/regions-close-over-type-parameter-1.base.stderr @@ -1,18 +1,24 @@ error[E0310]: the parameter type `A` may not live long enough - --> $DIR/regions-close-over-type-parameter-1.rs:12:5 + --> $DIR/regions-close-over-type-parameter-1.rs:15:5 | -LL | fn make_object1<A: SomeTrait>(v: A) -> Box<dyn SomeTrait + 'static> { - | -- help: consider adding an explicit lifetime bound...: `A: 'static +` LL | Box::new(v) as Box<dyn SomeTrait + 'static> | ^^^^^^^^^^^ ...so that the type `A` will meet its required lifetime bounds + | +help: consider adding an explicit lifetime bound... + | +LL | fn make_object1<A: SomeTrait + 'static>(v: A) -> Box<dyn SomeTrait + 'static> { + | +++++++++ error[E0309]: the parameter type `A` may not live long enough - --> $DIR/regions-close-over-type-parameter-1.rs:21:5 + --> $DIR/regions-close-over-type-parameter-1.rs:24:5 | -LL | fn make_object3<'a, 'b, A: SomeTrait + 'a>(v: A) -> Box<dyn SomeTrait + 'b> { - | -- help: consider adding an explicit lifetime bound...: `A: 'b +` LL | Box::new(v) as Box<dyn SomeTrait + 'b> | ^^^^^^^^^^^ ...so that the type `A` will meet its required lifetime bounds + | +help: consider adding an explicit lifetime bound... + | +LL | fn make_object3<'a, 'b, A: SomeTrait + 'a + 'b>(v: A) -> Box<dyn SomeTrait + 'b> { + | ++++ error: aborting due to 2 previous errors diff --git a/src/test/ui/regions/regions-close-over-type-parameter-1.nll.stderr b/src/test/ui/regions/regions-close-over-type-parameter-1.nll.stderr index b576ae87011..d8f77ad85c9 100644 --- a/src/test/ui/regions/regions-close-over-type-parameter-1.nll.stderr +++ b/src/test/ui/regions/regions-close-over-type-parameter-1.nll.stderr @@ -1,18 +1,24 @@ error[E0310]: the parameter type `A` may not live long enough - --> $DIR/regions-close-over-type-parameter-1.rs:12:5 + --> $DIR/regions-close-over-type-parameter-1.rs:15:5 | LL | Box::new(v) as Box<dyn SomeTrait + 'static> - | ^^^^^^^^^^^ + | ^^^^^^^^^^^ ...so that the type `A` will meet its required lifetime bounds | - = help: consider adding an explicit lifetime bound `A: 'static`... +help: consider adding an explicit lifetime bound... + | +LL | fn make_object1<A: SomeTrait + 'static>(v: A) -> Box<dyn SomeTrait + 'static> { + | +++++++++ error[E0309]: the parameter type `A` may not live long enough - --> $DIR/regions-close-over-type-parameter-1.rs:21:5 + --> $DIR/regions-close-over-type-parameter-1.rs:24:5 | LL | Box::new(v) as Box<dyn SomeTrait + 'b> - | ^^^^^^^^^^^ + | ^^^^^^^^^^^ ...so that the type `A` will meet its required lifetime bounds + | +help: consider adding an explicit lifetime bound... | - = help: consider adding an explicit lifetime bound `A: 'b`... +LL | fn make_object3<'a, 'b, A: SomeTrait + 'a + 'b>(v: A) -> Box<dyn SomeTrait + 'b> { + | ++++ error: aborting due to 2 previous errors diff --git a/src/test/ui/regions/regions-close-over-type-parameter-1.rs b/src/test/ui/regions/regions-close-over-type-parameter-1.rs index 52d18c5d7a6..cf425bcd4f3 100644 --- a/src/test/ui/regions/regions-close-over-type-parameter-1.rs +++ b/src/test/ui/regions/regions-close-over-type-parameter-1.rs @@ -2,6 +2,9 @@ // an object. This should yield errors unless `A` (and the object) // both have suitable bounds. +// revisions: base nll +// ignore-compare-mode-nll +//[nll] compile-flags: -Z borrowck=mir trait SomeTrait { fn get(&self) -> isize; diff --git a/src/test/ui/regions/regions-close-over-type-parameter-multiple.stderr b/src/test/ui/regions/regions-close-over-type-parameter-multiple.base.stderr index aa22fd96deb..171203897d7 100644 --- a/src/test/ui/regions/regions-close-over-type-parameter-multiple.stderr +++ b/src/test/ui/regions/regions-close-over-type-parameter-multiple.base.stderr @@ -1,26 +1,26 @@ error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements - --> $DIR/regions-close-over-type-parameter-multiple.rs:20:5 + --> $DIR/regions-close-over-type-parameter-multiple.rs:23:5 | LL | Box::new(v) as Box<dyn SomeTrait + 'a> | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: first, the lifetime cannot outlive the lifetime `'a` as defined here... - --> $DIR/regions-close-over-type-parameter-multiple.rs:18:20 + --> $DIR/regions-close-over-type-parameter-multiple.rs:21:20 | LL | fn make_object_bad<'a,'b,'c,A:SomeTrait+'a+'b>(v: A) -> Box<dyn SomeTrait + 'c> { | ^^ note: ...so that the declared lifetime parameter bounds are satisfied - --> $DIR/regions-close-over-type-parameter-multiple.rs:20:5 + --> $DIR/regions-close-over-type-parameter-multiple.rs:23:5 | LL | Box::new(v) as Box<dyn SomeTrait + 'a> | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ note: but, the lifetime must be valid for the lifetime `'c` as defined here... - --> $DIR/regions-close-over-type-parameter-multiple.rs:18:26 + --> $DIR/regions-close-over-type-parameter-multiple.rs:21:26 | LL | fn make_object_bad<'a,'b,'c,A:SomeTrait+'a+'b>(v: A) -> Box<dyn SomeTrait + 'c> { | ^^ note: ...so that the types are compatible - --> $DIR/regions-close-over-type-parameter-multiple.rs:20:5 + --> $DIR/regions-close-over-type-parameter-multiple.rs:23:5 | LL | Box::new(v) as Box<dyn SomeTrait + 'a> | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/regions/regions-close-over-type-parameter-multiple.nll.stderr b/src/test/ui/regions/regions-close-over-type-parameter-multiple.nll.stderr index 25566742099..66459957ed4 100644 --- a/src/test/ui/regions/regions-close-over-type-parameter-multiple.nll.stderr +++ b/src/test/ui/regions/regions-close-over-type-parameter-multiple.nll.stderr @@ -1,5 +1,5 @@ error: lifetime may not live long enough - --> $DIR/regions-close-over-type-parameter-multiple.rs:20:5 + --> $DIR/regions-close-over-type-parameter-multiple.rs:23:5 | LL | fn make_object_bad<'a,'b,'c,A:SomeTrait+'a+'b>(v: A) -> Box<dyn SomeTrait + 'c> { | -- -- lifetime `'c` defined here diff --git a/src/test/ui/regions/regions-close-over-type-parameter-multiple.rs b/src/test/ui/regions/regions-close-over-type-parameter-multiple.rs index fc7696e7e03..3d5f4e12665 100644 --- a/src/test/ui/regions/regions-close-over-type-parameter-multiple.rs +++ b/src/test/ui/regions/regions-close-over-type-parameter-multiple.rs @@ -1,6 +1,9 @@ // Various tests where we over type parameters with multiple lifetime // bounds. +// revisions: base nll +// ignore-compare-mode-nll +//[nll] compile-flags: -Z borrowck=mir trait SomeTrait { fn get(&self) -> isize; } @@ -17,7 +20,9 @@ fn make_object_good2<'a,'b,A:SomeTrait+'a+'b>(v: A) -> Box<dyn SomeTrait + 'b> { fn make_object_bad<'a,'b,'c,A:SomeTrait+'a+'b>(v: A) -> Box<dyn SomeTrait + 'c> { // A outlives 'a AND 'b...but not 'c. - Box::new(v) as Box<dyn SomeTrait + 'a> //~ ERROR cannot infer an appropriate lifetime + Box::new(v) as Box<dyn SomeTrait + 'a> + //[base]~^ ERROR cannot infer an appropriate lifetime + //[nll]~^^ ERROR lifetime may not live long enough } fn main() { diff --git a/src/test/ui/regions/regions-close-param-into-object.stderr b/src/test/ui/regions/regions-close-param-into-object.base.stderr index 5c355bbb734..79a5d34dea8 100644 --- a/src/test/ui/regions/regions-close-param-into-object.stderr +++ b/src/test/ui/regions/regions-close-param-into-object.base.stderr @@ -1,38 +1,46 @@ error[E0310]: the parameter type `T` may not live long enough - --> $DIR/regions-close-param-into-object.rs:6:5 + --> $DIR/regions-close-param-into-object.rs:10:5 | -LL | fn p1<T>(v: T) -> Box<dyn X + 'static> - | - help: consider adding an explicit lifetime bound...: `T: 'static` -... LL | Box::new(v) | ^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds + | +help: consider adding an explicit lifetime bound... + | +LL | where T : X + 'static + | +++++++++ error[E0310]: the parameter type `T` may not live long enough - --> $DIR/regions-close-param-into-object.rs:12:5 + --> $DIR/regions-close-param-into-object.rs:16:5 | -LL | fn p2<T>(v: Box<T>) -> Box<dyn X + 'static> - | - help: consider adding an explicit lifetime bound...: `T: 'static` -... LL | Box::new(v) | ^^^^^^^^^^^ ...so that the type `Box<T>` will meet its required lifetime bounds + | +help: consider adding an explicit lifetime bound... + | +LL | fn p2<T: 'static>(v: Box<T>) -> Box<dyn X + 'static> + | +++++++++ error[E0309]: the parameter type `T` may not live long enough - --> $DIR/regions-close-param-into-object.rs:18:5 + --> $DIR/regions-close-param-into-object.rs:22:5 | -LL | fn p3<'a,T>(v: T) -> Box<dyn X + 'a> - | - help: consider adding an explicit lifetime bound...: `T: 'a` -... LL | Box::new(v) | ^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds + | +help: consider adding an explicit lifetime bound... + | +LL | where T : X + 'a + | ++++ error[E0309]: the parameter type `T` may not live long enough - --> $DIR/regions-close-param-into-object.rs:24:5 + --> $DIR/regions-close-param-into-object.rs:28:5 | -LL | fn p4<'a,T>(v: Box<T>) -> Box<dyn X + 'a> - | - help: consider adding an explicit lifetime bound...: `T: 'a` -... LL | Box::new(v) | ^^^^^^^^^^^ ...so that the type `Box<T>` will meet its required lifetime bounds + | +help: consider adding an explicit lifetime bound... + | +LL | fn p4<'a,T: 'a>(v: Box<T>) -> Box<dyn X + 'a> + | ++++ error: aborting due to 4 previous errors diff --git a/src/test/ui/regions/regions-close-param-into-object.nll.stderr b/src/test/ui/regions/regions-close-param-into-object.nll.stderr index 7bd7824f00a..6ee12d5b82c 100644 --- a/src/test/ui/regions/regions-close-param-into-object.nll.stderr +++ b/src/test/ui/regions/regions-close-param-into-object.nll.stderr @@ -1,34 +1,46 @@ error[E0310]: the parameter type `T` may not live long enough - --> $DIR/regions-close-param-into-object.rs:6:5 + --> $DIR/regions-close-param-into-object.rs:10:5 | LL | Box::new(v) - | ^^^^^^^^^^^ + | ^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds | - = help: consider adding an explicit lifetime bound `T: 'static`... +help: consider adding an explicit lifetime bound... + | +LL | where T : X + 'static + | +++++++++ error[E0310]: the parameter type `T` may not live long enough - --> $DIR/regions-close-param-into-object.rs:12:5 + --> $DIR/regions-close-param-into-object.rs:16:5 | LL | Box::new(v) - | ^^^^^^^^^^^ + | ^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds + | +help: consider adding an explicit lifetime bound... | - = help: consider adding an explicit lifetime bound `T: 'static`... +LL | fn p2<T: 'static>(v: Box<T>) -> Box<dyn X + 'static> + | +++++++++ error[E0309]: the parameter type `T` may not live long enough - --> $DIR/regions-close-param-into-object.rs:18:5 + --> $DIR/regions-close-param-into-object.rs:22:5 | LL | Box::new(v) - | ^^^^^^^^^^^ + | ^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds | - = help: consider adding an explicit lifetime bound `T: 'a`... +help: consider adding an explicit lifetime bound... + | +LL | where T : X + 'a + | ++++ error[E0309]: the parameter type `T` may not live long enough - --> $DIR/regions-close-param-into-object.rs:24:5 + --> $DIR/regions-close-param-into-object.rs:28:5 | LL | Box::new(v) - | ^^^^^^^^^^^ + | ^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds + | +help: consider adding an explicit lifetime bound... | - = help: consider adding an explicit lifetime bound `T: 'a`... +LL | fn p4<'a,T: 'a>(v: Box<T>) -> Box<dyn X + 'a> + | ++++ error: aborting due to 4 previous errors diff --git a/src/test/ui/regions/regions-close-param-into-object.rs b/src/test/ui/regions/regions-close-param-into-object.rs index 2760e5eed95..aab3ad202e6 100644 --- a/src/test/ui/regions/regions-close-param-into-object.rs +++ b/src/test/ui/regions/regions-close-param-into-object.rs @@ -1,3 +1,7 @@ +// revisions: base nll +// ignore-compare-mode-nll +//[nll] compile-flags: -Z borrowck=mir + trait X { fn foo(&self) {} } fn p1<T>(v: T) -> Box<dyn X + 'static> diff --git a/src/test/ui/regions/regions-creating-enums3.stderr b/src/test/ui/regions/regions-creating-enums3.base.stderr index 2fc1fc3f681..68a7b473695 100644 --- a/src/test/ui/regions/regions-creating-enums3.stderr +++ b/src/test/ui/regions/regions-creating-enums3.base.stderr @@ -1,5 +1,5 @@ error[E0623]: lifetime mismatch - --> $DIR/regions-creating-enums3.rs:7:5 + --> $DIR/regions-creating-enums3.rs:11:5 | LL | fn mk_add_bad1<'a,'b>(x: &'a Ast<'a>, y: &'b Ast<'b>) -> Ast<'a> { | ----------- ------- diff --git a/src/test/ui/regions/regions-creating-enums3.nll.stderr b/src/test/ui/regions/regions-creating-enums3.nll.stderr index 41d609b56d2..8334dc77687 100644 --- a/src/test/ui/regions/regions-creating-enums3.nll.stderr +++ b/src/test/ui/regions/regions-creating-enums3.nll.stderr @@ -1,5 +1,5 @@ error: lifetime may not live long enough - --> $DIR/regions-creating-enums3.rs:7:5 + --> $DIR/regions-creating-enums3.rs:11:5 | LL | fn mk_add_bad1<'a,'b>(x: &'a Ast<'a>, y: &'b Ast<'b>) -> Ast<'a> { | -- -- lifetime `'b` defined here diff --git a/src/test/ui/regions/regions-creating-enums3.rs b/src/test/ui/regions/regions-creating-enums3.rs index 3da0cb4cb81..dcea761d33f 100644 --- a/src/test/ui/regions/regions-creating-enums3.rs +++ b/src/test/ui/regions/regions-creating-enums3.rs @@ -1,10 +1,16 @@ +// revisions: base nll +// ignore-compare-mode-nll +//[nll] compile-flags: -Z borrowck=mir + enum Ast<'a> { Num(usize), Add(&'a Ast<'a>, &'a Ast<'a>) } fn mk_add_bad1<'a,'b>(x: &'a Ast<'a>, y: &'b Ast<'b>) -> Ast<'a> { - Ast::Add(x, y) //~ ERROR lifetime mismatch [E0623] + Ast::Add(x, y) + //[base]~^ ERROR lifetime mismatch [E0623] + //[nll]~^^ ERROR lifetime may not live long enough } fn main() { diff --git a/src/test/ui/regions/regions-creating-enums4.stderr b/src/test/ui/regions/regions-creating-enums4.base.stderr index 8b1b90f5b1a..445a4291f27 100644 --- a/src/test/ui/regions/regions-creating-enums4.stderr +++ b/src/test/ui/regions/regions-creating-enums4.base.stderr @@ -1,28 +1,28 @@ error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'a` due to conflicting requirements - --> $DIR/regions-creating-enums4.rs:7:5 + --> $DIR/regions-creating-enums4.rs:11:5 | LL | Ast::Add(x, y) | ^^^^^^^^ | note: first, the lifetime cannot outlive the lifetime `'a` as defined here... - --> $DIR/regions-creating-enums4.rs:6:16 + --> $DIR/regions-creating-enums4.rs:10:16 | LL | fn mk_add_bad2<'a,'b>(x: &'a Ast<'a>, y: &'a Ast<'a>, z: &Ast) -> Ast<'b> { | ^^ note: ...so that the expression is assignable - --> $DIR/regions-creating-enums4.rs:7:14 + --> $DIR/regions-creating-enums4.rs:11:14 | LL | Ast::Add(x, y) | ^ = note: expected `&Ast<'_>` found `&Ast<'a>` note: but, the lifetime must be valid for the lifetime `'b` as defined here... - --> $DIR/regions-creating-enums4.rs:6:19 + --> $DIR/regions-creating-enums4.rs:10:19 | LL | fn mk_add_bad2<'a,'b>(x: &'a Ast<'a>, y: &'a Ast<'a>, z: &Ast) -> Ast<'b> { | ^^ note: ...so that the types are compatible - --> $DIR/regions-creating-enums4.rs:7:5 + --> $DIR/regions-creating-enums4.rs:11:5 | LL | Ast::Add(x, y) | ^^^^^^^^^^^^^^ diff --git a/src/test/ui/regions/regions-creating-enums4.nll.stderr b/src/test/ui/regions/regions-creating-enums4.nll.stderr index 91cf57e099d..e215c63d39d 100644 --- a/src/test/ui/regions/regions-creating-enums4.nll.stderr +++ b/src/test/ui/regions/regions-creating-enums4.nll.stderr @@ -1,5 +1,5 @@ error: lifetime may not live long enough - --> $DIR/regions-creating-enums4.rs:7:5 + --> $DIR/regions-creating-enums4.rs:11:5 | LL | fn mk_add_bad2<'a,'b>(x: &'a Ast<'a>, y: &'a Ast<'a>, z: &Ast) -> Ast<'b> { | -- -- lifetime `'b` defined here diff --git a/src/test/ui/regions/regions-creating-enums4.rs b/src/test/ui/regions/regions-creating-enums4.rs index 11d3d831151..18bd592b1c3 100644 --- a/src/test/ui/regions/regions-creating-enums4.rs +++ b/src/test/ui/regions/regions-creating-enums4.rs @@ -1,10 +1,16 @@ +// revisions: base nll +// ignore-compare-mode-nll +//[nll] compile-flags: -Z borrowck=mir + enum Ast<'a> { Num(usize), Add(&'a Ast<'a>, &'a Ast<'a>) } fn mk_add_bad2<'a,'b>(x: &'a Ast<'a>, y: &'a Ast<'a>, z: &Ast) -> Ast<'b> { - Ast::Add(x, y) //~ ERROR cannot infer + Ast::Add(x, y) + //[base]~^ ERROR cannot infer + //[nll]~^^ ERROR lifetime may not live long enough } fn main() { diff --git a/src/test/ui/regions/regions-early-bound-error-method.stderr b/src/test/ui/regions/regions-early-bound-error-method.base.stderr index 99a5f0ce4cd..9e1f2b0e5bd 100644 --- a/src/test/ui/regions/regions-early-bound-error-method.stderr +++ b/src/test/ui/regions/regions-early-bound-error-method.base.stderr @@ -1,16 +1,16 @@ error[E0312]: lifetime of reference outlives lifetime of borrowed content... - --> $DIR/regions-early-bound-error-method.rs:20:9 + --> $DIR/regions-early-bound-error-method.rs:24:9 | LL | g2.get() | ^^^^^^^^ | note: ...the reference is valid for the lifetime `'a` as defined here... - --> $DIR/regions-early-bound-error-method.rs:18:6 + --> $DIR/regions-early-bound-error-method.rs:22:6 | LL | impl<'a> Box<'a> { | ^^ note: ...but the borrowed content is only valid for the lifetime `'b` as defined here - --> $DIR/regions-early-bound-error-method.rs:19:11 + --> $DIR/regions-early-bound-error-method.rs:23:11 | LL | fn or<'b,G:GetRef<'b>>(&self, g2: G) -> &'a isize { | ^^ diff --git a/src/test/ui/regions/regions-early-bound-error-method.nll.stderr b/src/test/ui/regions/regions-early-bound-error-method.nll.stderr index 7f10c051f29..98389ed0ca5 100644 --- a/src/test/ui/regions/regions-early-bound-error-method.nll.stderr +++ b/src/test/ui/regions/regions-early-bound-error-method.nll.stderr @@ -1,5 +1,5 @@ error: lifetime may not live long enough - --> $DIR/regions-early-bound-error-method.rs:20:9 + --> $DIR/regions-early-bound-error-method.rs:24:9 | LL | impl<'a> Box<'a> { | -- lifetime `'a` defined here diff --git a/src/test/ui/regions/regions-early-bound-error-method.rs b/src/test/ui/regions/regions-early-bound-error-method.rs index 32428143ef9..44ee19fa898 100644 --- a/src/test/ui/regions/regions-early-bound-error-method.rs +++ b/src/test/ui/regions/regions-early-bound-error-method.rs @@ -1,6 +1,10 @@ // Tests that you can use a fn lifetime parameter as part of // the value for a type parameter in a bound. +// revisions: base nll +// ignore-compare-mode-nll +//[nll] compile-flags: -Z borrowck=mir + trait GetRef<'a> { fn get(&self) -> &'a isize; } @@ -18,7 +22,8 @@ impl<'a> GetRef<'a> for Box<'a> { impl<'a> Box<'a> { fn or<'b,G:GetRef<'b>>(&self, g2: G) -> &'a isize { g2.get() - //~^ ERROR E0312 + //[base]~^ ERROR E0312 + //[nll]~^^ ERROR lifetime may not live long enough } } diff --git a/src/test/ui/regions/regions-early-bound-error.stderr b/src/test/ui/regions/regions-early-bound-error.base.stderr index df9e979eacf..e1b60536d29 100644 --- a/src/test/ui/regions/regions-early-bound-error.stderr +++ b/src/test/ui/regions/regions-early-bound-error.base.stderr @@ -1,16 +1,16 @@ error[E0312]: lifetime of reference outlives lifetime of borrowed content... - --> $DIR/regions-early-bound-error.rs:19:5 + --> $DIR/regions-early-bound-error.rs:23:5 | LL | g1.get() | ^^^^^^^^ | note: ...the reference is valid for the lifetime `'b` as defined here... - --> $DIR/regions-early-bound-error.rs:18:11 + --> $DIR/regions-early-bound-error.rs:22:11 | LL | fn get<'a,'b,G:GetRef<'a, isize>>(g1: G, b: &'b isize) -> &'b isize { | ^^ note: ...but the borrowed content is only valid for the lifetime `'a` as defined here - --> $DIR/regions-early-bound-error.rs:18:8 + --> $DIR/regions-early-bound-error.rs:22:8 | LL | fn get<'a,'b,G:GetRef<'a, isize>>(g1: G, b: &'b isize) -> &'b isize { | ^^ diff --git a/src/test/ui/regions/regions-early-bound-error.nll.stderr b/src/test/ui/regions/regions-early-bound-error.nll.stderr index eb4cd5ca72e..f57249e4e8f 100644 --- a/src/test/ui/regions/regions-early-bound-error.nll.stderr +++ b/src/test/ui/regions/regions-early-bound-error.nll.stderr @@ -1,5 +1,5 @@ error: lifetime may not live long enough - --> $DIR/regions-early-bound-error.rs:19:5 + --> $DIR/regions-early-bound-error.rs:23:5 | LL | fn get<'a,'b,G:GetRef<'a, isize>>(g1: G, b: &'b isize) -> &'b isize { | -- -- lifetime `'b` defined here diff --git a/src/test/ui/regions/regions-early-bound-error.rs b/src/test/ui/regions/regions-early-bound-error.rs index 78dad4f2649..372596cd5f4 100644 --- a/src/test/ui/regions/regions-early-bound-error.rs +++ b/src/test/ui/regions/regions-early-bound-error.rs @@ -1,6 +1,10 @@ // Tests that you can use a fn lifetime parameter as part of // the value for a type parameter in a bound. +// revisions: base nll +// ignore-compare-mode-nll +//[nll] compile-flags: -Z borrowck=mir + trait GetRef<'a, T> { fn get(&self) -> &'a T; } @@ -17,7 +21,8 @@ impl<'a,T:Clone> GetRef<'a,T> for Box<'a,T> { fn get<'a,'b,G:GetRef<'a, isize>>(g1: G, b: &'b isize) -> &'b isize { g1.get() - //~^ ERROR E0312 + //[base]~^ ERROR E0312 + //[nll]~^^ ERROR lifetime may not live long enough } fn main() { diff --git a/src/test/ui/regions/regions-fn-subtyping-return-static-fail.stderr b/src/test/ui/regions/regions-fn-subtyping-return-static-fail.base.stderr index c9ce936c7d4..2182d8f661f 100644 --- a/src/test/ui/regions/regions-fn-subtyping-return-static-fail.stderr +++ b/src/test/ui/regions/regions-fn-subtyping-return-static-fail.base.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/regions-fn-subtyping-return-static-fail.rs:48:12 + --> $DIR/regions-fn-subtyping-return-static-fail.rs:52:12 | LL | want_G(baz); | ^^^ one type is more general than the other diff --git a/src/test/ui/regions/regions-fn-subtyping-return-static-fail.nll.stderr b/src/test/ui/regions/regions-fn-subtyping-return-static-fail.nll.stderr index c2956cd8958..0bca2cfbefd 100644 --- a/src/test/ui/regions/regions-fn-subtyping-return-static-fail.nll.stderr +++ b/src/test/ui/regions/regions-fn-subtyping-return-static-fail.nll.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/regions-fn-subtyping-return-static-fail.rs:48:5 + --> $DIR/regions-fn-subtyping-return-static-fail.rs:52:5 | LL | want_G(baz); | ^^^^^^^^^^^ one type is more general than the other diff --git a/src/test/ui/regions/regions-fn-subtyping-return-static-fail.rs b/src/test/ui/regions/regions-fn-subtyping-return-static-fail.rs index 539221b5a04..05c6ac0cb1a 100644 --- a/src/test/ui/regions/regions-fn-subtyping-return-static-fail.rs +++ b/src/test/ui/regions/regions-fn-subtyping-return-static-fail.rs @@ -6,6 +6,10 @@ // This can safely be considered to be an instance of `F` because all // lifetimes are sublifetimes of 'static. +// revisions: base nll +// ignore-compare-mode-nll +//[nll] compile-flags: -Z borrowck=mir + #![allow(dead_code)] #![allow(unused_variables)] diff --git a/src/test/ui/regions/regions-free-region-ordering-callee.stderr b/src/test/ui/regions/regions-free-region-ordering-callee.base.stderr index 4648bf046bc..ae6d95dd469 100644 --- a/src/test/ui/regions/regions-free-region-ordering-callee.stderr +++ b/src/test/ui/regions/regions-free-region-ordering-callee.base.stderr @@ -1,5 +1,5 @@ error[E0623]: lifetime mismatch - --> $DIR/regions-free-region-ordering-callee.rs:13:5 + --> $DIR/regions-free-region-ordering-callee.rs:17:5 | LL | fn ordering2<'a, 'b>(x: &'a &'b usize, y: &'a usize) -> &'b usize { | ------------- --------- @@ -10,7 +10,7 @@ LL | &*y | ^^^ ...but data from `x` is returned here error[E0623]: lifetime mismatch - --> $DIR/regions-free-region-ordering-callee.rs:18:24 + --> $DIR/regions-free-region-ordering-callee.rs:24:24 | LL | fn ordering3<'a, 'b>(x: &'a usize, y: &'b usize) -> &'a &'b usize { | --------- ------------- diff --git a/src/test/ui/regions/regions-free-region-ordering-callee.nll.stderr b/src/test/ui/regions/regions-free-region-ordering-callee.nll.stderr index f61f068a486..7dfff2bb060 100644 --- a/src/test/ui/regions/regions-free-region-ordering-callee.nll.stderr +++ b/src/test/ui/regions/regions-free-region-ordering-callee.nll.stderr @@ -1,5 +1,5 @@ error: lifetime may not live long enough - --> $DIR/regions-free-region-ordering-callee.rs:13:5 + --> $DIR/regions-free-region-ordering-callee.rs:17:5 | LL | fn ordering2<'a, 'b>(x: &'a &'b usize, y: &'a usize) -> &'b usize { | -- -- lifetime `'b` defined here @@ -12,7 +12,7 @@ LL | &*y = help: consider adding the following bound: `'a: 'b` error: lifetime may not live long enough - --> $DIR/regions-free-region-ordering-callee.rs:18:12 + --> $DIR/regions-free-region-ordering-callee.rs:24:12 | LL | fn ordering3<'a, 'b>(x: &'a usize, y: &'b usize) -> &'a &'b usize { | -- -- lifetime `'b` defined here diff --git a/src/test/ui/regions/regions-free-region-ordering-callee.rs b/src/test/ui/regions/regions-free-region-ordering-callee.rs index ee9a977a74f..eca863f2e79 100644 --- a/src/test/ui/regions/regions-free-region-ordering-callee.rs +++ b/src/test/ui/regions/regions-free-region-ordering-callee.rs @@ -2,6 +2,10 @@ // that appear in their parameter list. See also // regions-free-region-ordering-caller.rs +// revisions: base nll +// ignore-compare-mode-nll +//[nll] compile-flags: -Z borrowck=mir + fn ordering1<'a, 'b>(x: &'a &'b usize) -> &'a usize { // It is safe to assume that 'a <= 'b due to the type of x let y: &'b usize = &**x; @@ -10,13 +14,16 @@ fn ordering1<'a, 'b>(x: &'a &'b usize) -> &'a usize { fn ordering2<'a, 'b>(x: &'a &'b usize, y: &'a usize) -> &'b usize { // However, it is not safe to assume that 'b <= 'a - &*y //~ ERROR lifetime mismatch [E0623] + &*y + //[base]~^ ERROR lifetime mismatch [E0623] + //[nll]~^^ ERROR lifetime may not live long enough } fn ordering3<'a, 'b>(x: &'a usize, y: &'b usize) -> &'a &'b usize { // Do not infer an ordering from the return value. let z: &'b usize = &*x; - //~^ ERROR lifetime mismatch [E0623] + //[base]~^ ERROR lifetime mismatch [E0623] + //[nll]~^^ ERROR lifetime may not live long enough panic!(); } diff --git a/src/test/ui/regions/regions-free-region-ordering-incorrect.stderr b/src/test/ui/regions/regions-free-region-ordering-incorrect.base.stderr index b0a8f4af397..eb4ffce89a3 100644 --- a/src/test/ui/regions/regions-free-region-ordering-incorrect.stderr +++ b/src/test/ui/regions/regions-free-region-ordering-incorrect.base.stderr @@ -1,26 +1,26 @@ error[E0495]: cannot infer an appropriate lifetime for borrow expression due to conflicting requirements - --> $DIR/regions-free-region-ordering-incorrect.rs:17:21 + --> $DIR/regions-free-region-ordering-incorrect.rs:21:21 | LL | None => &self.val | ^^^^^^^^^ | note: first, the lifetime cannot outlive the lifetime `'a` as defined here... - --> $DIR/regions-free-region-ordering-incorrect.rs:14:12 + --> $DIR/regions-free-region-ordering-incorrect.rs:18:12 | LL | fn get<'a>(&'a self) -> &'b T { | ^^ note: ...so that reference does not outlive borrowed content - --> $DIR/regions-free-region-ordering-incorrect.rs:17:21 + --> $DIR/regions-free-region-ordering-incorrect.rs:21:21 | LL | None => &self.val | ^^^^^^^^^ note: but, the lifetime must be valid for the lifetime `'b` as defined here... - --> $DIR/regions-free-region-ordering-incorrect.rs:13:6 + --> $DIR/regions-free-region-ordering-incorrect.rs:17:6 | LL | impl<'b, T> Node<'b, T> { | ^^ note: ...so that reference does not outlive borrowed content - --> $DIR/regions-free-region-ordering-incorrect.rs:15:9 + --> $DIR/regions-free-region-ordering-incorrect.rs:19:9 | LL | / match self.next { LL | | Some(ref next) => next.get(), diff --git a/src/test/ui/regions/regions-free-region-ordering-incorrect.nll.stderr b/src/test/ui/regions/regions-free-region-ordering-incorrect.nll.stderr index f7c75033c04..336cfd3e6c5 100644 --- a/src/test/ui/regions/regions-free-region-ordering-incorrect.nll.stderr +++ b/src/test/ui/regions/regions-free-region-ordering-incorrect.nll.stderr @@ -1,5 +1,5 @@ error: lifetime may not live long enough - --> $DIR/regions-free-region-ordering-incorrect.rs:15:9 + --> $DIR/regions-free-region-ordering-incorrect.rs:19:9 | LL | impl<'b, T> Node<'b, T> { | -- lifetime `'b` defined here diff --git a/src/test/ui/regions/regions-free-region-ordering-incorrect.rs b/src/test/ui/regions/regions-free-region-ordering-incorrect.rs index 65e3f52609e..43427d13ffa 100644 --- a/src/test/ui/regions/regions-free-region-ordering-incorrect.rs +++ b/src/test/ui/regions/regions-free-region-ordering-incorrect.rs @@ -5,6 +5,10 @@ // // This test began its life as a test for issue #4325. +// revisions: base nll +// ignore-compare-mode-nll +//[nll] compile-flags: -Z borrowck=mir + struct Node<'b, T: 'b> { val: T, next: Option<&'b Node<'b, T>> @@ -12,9 +16,9 @@ struct Node<'b, T: 'b> { impl<'b, T> Node<'b, T> { fn get<'a>(&'a self) -> &'b T { - match self.next { + match self.next { //[nll]~ ERROR lifetime may not live long enough Some(ref next) => next.get(), - None => &self.val //~ ERROR cannot infer + None => &self.val //[base]~ ERROR cannot infer } } } diff --git a/src/test/ui/regions/regions-free-region-outlives-static-outlives-free-region.rs b/src/test/ui/regions/regions-free-region-outlives-static-outlives-free-region.rs index f464cab7554..7c2e1aeeea6 100644 --- a/src/test/ui/regions/regions-free-region-outlives-static-outlives-free-region.rs +++ b/src/test/ui/regions/regions-free-region-outlives-static-outlives-free-region.rs @@ -9,7 +9,7 @@ // 'a : 'b fn test<'a,'b>(x: &'a i32) -> &'b i32 - where 'a: 'static + where 'a: 'static //~ WARN unnecessary lifetime parameter `'a` { x } diff --git a/src/test/ui/regions/regions-free-region-outlives-static-outlives-free-region.stderr b/src/test/ui/regions/regions-free-region-outlives-static-outlives-free-region.stderr new file mode 100644 index 00000000000..70ed418d5cb --- /dev/null +++ b/src/test/ui/regions/regions-free-region-outlives-static-outlives-free-region.stderr @@ -0,0 +1,10 @@ +warning: unnecessary lifetime parameter `'a` + --> $DIR/regions-free-region-outlives-static-outlives-free-region.rs:12:11 + | +LL | where 'a: 'static + | ^^ + | + = help: you can use the `'static` lifetime directly, in place of `'a` + +warning: 1 warning emitted + diff --git a/src/test/ui/regions/regions-implied-bounds-projection-gap-1.stderr b/src/test/ui/regions/regions-implied-bounds-projection-gap-1.base.stderr index ea59ea11a14..85ced4b5241 100644 --- a/src/test/ui/regions/regions-implied-bounds-projection-gap-1.stderr +++ b/src/test/ui/regions/regions-implied-bounds-projection-gap-1.base.stderr @@ -1,11 +1,13 @@ error[E0309]: the parameter type `T` may not live long enough - --> $DIR/regions-implied-bounds-projection-gap-1.rs:16:10 + --> $DIR/regions-implied-bounds-projection-gap-1.rs:20:10 | -LL | fn func<'x, T:Trait1<'x>>(t: &'x T::Foo) - | -- help: consider adding an explicit lifetime bound...: `T: 'x +` -LL | { LL | wf::<&'x T>(); | ^^^^^ ...so that the reference type `&'x T` does not outlive the data it points at + | +help: consider adding an explicit lifetime bound... + | +LL | fn func<'x, T:Trait1<'x> + 'x>(t: &'x T::Foo) + | ++++ error: aborting due to previous error diff --git a/src/test/ui/regions/regions-implied-bounds-projection-gap-1.nll.stderr b/src/test/ui/regions/regions-implied-bounds-projection-gap-1.nll.stderr index 0f0f86dfcdd..1a428eb25d7 100644 --- a/src/test/ui/regions/regions-implied-bounds-projection-gap-1.nll.stderr +++ b/src/test/ui/regions/regions-implied-bounds-projection-gap-1.nll.stderr @@ -1,10 +1,13 @@ error[E0309]: the parameter type `T` may not live long enough - --> $DIR/regions-implied-bounds-projection-gap-1.rs:16:5 + --> $DIR/regions-implied-bounds-projection-gap-1.rs:20:5 | LL | wf::<&'x T>(); - | ^^^^^^^^^^^ + | ^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds | - = help: consider adding an explicit lifetime bound `T: 'x`... +help: consider adding an explicit lifetime bound... + | +LL | fn func<'x, T:Trait1<'x> + 'x>(t: &'x T::Foo) + | ++++ error: aborting due to previous error diff --git a/src/test/ui/regions/regions-implied-bounds-projection-gap-1.rs b/src/test/ui/regions/regions-implied-bounds-projection-gap-1.rs index 38fc9c462da..f11fc207b91 100644 --- a/src/test/ui/regions/regions-implied-bounds-projection-gap-1.rs +++ b/src/test/ui/regions/regions-implied-bounds-projection-gap-1.rs @@ -3,6 +3,10 @@ // there might be other ways for the caller of `func` to show that // `T::Foo: 'x` holds (e.g., where-clause). +// revisions: base nll +// ignore-compare-mode-nll +//[nll] compile-flags: -Z borrowck=mir + trait Trait1<'x> { type Foo; } diff --git a/src/test/ui/regions/regions-infer-bound-from-trait-self.stderr b/src/test/ui/regions/regions-infer-bound-from-trait-self.base.stderr index 97a3947bc0a..faa638aa281 100644 --- a/src/test/ui/regions/regions-infer-bound-from-trait-self.stderr +++ b/src/test/ui/regions/regions-infer-bound-from-trait-self.base.stderr @@ -1,5 +1,5 @@ error[E0309]: the parameter type `Self` may not live long enough - --> $DIR/regions-infer-bound-from-trait-self.rs:46:9 + --> $DIR/regions-infer-bound-from-trait-self.rs:50:9 | LL | check_bound(x, self) | ^^^^^^^^^^^ @@ -7,7 +7,7 @@ LL | check_bound(x, self) = help: consider adding an explicit lifetime bound `Self: 'a`... = note: ...so that the type `Self` will meet its required lifetime bounds... note: ...that is required by this bound - --> $DIR/regions-infer-bound-from-trait-self.rs:12:21 + --> $DIR/regions-infer-bound-from-trait-self.rs:16:21 | LL | fn check_bound<'a,A:'a>(x: Inv<'a>, a: A) { } | ^^ diff --git a/src/test/ui/regions/regions-infer-bound-from-trait-self.nll.stderr b/src/test/ui/regions/regions-infer-bound-from-trait-self.nll.stderr index 0651e305cde..9c886c42c72 100644 --- a/src/test/ui/regions/regions-infer-bound-from-trait-self.nll.stderr +++ b/src/test/ui/regions/regions-infer-bound-from-trait-self.nll.stderr @@ -1,10 +1,11 @@ error[E0309]: the parameter type `Self` may not live long enough - --> $DIR/regions-infer-bound-from-trait-self.rs:46:9 + --> $DIR/regions-infer-bound-from-trait-self.rs:50:9 | LL | check_bound(x, self) | ^^^^^^^^^^^^^^^^^^^^ | = help: consider adding an explicit lifetime bound `Self: 'a`... + = note: ...so that the type `Self` will meet its required lifetime bounds error: aborting due to previous error diff --git a/src/test/ui/regions/regions-infer-bound-from-trait-self.rs b/src/test/ui/regions/regions-infer-bound-from-trait-self.rs index d15bfffe9d9..ef8be05b2d2 100644 --- a/src/test/ui/regions/regions-infer-bound-from-trait-self.rs +++ b/src/test/ui/regions/regions-infer-bound-from-trait-self.rs @@ -1,6 +1,10 @@ // Test that we can derive lifetime bounds on `Self` from trait // inheritance. +// revisions: base nll +// ignore-compare-mode-nll +//[nll] compile-flags: -Z borrowck=mir + trait Static : 'static { } trait Is<'a> : 'a { } diff --git a/src/test/ui/regions/regions-infer-bound-from-trait.stderr b/src/test/ui/regions/regions-infer-bound-from-trait.base.stderr index fd1090d2dbd..658740f3f87 100644 --- a/src/test/ui/regions/regions-infer-bound-from-trait.stderr +++ b/src/test/ui/regions/regions-infer-bound-from-trait.base.stderr @@ -1,30 +1,34 @@ error[E0309]: the parameter type `A` may not live long enough - --> $DIR/regions-infer-bound-from-trait.rs:33:5 + --> $DIR/regions-infer-bound-from-trait.rs:37:5 | -LL | fn bar1<'a,A>(x: Inv<'a>, a: A) { - | - help: consider adding an explicit lifetime bound...: `A: 'a` LL | check_bound(x, a) | ^^^^^^^^^^^ ...so that the type `A` will meet its required lifetime bounds... | note: ...that is required by this bound - --> $DIR/regions-infer-bound-from-trait.rs:12:21 + --> $DIR/regions-infer-bound-from-trait.rs:16:21 | LL | fn check_bound<'a,A:'a>(x: Inv<'a>, a: A) { } | ^^ +help: consider adding an explicit lifetime bound... + | +LL | fn bar1<'a,A: 'a>(x: Inv<'a>, a: A) { + | ++++ error[E0309]: the parameter type `A` may not live long enough - --> $DIR/regions-infer-bound-from-trait.rs:37:5 + --> $DIR/regions-infer-bound-from-trait.rs:41:5 | -LL | fn bar2<'a,'b,A:Is<'b>>(x: Inv<'a>, y: Inv<'b>, a: A) { - | -- help: consider adding an explicit lifetime bound...: `A: 'a +` LL | check_bound(x, a) | ^^^^^^^^^^^ ...so that the type `A` will meet its required lifetime bounds... | note: ...that is required by this bound - --> $DIR/regions-infer-bound-from-trait.rs:12:21 + --> $DIR/regions-infer-bound-from-trait.rs:16:21 | LL | fn check_bound<'a,A:'a>(x: Inv<'a>, a: A) { } | ^^ +help: consider adding an explicit lifetime bound... + | +LL | fn bar2<'a,'b,A:Is<'b> + 'a>(x: Inv<'a>, y: Inv<'b>, a: A) { + | ++++ error: aborting due to 2 previous errors diff --git a/src/test/ui/regions/regions-infer-bound-from-trait.nll.stderr b/src/test/ui/regions/regions-infer-bound-from-trait.nll.stderr index 1f7b34fc699..5cc2d20c2e0 100644 --- a/src/test/ui/regions/regions-infer-bound-from-trait.nll.stderr +++ b/src/test/ui/regions/regions-infer-bound-from-trait.nll.stderr @@ -1,18 +1,24 @@ error[E0309]: the parameter type `A` may not live long enough - --> $DIR/regions-infer-bound-from-trait.rs:33:5 + --> $DIR/regions-infer-bound-from-trait.rs:37:5 | LL | check_bound(x, a) - | ^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^ ...so that the type `A` will meet its required lifetime bounds + | +help: consider adding an explicit lifetime bound... | - = help: consider adding an explicit lifetime bound `A: 'a`... +LL | fn bar1<'a,A: 'a>(x: Inv<'a>, a: A) { + | ++++ error[E0309]: the parameter type `A` may not live long enough - --> $DIR/regions-infer-bound-from-trait.rs:37:5 + --> $DIR/regions-infer-bound-from-trait.rs:41:5 | LL | check_bound(x, a) - | ^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^ ...so that the type `A` will meet its required lifetime bounds + | +help: consider adding an explicit lifetime bound... | - = help: consider adding an explicit lifetime bound `A: 'a`... +LL | fn bar2<'a,'b,A:Is<'b> + 'a>(x: Inv<'a>, y: Inv<'b>, a: A) { + | ++++ error: aborting due to 2 previous errors diff --git a/src/test/ui/regions/regions-infer-bound-from-trait.rs b/src/test/ui/regions/regions-infer-bound-from-trait.rs index 610452182f8..96f9125313b 100644 --- a/src/test/ui/regions/regions-infer-bound-from-trait.rs +++ b/src/test/ui/regions/regions-infer-bound-from-trait.rs @@ -1,6 +1,10 @@ // Test that we can derive lifetime bounds on type parameters // from trait inheritance. +// revisions: base nll +// ignore-compare-mode-nll +//[nll] compile-flags: -Z borrowck=mir + trait Static : 'static { } trait Is<'a> : 'a { } diff --git a/src/test/ui/regions/regions-infer-contravariance-due-to-decl.stderr b/src/test/ui/regions/regions-infer-contravariance-due-to-decl.base.stderr index f3a0358b90f..fbe2c0da6e2 100644 --- a/src/test/ui/regions/regions-infer-contravariance-due-to-decl.stderr +++ b/src/test/ui/regions/regions-infer-contravariance-due-to-decl.base.stderr @@ -1,5 +1,5 @@ error[E0623]: lifetime mismatch - --> $DIR/regions-infer-contravariance-due-to-decl.rs:25:35 + --> $DIR/regions-infer-contravariance-due-to-decl.rs:29:35 | LL | fn use_<'short,'long>(c: Contravariant<'short>, | --------------------- these two types are declared with different lifetimes... diff --git a/src/test/ui/regions/regions-infer-contravariance-due-to-decl.nll.stderr b/src/test/ui/regions/regions-infer-contravariance-due-to-decl.nll.stderr index 94b80852d01..0b1bf5271a7 100644 --- a/src/test/ui/regions/regions-infer-contravariance-due-to-decl.nll.stderr +++ b/src/test/ui/regions/regions-infer-contravariance-due-to-decl.nll.stderr @@ -1,5 +1,5 @@ error: lifetime may not live long enough - --> $DIR/regions-infer-contravariance-due-to-decl.rs:25:12 + --> $DIR/regions-infer-contravariance-due-to-decl.rs:29:12 | LL | fn use_<'short,'long>(c: Contravariant<'short>, | ------ ----- lifetime `'long` defined here diff --git a/src/test/ui/regions/regions-infer-contravariance-due-to-decl.rs b/src/test/ui/regions/regions-infer-contravariance-due-to-decl.rs index 84161388a6e..233f72fd296 100644 --- a/src/test/ui/regions/regions-infer-contravariance-due-to-decl.rs +++ b/src/test/ui/regions/regions-infer-contravariance-due-to-decl.rs @@ -4,6 +4,10 @@ // Note: see variance-regions-*.rs for the tests that check that the // variance inference works in the first place. +// revisions: base nll +// ignore-compare-mode-nll +//[nll] compile-flags: -Z borrowck=mir + use std::marker; // This is contravariant with respect to 'a, meaning that @@ -22,7 +26,9 @@ fn use_<'short,'long>(c: Contravariant<'short>, // 'short <= 'long, this would be true if the Contravariant type were // covariant with respect to its parameter 'a. - let _: Contravariant<'long> = c; //~ ERROR E0623 + let _: Contravariant<'long> = c; + //[base]~^ ERROR E0623 + //[nll]~^^ ERROR lifetime may not live long enough } fn main() {} diff --git a/src/test/ui/regions/regions-infer-covariance-due-to-decl.stderr b/src/test/ui/regions/regions-infer-covariance-due-to-decl.base.stderr index c3e2075fbc3..bb22e15af69 100644 --- a/src/test/ui/regions/regions-infer-covariance-due-to-decl.stderr +++ b/src/test/ui/regions/regions-infer-covariance-due-to-decl.base.stderr @@ -1,5 +1,5 @@ error[E0623]: lifetime mismatch - --> $DIR/regions-infer-covariance-due-to-decl.rs:22:32 + --> $DIR/regions-infer-covariance-due-to-decl.rs:26:32 | LL | fn use_<'short,'long>(c: Covariant<'long>, | ---------------- diff --git a/src/test/ui/regions/regions-infer-covariance-due-to-decl.nll.stderr b/src/test/ui/regions/regions-infer-covariance-due-to-decl.nll.stderr index f44a0fad59b..4d72b8471dc 100644 --- a/src/test/ui/regions/regions-infer-covariance-due-to-decl.nll.stderr +++ b/src/test/ui/regions/regions-infer-covariance-due-to-decl.nll.stderr @@ -1,5 +1,5 @@ error: lifetime may not live long enough - --> $DIR/regions-infer-covariance-due-to-decl.rs:22:12 + --> $DIR/regions-infer-covariance-due-to-decl.rs:26:12 | LL | fn use_<'short,'long>(c: Covariant<'long>, | ------ ----- lifetime `'long` defined here diff --git a/src/test/ui/regions/regions-infer-covariance-due-to-decl.rs b/src/test/ui/regions/regions-infer-covariance-due-to-decl.rs index b5079206578..c4225e76967 100644 --- a/src/test/ui/regions/regions-infer-covariance-due-to-decl.rs +++ b/src/test/ui/regions/regions-infer-covariance-due-to-decl.rs @@ -4,6 +4,10 @@ // Note: see variance-regions-*.rs for the tests that check that the // variance inference works in the first place. +// revisions: base nll +// ignore-compare-mode-nll +//[nll] compile-flags: -Z borrowck=mir + use std::marker; struct Covariant<'a> { @@ -19,7 +23,9 @@ fn use_<'short,'long>(c: Covariant<'long>, // 'short <= 'long, this would be true if the Covariant type were // contravariant with respect to its parameter 'a. - let _: Covariant<'short> = c; //~ ERROR E0623 + let _: Covariant<'short> = c; + //[base]~^ ERROR E0623 + //[nll]~^^ ERROR lifetime may not live long enough } fn main() {} diff --git a/src/test/ui/regions/regions-infer-invariance-due-to-decl.stderr b/src/test/ui/regions/regions-infer-invariance-due-to-decl.base.stderr index afd522aa003..dc7d0005ca2 100644 --- a/src/test/ui/regions/regions-infer-invariance-due-to-decl.stderr +++ b/src/test/ui/regions/regions-infer-invariance-due-to-decl.base.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/regions-infer-invariance-due-to-decl.rs:12:5 + --> $DIR/regions-infer-invariance-due-to-decl.rs:16:5 | LL | b_isize | ^^^^^^^ lifetime mismatch @@ -7,7 +7,7 @@ LL | b_isize = note: expected struct `Invariant<'static>` found struct `Invariant<'r>` note: the lifetime `'r` as defined here... - --> $DIR/regions-infer-invariance-due-to-decl.rs:11:23 + --> $DIR/regions-infer-invariance-due-to-decl.rs:15:23 | LL | fn to_longer_lifetime<'r>(b_isize: Invariant<'r>) -> Invariant<'static> { | ^^ diff --git a/src/test/ui/regions/regions-infer-invariance-due-to-decl.nll.stderr b/src/test/ui/regions/regions-infer-invariance-due-to-decl.nll.stderr index c8c7808e06c..d7b7f9883a7 100644 --- a/src/test/ui/regions/regions-infer-invariance-due-to-decl.nll.stderr +++ b/src/test/ui/regions/regions-infer-invariance-due-to-decl.nll.stderr @@ -1,5 +1,5 @@ error: lifetime may not live long enough - --> $DIR/regions-infer-invariance-due-to-decl.rs:12:5 + --> $DIR/regions-infer-invariance-due-to-decl.rs:16:5 | LL | fn to_longer_lifetime<'r>(b_isize: Invariant<'r>) -> Invariant<'static> { | -- lifetime `'r` defined here diff --git a/src/test/ui/regions/regions-infer-invariance-due-to-decl.rs b/src/test/ui/regions/regions-infer-invariance-due-to-decl.rs index e0fa904e8fe..6433773b2d1 100644 --- a/src/test/ui/regions/regions-infer-invariance-due-to-decl.rs +++ b/src/test/ui/regions/regions-infer-invariance-due-to-decl.rs @@ -1,3 +1,7 @@ +// revisions: base nll +// ignore-compare-mode-nll +//[nll] compile-flags: -Z borrowck=mir + use std::marker; struct Invariant<'a> { @@ -9,7 +13,9 @@ fn to_same_lifetime<'r>(b_isize: Invariant<'r>) { } fn to_longer_lifetime<'r>(b_isize: Invariant<'r>) -> Invariant<'static> { - b_isize //~ ERROR mismatched types + b_isize + //[base]~^ ERROR mismatched types + //[nll]~^^ ERROR lifetime may not live long enough } fn main() { diff --git a/src/test/ui/regions/regions-infer-invariance-due-to-mutability-3.stderr b/src/test/ui/regions/regions-infer-invariance-due-to-mutability-3.base.stderr index bb594f3676e..b2530d7b6cd 100644 --- a/src/test/ui/regions/regions-infer-invariance-due-to-mutability-3.stderr +++ b/src/test/ui/regions/regions-infer-invariance-due-to-mutability-3.base.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/regions-infer-invariance-due-to-mutability-3.rs:10:5 + --> $DIR/regions-infer-invariance-due-to-mutability-3.rs:14:5 | LL | b_isize | ^^^^^^^ lifetime mismatch @@ -7,7 +7,7 @@ LL | b_isize = note: expected struct `Invariant<'static>` found struct `Invariant<'r>` note: the lifetime `'r` as defined here... - --> $DIR/regions-infer-invariance-due-to-mutability-3.rs:9:23 + --> $DIR/regions-infer-invariance-due-to-mutability-3.rs:13:23 | LL | fn to_longer_lifetime<'r>(b_isize: Invariant<'r>) -> Invariant<'static> { | ^^ diff --git a/src/test/ui/regions/regions-infer-invariance-due-to-mutability-3.nll.stderr b/src/test/ui/regions/regions-infer-invariance-due-to-mutability-3.nll.stderr index 1165011c1f4..37fa5e3bf44 100644 --- a/src/test/ui/regions/regions-infer-invariance-due-to-mutability-3.nll.stderr +++ b/src/test/ui/regions/regions-infer-invariance-due-to-mutability-3.nll.stderr @@ -1,5 +1,5 @@ error: lifetime may not live long enough - --> $DIR/regions-infer-invariance-due-to-mutability-3.rs:10:5 + --> $DIR/regions-infer-invariance-due-to-mutability-3.rs:14:5 | LL | fn to_longer_lifetime<'r>(b_isize: Invariant<'r>) -> Invariant<'static> { | -- lifetime `'r` defined here diff --git a/src/test/ui/regions/regions-infer-invariance-due-to-mutability-3.rs b/src/test/ui/regions/regions-infer-invariance-due-to-mutability-3.rs index 5843598ab48..4690f9d8b08 100644 --- a/src/test/ui/regions/regions-infer-invariance-due-to-mutability-3.rs +++ b/src/test/ui/regions/regions-infer-invariance-due-to-mutability-3.rs @@ -1,3 +1,7 @@ +// revisions: base nll +// ignore-compare-mode-nll +//[nll] compile-flags: -Z borrowck=mir + struct Invariant<'a> { f: Box<dyn FnOnce(&mut &'a isize) + 'static>, } @@ -7,7 +11,9 @@ fn to_same_lifetime<'r>(b_isize: Invariant<'r>) { } fn to_longer_lifetime<'r>(b_isize: Invariant<'r>) -> Invariant<'static> { - b_isize //~ ERROR mismatched types + b_isize + //[base]~^ ERROR mismatched types + //[nll]~^^ ERROR lifetime may not live long enough } fn main() { diff --git a/src/test/ui/regions/regions-infer-invariance-due-to-mutability-4.stderr b/src/test/ui/regions/regions-infer-invariance-due-to-mutability-4.base.stderr index 04d11b5b7c7..12774ca92e2 100644 --- a/src/test/ui/regions/regions-infer-invariance-due-to-mutability-4.stderr +++ b/src/test/ui/regions/regions-infer-invariance-due-to-mutability-4.base.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/regions-infer-invariance-due-to-mutability-4.rs:10:5 + --> $DIR/regions-infer-invariance-due-to-mutability-4.rs:14:5 | LL | b_isize | ^^^^^^^ lifetime mismatch @@ -7,7 +7,7 @@ LL | b_isize = note: expected struct `Invariant<'static>` found struct `Invariant<'r>` note: the lifetime `'r` as defined here... - --> $DIR/regions-infer-invariance-due-to-mutability-4.rs:9:23 + --> $DIR/regions-infer-invariance-due-to-mutability-4.rs:13:23 | LL | fn to_longer_lifetime<'r>(b_isize: Invariant<'r>) -> Invariant<'static> { | ^^ diff --git a/src/test/ui/regions/regions-infer-invariance-due-to-mutability-4.nll.stderr b/src/test/ui/regions/regions-infer-invariance-due-to-mutability-4.nll.stderr index f3973a93bad..1b3ef7bc028 100644 --- a/src/test/ui/regions/regions-infer-invariance-due-to-mutability-4.nll.stderr +++ b/src/test/ui/regions/regions-infer-invariance-due-to-mutability-4.nll.stderr @@ -1,5 +1,5 @@ error: lifetime may not live long enough - --> $DIR/regions-infer-invariance-due-to-mutability-4.rs:10:5 + --> $DIR/regions-infer-invariance-due-to-mutability-4.rs:14:5 | LL | fn to_longer_lifetime<'r>(b_isize: Invariant<'r>) -> Invariant<'static> { | -- lifetime `'r` defined here diff --git a/src/test/ui/regions/regions-infer-invariance-due-to-mutability-4.rs b/src/test/ui/regions/regions-infer-invariance-due-to-mutability-4.rs index f0af18cf618..8e257c4fd0e 100644 --- a/src/test/ui/regions/regions-infer-invariance-due-to-mutability-4.rs +++ b/src/test/ui/regions/regions-infer-invariance-due-to-mutability-4.rs @@ -1,3 +1,7 @@ +// revisions: base nll +// ignore-compare-mode-nll +//[nll] compile-flags: -Z borrowck=mir + struct Invariant<'a> { f: Box<dyn FnOnce() -> *mut &'a isize + 'static>, } @@ -7,7 +11,9 @@ fn to_same_lifetime<'r>(b_isize: Invariant<'r>) { } fn to_longer_lifetime<'r>(b_isize: Invariant<'r>) -> Invariant<'static> { - b_isize //~ ERROR mismatched types + b_isize + //[base]~^ ERROR mismatched types + //[nll]~^^ ERROR lifetime may not live long enough } fn main() { diff --git a/src/test/ui/regions/regions-infer-not-param.stderr b/src/test/ui/regions/regions-infer-not-param.base.stderr index a23bdeb834f..f43274163d0 100644 --- a/src/test/ui/regions/regions-infer-not-param.stderr +++ b/src/test/ui/regions/regions-infer-not-param.base.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/regions-infer-not-param.rs:15:54 + --> $DIR/regions-infer-not-param.rs:19:54 | LL | fn take_direct<'a,'b>(p: Direct<'a>) -> Direct<'b> { p } | ^ lifetime mismatch @@ -7,18 +7,18 @@ LL | fn take_direct<'a,'b>(p: Direct<'a>) -> Direct<'b> { p } = note: expected struct `Direct<'b>` found struct `Direct<'a>` note: the lifetime `'a` as defined here... - --> $DIR/regions-infer-not-param.rs:15:16 + --> $DIR/regions-infer-not-param.rs:19:16 | LL | fn take_direct<'a,'b>(p: Direct<'a>) -> Direct<'b> { p } | ^^ note: ...does not necessarily outlive the lifetime `'b` as defined here - --> $DIR/regions-infer-not-param.rs:15:19 + --> $DIR/regions-infer-not-param.rs:19:19 | LL | fn take_direct<'a,'b>(p: Direct<'a>) -> Direct<'b> { p } | ^^ error[E0308]: mismatched types - --> $DIR/regions-infer-not-param.rs:19:63 + --> $DIR/regions-infer-not-param.rs:25:63 | LL | fn take_indirect2<'a,'b>(p: Indirect2<'a>) -> Indirect2<'b> { p } | ^ lifetime mismatch @@ -26,18 +26,18 @@ LL | fn take_indirect2<'a,'b>(p: Indirect2<'a>) -> Indirect2<'b> { p } = note: expected struct `Indirect2<'b>` found struct `Indirect2<'a>` note: the lifetime `'a` as defined here... - --> $DIR/regions-infer-not-param.rs:19:19 + --> $DIR/regions-infer-not-param.rs:25:19 | LL | fn take_indirect2<'a,'b>(p: Indirect2<'a>) -> Indirect2<'b> { p } | ^^ note: ...does not necessarily outlive the lifetime `'b` as defined here - --> $DIR/regions-infer-not-param.rs:19:22 + --> $DIR/regions-infer-not-param.rs:25:22 | LL | fn take_indirect2<'a,'b>(p: Indirect2<'a>) -> Indirect2<'b> { p } | ^^ error[E0308]: mismatched types - --> $DIR/regions-infer-not-param.rs:19:63 + --> $DIR/regions-infer-not-param.rs:25:63 | LL | fn take_indirect2<'a,'b>(p: Indirect2<'a>) -> Indirect2<'b> { p } | ^ lifetime mismatch @@ -45,12 +45,12 @@ LL | fn take_indirect2<'a,'b>(p: Indirect2<'a>) -> Indirect2<'b> { p } = note: expected struct `Indirect2<'b>` found struct `Indirect2<'a>` note: the lifetime `'b` as defined here... - --> $DIR/regions-infer-not-param.rs:19:22 + --> $DIR/regions-infer-not-param.rs:25:22 | LL | fn take_indirect2<'a,'b>(p: Indirect2<'a>) -> Indirect2<'b> { p } | ^^ note: ...does not necessarily outlive the lifetime `'a` as defined here - --> $DIR/regions-infer-not-param.rs:19:19 + --> $DIR/regions-infer-not-param.rs:25:19 | LL | fn take_indirect2<'a,'b>(p: Indirect2<'a>) -> Indirect2<'b> { p } | ^^ diff --git a/src/test/ui/regions/regions-infer-not-param.nll.stderr b/src/test/ui/regions/regions-infer-not-param.nll.stderr index f4875e49c3d..95e6b03c350 100644 --- a/src/test/ui/regions/regions-infer-not-param.nll.stderr +++ b/src/test/ui/regions/regions-infer-not-param.nll.stderr @@ -1,5 +1,5 @@ error: lifetime may not live long enough - --> $DIR/regions-infer-not-param.rs:15:54 + --> $DIR/regions-infer-not-param.rs:19:54 | LL | fn take_direct<'a,'b>(p: Direct<'a>) -> Direct<'b> { p } | -- -- lifetime `'b` defined here ^ function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a` @@ -9,7 +9,7 @@ LL | fn take_direct<'a,'b>(p: Direct<'a>) -> Direct<'b> { p } = help: consider adding the following bound: `'a: 'b` error: lifetime may not live long enough - --> $DIR/regions-infer-not-param.rs:19:63 + --> $DIR/regions-infer-not-param.rs:25:63 | LL | fn take_indirect2<'a,'b>(p: Indirect2<'a>) -> Indirect2<'b> { p } | -- -- lifetime `'b` defined here ^ function was supposed to return data with lifetime `'a` but it is returning data with lifetime `'b` @@ -22,7 +22,7 @@ LL | fn take_indirect2<'a,'b>(p: Indirect2<'a>) -> Indirect2<'b> { p } = help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance error: lifetime may not live long enough - --> $DIR/regions-infer-not-param.rs:19:63 + --> $DIR/regions-infer-not-param.rs:25:63 | LL | fn take_indirect2<'a,'b>(p: Indirect2<'a>) -> Indirect2<'b> { p } | -- -- lifetime `'b` defined here ^ function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a` diff --git a/src/test/ui/regions/regions-infer-not-param.rs b/src/test/ui/regions/regions-infer-not-param.rs index 7643be64d5b..0b8af5bc152 100644 --- a/src/test/ui/regions/regions-infer-not-param.rs +++ b/src/test/ui/regions/regions-infer-not-param.rs @@ -1,3 +1,7 @@ +// revisions: base nll +// ignore-compare-mode-nll +//[nll] compile-flags: -Z borrowck=mir + struct Direct<'a> { f: &'a isize } @@ -12,15 +16,20 @@ struct Indirect2<'a> { g: Box<dyn FnOnce(Direct<'a>) + 'static> } -fn take_direct<'a,'b>(p: Direct<'a>) -> Direct<'b> { p } //~ ERROR mismatched types +fn take_direct<'a,'b>(p: Direct<'a>) -> Direct<'b> { p } +//[base]~^ ERROR mismatched types +//[nll]~^^ ERROR lifetime may not live long enough fn take_indirect1(p: Indirect1) -> Indirect1 { p } -fn take_indirect2<'a,'b>(p: Indirect2<'a>) -> Indirect2<'b> { p } //~ ERROR mismatched types -//~| expected struct `Indirect2<'b>` -//~| found struct `Indirect2<'a>` -//~| ERROR mismatched types -//~| expected struct `Indirect2<'b>` -//~| found struct `Indirect2<'a>` +fn take_indirect2<'a,'b>(p: Indirect2<'a>) -> Indirect2<'b> { p } +//[base]~^ ERROR mismatched types +//[base]~| expected struct `Indirect2<'b>` +//[base]~| found struct `Indirect2<'a>` +//[base]~| ERROR mismatched types +//[base]~| expected struct `Indirect2<'b>` +//[base]~| found struct `Indirect2<'a>` +//[nll]~^^^^^^^ ERROR lifetime may not live long enough +//[nll]~| ERROR lifetime may not live long enough fn main() {} diff --git a/src/test/ui/regions/regions-infer-paramd-indirect.stderr b/src/test/ui/regions/regions-infer-paramd-indirect.base.stderr index d2b369fb07b..1d4471f910d 100644 --- a/src/test/ui/regions/regions-infer-paramd-indirect.stderr +++ b/src/test/ui/regions/regions-infer-paramd-indirect.base.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/regions-infer-paramd-indirect.rs:22:18 + --> $DIR/regions-infer-paramd-indirect.rs:26:18 | LL | self.f = b; | ^ lifetime mismatch @@ -7,12 +7,12 @@ LL | self.f = b; = note: expected struct `Box<Box<&'a isize>>` found struct `Box<Box<&isize>>` note: the anonymous lifetime defined here... - --> $DIR/regions-infer-paramd-indirect.rs:21:36 + --> $DIR/regions-infer-paramd-indirect.rs:25:36 | LL | fn set_f_bad(&mut self, b: Box<B>) { | ^ note: ...does not necessarily outlive the lifetime `'a` as defined here - --> $DIR/regions-infer-paramd-indirect.rs:16:6 + --> $DIR/regions-infer-paramd-indirect.rs:20:6 | LL | impl<'a> SetF<'a> for C<'a> { | ^^ diff --git a/src/test/ui/regions/regions-infer-paramd-indirect.nll.stderr b/src/test/ui/regions/regions-infer-paramd-indirect.nll.stderr index afabdc1de1c..96377cbdab4 100644 --- a/src/test/ui/regions/regions-infer-paramd-indirect.nll.stderr +++ b/src/test/ui/regions/regions-infer-paramd-indirect.nll.stderr @@ -1,5 +1,5 @@ error: lifetime may not live long enough - --> $DIR/regions-infer-paramd-indirect.rs:22:9 + --> $DIR/regions-infer-paramd-indirect.rs:26:9 | LL | impl<'a> SetF<'a> for C<'a> { | -- lifetime `'a` defined here diff --git a/src/test/ui/regions/regions-infer-paramd-indirect.rs b/src/test/ui/regions/regions-infer-paramd-indirect.rs index 3b18bbf1df3..060306f611e 100644 --- a/src/test/ui/regions/regions-infer-paramd-indirect.rs +++ b/src/test/ui/regions/regions-infer-paramd-indirect.rs @@ -1,6 +1,10 @@ // Check that we correctly infer that b and c must be region // parameterized because they reference a which requires a region. +// revisions: base nll +// ignore-compare-mode-nll +//[nll] compile-flags: -Z borrowck=mir + type A<'a> = &'a isize; type B<'a> = Box<A<'a>>; @@ -20,10 +24,11 @@ impl<'a> SetF<'a> for C<'a> { fn set_f_bad(&mut self, b: Box<B>) { self.f = b; - //~^ ERROR mismatched types - //~| expected struct `Box<Box<&'a isize>>` - //~| found struct `Box<Box<&isize>>` - //~| lifetime mismatch + //[base]~^ ERROR mismatched types + //[base]~| expected struct `Box<Box<&'a isize>>` + //[base]~| found struct `Box<Box<&isize>>` + //[base]~| lifetime mismatch + //[nll]~^^^^^ ERROR lifetime may not live long enough } } diff --git a/src/test/ui/regions/regions-lifetime-bounds-on-fns.stderr b/src/test/ui/regions/regions-lifetime-bounds-on-fns.base.stderr index 2b2dd0dbbf2..e57b06aac39 100644 --- a/src/test/ui/regions/regions-lifetime-bounds-on-fns.stderr +++ b/src/test/ui/regions/regions-lifetime-bounds-on-fns.base.stderr @@ -1,5 +1,5 @@ error[E0623]: lifetime mismatch - --> $DIR/regions-lifetime-bounds-on-fns.rs:8:10 + --> $DIR/regions-lifetime-bounds-on-fns.rs:12:10 | LL | fn b<'a, 'b>(x: &mut &'a isize, y: &mut &'b isize) { | --------- --------- these two types are declared with different lifetimes... @@ -8,7 +8,7 @@ LL | *x = *y; | ^^ ...but data from `y` flows into `x` here error[E0623]: lifetime mismatch - --> $DIR/regions-lifetime-bounds-on-fns.rs:14:7 + --> $DIR/regions-lifetime-bounds-on-fns.rs:20:7 | LL | fn c<'a,'b>(x: &mut &'a isize, y: &mut &'b isize) { | --------- --------- these two types are declared with different lifetimes... @@ -17,7 +17,7 @@ LL | a(x, y); | ^ ...but data from `y` flows into `x` here error[E0308]: mismatched types - --> $DIR/regions-lifetime-bounds-on-fns.rs:20:43 + --> $DIR/regions-lifetime-bounds-on-fns.rs:28:43 | LL | let _: fn(&mut &isize, &mut &isize) = a; | ^ one type is more general than the other diff --git a/src/test/ui/regions/regions-lifetime-bounds-on-fns.nll.stderr b/src/test/ui/regions/regions-lifetime-bounds-on-fns.nll.stderr index ee3dcef1cb5..7fe8b4bf57f 100644 --- a/src/test/ui/regions/regions-lifetime-bounds-on-fns.nll.stderr +++ b/src/test/ui/regions/regions-lifetime-bounds-on-fns.nll.stderr @@ -1,5 +1,5 @@ error: lifetime may not live long enough - --> $DIR/regions-lifetime-bounds-on-fns.rs:8:5 + --> $DIR/regions-lifetime-bounds-on-fns.rs:12:5 | LL | fn b<'a, 'b>(x: &mut &'a isize, y: &mut &'b isize) { | -- -- lifetime `'b` defined here @@ -12,7 +12,7 @@ LL | *x = *y; = help: consider adding the following bound: `'b: 'a` error: lifetime may not live long enough - --> $DIR/regions-lifetime-bounds-on-fns.rs:14:5 + --> $DIR/regions-lifetime-bounds-on-fns.rs:20:5 | LL | fn c<'a,'b>(x: &mut &'a isize, y: &mut &'b isize) { | -- -- lifetime `'b` defined here @@ -28,7 +28,7 @@ LL | a(x, y); = help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance error[E0308]: mismatched types - --> $DIR/regions-lifetime-bounds-on-fns.rs:20:12 + --> $DIR/regions-lifetime-bounds-on-fns.rs:28:12 | LL | let _: fn(&mut &isize, &mut &isize) = a; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other @@ -37,7 +37,7 @@ LL | let _: fn(&mut &isize, &mut &isize) = a; found fn pointer `for<'r, 's> fn(&'r mut &isize, &'s mut &isize)` error[E0308]: mismatched types - --> $DIR/regions-lifetime-bounds-on-fns.rs:20:12 + --> $DIR/regions-lifetime-bounds-on-fns.rs:28:12 | LL | let _: fn(&mut &isize, &mut &isize) = a; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other diff --git a/src/test/ui/regions/regions-lifetime-bounds-on-fns.rs b/src/test/ui/regions/regions-lifetime-bounds-on-fns.rs index 7d7f62e1979..97c08d8ab0e 100644 --- a/src/test/ui/regions/regions-lifetime-bounds-on-fns.rs +++ b/src/test/ui/regions/regions-lifetime-bounds-on-fns.rs @@ -1,3 +1,7 @@ +// revisions: base nll +// ignore-compare-mode-nll +//[nll] compile-flags: -Z borrowck=mir + fn a<'a, 'b:'a>(x: &mut &'a isize, y: &mut &'b isize) { // Note: this is legal because of the `'b:'a` declaration. *x = *y; @@ -5,19 +9,25 @@ fn a<'a, 'b:'a>(x: &mut &'a isize, y: &mut &'b isize) { fn b<'a, 'b>(x: &mut &'a isize, y: &mut &'b isize) { // Illegal now because there is no `'b:'a` declaration. - *x = *y; //~ ERROR E0623 + *x = *y; + //[base]~^ ERROR lifetime mismatch [E0623] + //[nll]~^^ ERROR lifetime may not live long enough } fn c<'a,'b>(x: &mut &'a isize, y: &mut &'b isize) { // Here we try to call `foo` but do not know that `'a` and `'b` are // related as required. - a(x, y); //~ ERROR lifetime mismatch [E0623] + a(x, y); + //[base]~^ ERROR lifetime mismatch [E0623] + //[nll]~^^ ERROR lifetime may not live long enough } fn d() { // 'a and 'b are early bound in the function `a` because they appear // inconstraints: - let _: fn(&mut &isize, &mut &isize) = a; //~ ERROR E0308 + let _: fn(&mut &isize, &mut &isize) = a; + //~^ ERROR mismatched types [E0308] + //[nll]~^^ ERROR mismatched types [E0308] } fn e() { diff --git a/src/test/ui/regions/regions-nested-fns.stderr b/src/test/ui/regions/regions-nested-fns.base.stderr index 11affcaaa79..37ce569e761 100644 --- a/src/test/ui/regions/regions-nested-fns.stderr +++ b/src/test/ui/regions/regions-nested-fns.base.stderr @@ -1,40 +1,46 @@ error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements - --> $DIR/regions-nested-fns.rs:5:18 + --> $DIR/regions-nested-fns.rs:9:18 | LL | let mut ay = &y; | ^^ | note: first, the lifetime cannot outlive the anonymous lifetime #1 defined here... - --> $DIR/regions-nested-fns.rs:7:58 + --> $DIR/regions-nested-fns.rs:13:58 | LL | ignore::<Box<dyn for<'z> FnMut(&'z isize)>>(Box::new(|z| { | __________________________________________________________^ LL | | ay = x; LL | | ay = &y; +LL | | LL | | ay = z; +LL | | LL | | })); | |_____^ note: ...so that reference does not outlive borrowed content - --> $DIR/regions-nested-fns.rs:10:14 + --> $DIR/regions-nested-fns.rs:17:14 | LL | ay = z; | ^ note: but, the lifetime must be valid for the anonymous lifetime #1 defined here... - --> $DIR/regions-nested-fns.rs:13:72 + --> $DIR/regions-nested-fns.rs:21:72 | LL | ignore::< Box<dyn for<'z> FnMut(&'z isize) -> &'z isize>>(Box::new(|z| { | ________________________________________________________________________^ LL | | if false { return x; } +LL | | +LL | | LL | | if false { return ay; } LL | | return z; LL | | })); | |_____^ note: ...so that the types are compatible - --> $DIR/regions-nested-fns.rs:13:76 + --> $DIR/regions-nested-fns.rs:21:76 | LL | ignore::< Box<dyn for<'z> FnMut(&'z isize) -> &'z isize>>(Box::new(|z| { | ____________________________________________________________________________^ LL | | if false { return x; } +LL | | +LL | | LL | | if false { return ay; } LL | | return z; LL | | })); @@ -43,23 +49,25 @@ LL | | })); found `&isize` error[E0312]: lifetime of reference outlives lifetime of borrowed content... - --> $DIR/regions-nested-fns.rs:14:27 + --> $DIR/regions-nested-fns.rs:22:27 | LL | if false { return x; } | ^ | note: ...the reference is valid for the anonymous lifetime #1 defined here... - --> $DIR/regions-nested-fns.rs:13:72 + --> $DIR/regions-nested-fns.rs:21:72 | LL | ignore::< Box<dyn for<'z> FnMut(&'z isize) -> &'z isize>>(Box::new(|z| { | ________________________________________________________________________^ LL | | if false { return x; } +LL | | +LL | | LL | | if false { return ay; } LL | | return z; LL | | })); | |_____^ note: ...but the borrowed content is only valid for the lifetime `'x` as defined here - --> $DIR/regions-nested-fns.rs:3:11 + --> $DIR/regions-nested-fns.rs:7:11 | LL | fn nested<'x>(x: &'x isize) { | ^^ diff --git a/src/test/ui/regions/regions-nested-fns.nll.stderr b/src/test/ui/regions/regions-nested-fns.nll.stderr index a0cfa362472..6f2a89994b0 100644 --- a/src/test/ui/regions/regions-nested-fns.nll.stderr +++ b/src/test/ui/regions/regions-nested-fns.nll.stderr @@ -1,9 +1,9 @@ error[E0521]: borrowed data escapes outside of closure - --> $DIR/regions-nested-fns.rs:10:9 + --> $DIR/regions-nested-fns.rs:17:9 | LL | let mut ay = &y; | ------ `ay` declared here, outside of the closure body -LL | +... LL | ignore::<Box<dyn for<'z> FnMut(&'z isize)>>(Box::new(|z| { | - `z` is a reference that is only valid in the closure body ... @@ -11,7 +11,7 @@ LL | ay = z; | ^^^^^^ `z` escapes the closure body here error[E0597]: `y` does not live long enough - --> $DIR/regions-nested-fns.rs:5:18 + --> $DIR/regions-nested-fns.rs:9:18 | LL | let mut ay = &y; | ^^ borrowed value does not live long enough @@ -23,7 +23,7 @@ LL | } | - `y` dropped here while still borrowed error[E0597]: `y` does not live long enough - --> $DIR/regions-nested-fns.rs:9:15 + --> $DIR/regions-nested-fns.rs:15:15 | LL | ignore::<Box<dyn for<'z> FnMut(&'z isize)>>(Box::new(|z| { | --- value captured here @@ -38,7 +38,7 @@ LL | } | - `y` dropped here while still borrowed error: lifetime may not live long enough - --> $DIR/regions-nested-fns.rs:14:27 + --> $DIR/regions-nested-fns.rs:22:27 | LL | fn nested<'x>(x: &'x isize) { | -- lifetime `'x` defined here diff --git a/src/test/ui/regions/regions-nested-fns.rs b/src/test/ui/regions/regions-nested-fns.rs index c02d4e0ce45..8cc39792bd9 100644 --- a/src/test/ui/regions/regions-nested-fns.rs +++ b/src/test/ui/regions/regions-nested-fns.rs @@ -1,17 +1,27 @@ +// revisions: base nll +// ignore-compare-mode-nll +//[nll] compile-flags: -Z borrowck=mir + fn ignore<T>(t: T) {} fn nested<'x>(x: &'x isize) { let y = 3; - let mut ay = &y; //~ ERROR E0495 + let mut ay = &y; + //[base]~^ ERROR E0495 + //[nll]~^^ ERROR `y` does not live long enough [E0597] ignore::<Box<dyn for<'z> FnMut(&'z isize)>>(Box::new(|z| { ay = x; ay = &y; + //[nll]~^ ERROR `y` does not live long enough ay = z; + //[nll]~^ ERROR borrowed data escapes outside of closure [E0521] })); ignore::< Box<dyn for<'z> FnMut(&'z isize) -> &'z isize>>(Box::new(|z| { - if false { return x; } //~ ERROR E0312 + if false { return x; } + //[base]~^ ERROR E0312 + //[nll]~^^ ERROR lifetime may not live long enough if false { return ay; } return z; })); diff --git a/src/test/ui/regions/regions-outlives-projection-container.stderr b/src/test/ui/regions/regions-outlives-projection-container.base.stderr index 8c2b2c1e24a..9a66f67ea6e 100644 --- a/src/test/ui/regions/regions-outlives-projection-container.stderr +++ b/src/test/ui/regions/regions-outlives-projection-container.base.stderr @@ -1,67 +1,67 @@ error[E0491]: in type `&'a WithAssoc<TheType<'b>>`, reference has a longer lifetime than the data it references - --> $DIR/regions-outlives-projection-container.rs:36:13 + --> $DIR/regions-outlives-projection-container.rs:40:13 | LL | let _x: &'a WithAssoc<TheType<'b>> = loop { }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: the pointer is valid for the lifetime `'a` as defined here - --> $DIR/regions-outlives-projection-container.rs:28:15 + --> $DIR/regions-outlives-projection-container.rs:32:15 | LL | fn with_assoc<'a,'b>() { | ^^ note: but the referenced data is only valid for the lifetime `'b` as defined here - --> $DIR/regions-outlives-projection-container.rs:28:18 + --> $DIR/regions-outlives-projection-container.rs:32:18 | LL | fn with_assoc<'a,'b>() { | ^^ error[E0491]: in type `&'a WithoutAssoc<TheType<'b>>`, reference has a longer lifetime than the data it references - --> $DIR/regions-outlives-projection-container.rs:54:13 + --> $DIR/regions-outlives-projection-container.rs:59:13 | LL | let _x: &'a WithoutAssoc<TheType<'b>> = loop { }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: the pointer is valid for the lifetime `'a` as defined here - --> $DIR/regions-outlives-projection-container.rs:50:18 + --> $DIR/regions-outlives-projection-container.rs:55:18 | LL | fn without_assoc<'a,'b>() { | ^^ note: but the referenced data is only valid for the lifetime `'b` as defined here - --> $DIR/regions-outlives-projection-container.rs:50:21 + --> $DIR/regions-outlives-projection-container.rs:55:21 | LL | fn without_assoc<'a,'b>() { | ^^ error[E0491]: in type `&'a WithAssoc<TheType<'b>>`, reference has a longer lifetime than the data it references - --> $DIR/regions-outlives-projection-container.rs:63:12 + --> $DIR/regions-outlives-projection-container.rs:69:12 | LL | call::<&'a WithAssoc<TheType<'b>>>(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: the pointer is valid for the lifetime `'a` as defined here - --> $DIR/regions-outlives-projection-container.rs:58:20 + --> $DIR/regions-outlives-projection-container.rs:64:20 | LL | fn call_with_assoc<'a,'b>() { | ^^ note: but the referenced data is only valid for the lifetime `'b` as defined here - --> $DIR/regions-outlives-projection-container.rs:58:23 + --> $DIR/regions-outlives-projection-container.rs:64:23 | LL | fn call_with_assoc<'a,'b>() { | ^^ error[E0491]: in type `&'a WithoutAssoc<TheType<'b>>`, reference has a longer lifetime than the data it references - --> $DIR/regions-outlives-projection-container.rs:70:12 + --> $DIR/regions-outlives-projection-container.rs:77:12 | LL | call::<&'a WithoutAssoc<TheType<'b>>>(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: the pointer is valid for the lifetime `'a` as defined here - --> $DIR/regions-outlives-projection-container.rs:67:23 + --> $DIR/regions-outlives-projection-container.rs:74:23 | LL | fn call_without_assoc<'a,'b>() { | ^^ note: but the referenced data is only valid for the lifetime `'b` as defined here - --> $DIR/regions-outlives-projection-container.rs:67:26 + --> $DIR/regions-outlives-projection-container.rs:74:26 | LL | fn call_without_assoc<'a,'b>() { | ^^ diff --git a/src/test/ui/regions/regions-outlives-projection-container.nll.stderr b/src/test/ui/regions/regions-outlives-projection-container.nll.stderr index 073a3190022..d93eef9ce0b 100644 --- a/src/test/ui/regions/regions-outlives-projection-container.nll.stderr +++ b/src/test/ui/regions/regions-outlives-projection-container.nll.stderr @@ -1,5 +1,5 @@ error: lifetime may not live long enough - --> $DIR/regions-outlives-projection-container.rs:36:13 + --> $DIR/regions-outlives-projection-container.rs:40:13 | LL | fn with_assoc<'a,'b>() { | -- -- lifetime `'b` defined here @@ -12,7 +12,7 @@ LL | let _x: &'a WithAssoc<TheType<'b>> = loop { }; = help: consider adding the following bound: `'b: 'a` error: lifetime may not live long enough - --> $DIR/regions-outlives-projection-container.rs:54:13 + --> $DIR/regions-outlives-projection-container.rs:59:13 | LL | fn without_assoc<'a,'b>() { | -- -- lifetime `'b` defined here @@ -25,7 +25,7 @@ LL | let _x: &'a WithoutAssoc<TheType<'b>> = loop { }; = help: consider adding the following bound: `'b: 'a` error: lifetime may not live long enough - --> $DIR/regions-outlives-projection-container.rs:63:5 + --> $DIR/regions-outlives-projection-container.rs:69:5 | LL | fn call_with_assoc<'a,'b>() { | -- -- lifetime `'b` defined here @@ -38,7 +38,7 @@ LL | call::<&'a WithAssoc<TheType<'b>>>(); = help: consider adding the following bound: `'b: 'a` error: lifetime may not live long enough - --> $DIR/regions-outlives-projection-container.rs:70:5 + --> $DIR/regions-outlives-projection-container.rs:77:5 | LL | fn call_without_assoc<'a,'b>() { | -- -- lifetime `'b` defined here diff --git a/src/test/ui/regions/regions-outlives-projection-container.rs b/src/test/ui/regions/regions-outlives-projection-container.rs index 3afc600becb..ccfd2213b6f 100644 --- a/src/test/ui/regions/regions-outlives-projection-container.rs +++ b/src/test/ui/regions/regions-outlives-projection-container.rs @@ -2,6 +2,10 @@ // type of a bound that appears in the where clause on a struct must // outlive the location in which the type appears. Issue #22246. +// revisions: base nll +// ignore-compare-mode-nll +//[nll] compile-flags: -Z borrowck=mir + #![allow(dead_code)] #![feature(rustc_attrs)] @@ -34,7 +38,8 @@ fn with_assoc<'a,'b>() { // FIXME (#54943) NLL doesn't enforce WF condition in unreachable code if // `_x` is changed to `_` let _x: &'a WithAssoc<TheType<'b>> = loop { }; - //~^ ERROR reference has a longer lifetime + //[base]~^ ERROR reference has a longer lifetime + //[nll]~^^ ERROR lifetime may not live long enough } fn with_assoc1<'a,'b>() where 'b : 'a { @@ -52,7 +57,8 @@ fn without_assoc<'a,'b>() { // that `'b:'a` holds because the `'b` appears in `TheType<'b>`. let _x: &'a WithoutAssoc<TheType<'b>> = loop { }; - //~^ ERROR reference has a longer lifetime + //[base]~^ ERROR reference has a longer lifetime + //[nll]~^^ ERROR lifetime may not live long enough } fn call_with_assoc<'a,'b>() { @@ -61,13 +67,16 @@ fn call_with_assoc<'a,'b>() { // no data. call::<&'a WithAssoc<TheType<'b>>>(); - //~^ ERROR reference has a longer lifetime + //[base]~^ ERROR reference has a longer lifetime + //[nll]~^^ ERROR lifetime may not live long enough } fn call_without_assoc<'a,'b>() { // As `without_assoc`, but in a distinct scenario. - call::<&'a WithoutAssoc<TheType<'b>>>(); //~ ERROR reference has a longer lifetime + call::<&'a WithoutAssoc<TheType<'b>>>(); + //[base]~^ ERROR reference has a longer lifetime + //[nll]~^^ ERROR lifetime may not live long enough } fn call<T>() { } diff --git a/src/test/ui/regions/regions-proc-bound-capture.stderr b/src/test/ui/regions/regions-proc-bound-capture.base.stderr index 2ebe874da93..427c6f4ec8c 100644 --- a/src/test/ui/regions/regions-proc-bound-capture.stderr +++ b/src/test/ui/regions/regions-proc-bound-capture.base.stderr @@ -1,5 +1,5 @@ error[E0759]: `x` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement - --> $DIR/regions-proc-bound-capture.rs:9:14 + --> $DIR/regions-proc-bound-capture.rs:13:14 | LL | fn static_proc(x: &isize) -> Box<dyn FnMut() -> (isize) + 'static> { | ------ this data with an anonymous lifetime `'_`... @@ -8,7 +8,7 @@ LL | Box::new(move || { *x }) | ^^^^^^^^^^^^^^ ...is used and required to live as long as `'static` here | note: `'static` lifetime requirement introduced by the return type - --> $DIR/regions-proc-bound-capture.rs:7:59 + --> $DIR/regions-proc-bound-capture.rs:11:59 | LL | fn static_proc(x: &isize) -> Box<dyn FnMut() -> (isize) + 'static> { | ^^^^^^^ `'static` requirement introduced here diff --git a/src/test/ui/regions/regions-proc-bound-capture.nll.stderr b/src/test/ui/regions/regions-proc-bound-capture.nll.stderr index 75890b85815..ce4d2d4d111 100644 --- a/src/test/ui/regions/regions-proc-bound-capture.nll.stderr +++ b/src/test/ui/regions/regions-proc-bound-capture.nll.stderr @@ -1,11 +1,20 @@ error: lifetime may not live long enough - --> $DIR/regions-proc-bound-capture.rs:9:5 + --> $DIR/regions-proc-bound-capture.rs:13:5 | LL | fn static_proc(x: &isize) -> Box<dyn FnMut() -> (isize) + 'static> { | - let's call the lifetime of this reference `'1` LL | // This is illegal, because the region bound on `proc` is 'static. LL | Box::new(move || { *x }) | ^^^^^^^^^^^^^^^^^^^^^^^^ returning this value requires that `'1` must outlive `'static` + | +help: consider changing the trait object's explicit `'static` bound to the lifetime of argument `x` + | +LL | fn static_proc(x: &isize) -> Box<dyn FnMut() -> (isize) + '_> { + | ~~ +help: alternatively, add an explicit `'static` bound to this reference + | +LL | fn static_proc(x: &'static isize) -> Box<dyn FnMut() -> (isize) + 'static> { + | ~~~~~~~~~~~~~~ error: aborting due to previous error diff --git a/src/test/ui/regions/regions-proc-bound-capture.rs b/src/test/ui/regions/regions-proc-bound-capture.rs index 55d964ac534..1033163c8dd 100644 --- a/src/test/ui/regions/regions-proc-bound-capture.rs +++ b/src/test/ui/regions/regions-proc-bound-capture.rs @@ -1,3 +1,7 @@ +// revisions: base nll +// ignore-compare-mode-nll +//[nll] compile-flags: -Z borrowck=mir + fn borrowed_proc<'a>(x: &'a isize) -> Box<dyn FnMut()->(isize) + 'a> { // This is legal, because the region bound on `proc` // states that it captures `x`. @@ -6,7 +10,9 @@ fn borrowed_proc<'a>(x: &'a isize) -> Box<dyn FnMut()->(isize) + 'a> { fn static_proc(x: &isize) -> Box<dyn FnMut() -> (isize) + 'static> { // This is illegal, because the region bound on `proc` is 'static. - Box::new(move || { *x }) //~ ERROR E0759 + Box::new(move || { *x }) + //[base]~^ ERROR E0759 + //[nll]~^^ ERROR lifetime may not live long enough } fn main() { } diff --git a/src/test/ui/regions/regions-reborrow-from-shorter-mut-ref-mut-ref.stderr b/src/test/ui/regions/regions-reborrow-from-shorter-mut-ref-mut-ref.base.stderr index aca3a1ed057..7ecdb0cd15e 100644 --- a/src/test/ui/regions/regions-reborrow-from-shorter-mut-ref-mut-ref.stderr +++ b/src/test/ui/regions/regions-reborrow-from-shorter-mut-ref-mut-ref.base.stderr @@ -1,5 +1,5 @@ error[E0623]: lifetime mismatch - --> $DIR/regions-reborrow-from-shorter-mut-ref-mut-ref.rs:4:5 + --> $DIR/regions-reborrow-from-shorter-mut-ref-mut-ref.rs:8:5 | LL | fn copy_borrowed_ptr<'a, 'b, 'c>(p: &'a mut &'b mut &'c mut isize) -> &'b mut isize { | ----------------------------- ------------- diff --git a/src/test/ui/regions/regions-reborrow-from-shorter-mut-ref-mut-ref.nll.stderr b/src/test/ui/regions/regions-reborrow-from-shorter-mut-ref-mut-ref.nll.stderr index dc905d076bb..519ada7bdfc 100644 --- a/src/test/ui/regions/regions-reborrow-from-shorter-mut-ref-mut-ref.nll.stderr +++ b/src/test/ui/regions/regions-reborrow-from-shorter-mut-ref-mut-ref.nll.stderr @@ -1,5 +1,5 @@ error: lifetime may not live long enough - --> $DIR/regions-reborrow-from-shorter-mut-ref-mut-ref.rs:4:5 + --> $DIR/regions-reborrow-from-shorter-mut-ref-mut-ref.rs:8:5 | LL | fn copy_borrowed_ptr<'a, 'b, 'c>(p: &'a mut &'b mut &'c mut isize) -> &'b mut isize { | -- -- lifetime `'b` defined here diff --git a/src/test/ui/regions/regions-reborrow-from-shorter-mut-ref-mut-ref.rs b/src/test/ui/regions/regions-reborrow-from-shorter-mut-ref-mut-ref.rs index 35aca8be25b..c4ad05010fb 100644 --- a/src/test/ui/regions/regions-reborrow-from-shorter-mut-ref-mut-ref.rs +++ b/src/test/ui/regions/regions-reborrow-from-shorter-mut-ref-mut-ref.rs @@ -1,7 +1,13 @@ // Issue #8624. Test for reborrowing with 3 levels, not just two. +// revisions: base nll +// ignore-compare-mode-nll +//[nll] compile-flags: -Z borrowck=mir + fn copy_borrowed_ptr<'a, 'b, 'c>(p: &'a mut &'b mut &'c mut isize) -> &'b mut isize { - &mut ***p //~ ERROR lifetime mismatch [E0623] + &mut ***p + //[base]~^ ERROR lifetime mismatch [E0623] + //[nll]~^^ ERROR lifetime may not live long enough } fn main() { diff --git a/src/test/ui/regions/regions-reborrow-from-shorter-mut-ref.stderr b/src/test/ui/regions/regions-reborrow-from-shorter-mut-ref.base.stderr index a9916dbe4f5..3cb7de15850 100644 --- a/src/test/ui/regions/regions-reborrow-from-shorter-mut-ref.stderr +++ b/src/test/ui/regions/regions-reborrow-from-shorter-mut-ref.base.stderr @@ -1,5 +1,5 @@ error[E0623]: lifetime mismatch - --> $DIR/regions-reborrow-from-shorter-mut-ref.rs:6:5 + --> $DIR/regions-reborrow-from-shorter-mut-ref.rs:10:5 | LL | fn copy_borrowed_ptr<'a, 'b>(p: &'a mut &'b mut isize) -> &'b mut isize { | --------------------- ------------- diff --git a/src/test/ui/regions/regions-reborrow-from-shorter-mut-ref.nll.stderr b/src/test/ui/regions/regions-reborrow-from-shorter-mut-ref.nll.stderr index c98ec477417..4dd2a83739c 100644 --- a/src/test/ui/regions/regions-reborrow-from-shorter-mut-ref.nll.stderr +++ b/src/test/ui/regions/regions-reborrow-from-shorter-mut-ref.nll.stderr @@ -1,5 +1,5 @@ error: lifetime may not live long enough - --> $DIR/regions-reborrow-from-shorter-mut-ref.rs:6:5 + --> $DIR/regions-reborrow-from-shorter-mut-ref.rs:10:5 | LL | fn copy_borrowed_ptr<'a, 'b>(p: &'a mut &'b mut isize) -> &'b mut isize { | -- -- lifetime `'b` defined here diff --git a/src/test/ui/regions/regions-reborrow-from-shorter-mut-ref.rs b/src/test/ui/regions/regions-reborrow-from-shorter-mut-ref.rs index 77041ab4f05..c41e76e4d2a 100644 --- a/src/test/ui/regions/regions-reborrow-from-shorter-mut-ref.rs +++ b/src/test/ui/regions/regions-reborrow-from-shorter-mut-ref.rs @@ -2,8 +2,14 @@ // pointer which is backed by another `&'a mut` can only be done // for `'a` (which must be a sublifetime of `'b`). +// revisions: base nll +// ignore-compare-mode-nll +//[nll] compile-flags: -Z borrowck=mir + fn copy_borrowed_ptr<'a, 'b>(p: &'a mut &'b mut isize) -> &'b mut isize { - &mut **p //~ ERROR lifetime mismatch [E0623] + &mut **p + //[base]~^ ERROR lifetime mismatch [E0623] + //[nll]~^^ ERROR lifetime may not live long enough } fn main() { diff --git a/src/test/ui/regions/regions-ret-borrowed-1.stderr b/src/test/ui/regions/regions-ret-borrowed-1.base.stderr index 86df7bfeb70..d102f93a647 100644 --- a/src/test/ui/regions/regions-ret-borrowed-1.stderr +++ b/src/test/ui/regions/regions-ret-borrowed-1.base.stderr @@ -1,28 +1,28 @@ error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements - --> $DIR/regions-ret-borrowed-1.rs:10:14 + --> $DIR/regions-ret-borrowed-1.rs:14:14 | LL | with(|o| o) | ^ | note: first, the lifetime cannot outlive the anonymous lifetime #1 defined here... - --> $DIR/regions-ret-borrowed-1.rs:10:10 + --> $DIR/regions-ret-borrowed-1.rs:14:10 | LL | with(|o| o) | ^^^^^ note: ...so that the types are compatible - --> $DIR/regions-ret-borrowed-1.rs:10:14 + --> $DIR/regions-ret-borrowed-1.rs:14:14 | LL | with(|o| o) | ^ = note: expected `&isize` found `&isize` note: but, the lifetime must be valid for the lifetime `'a` as defined here... - --> $DIR/regions-ret-borrowed-1.rs:9:14 + --> $DIR/regions-ret-borrowed-1.rs:13:14 | LL | fn return_it<'a>() -> &'a isize { | ^^ note: ...so that reference does not outlive borrowed content - --> $DIR/regions-ret-borrowed-1.rs:10:5 + --> $DIR/regions-ret-borrowed-1.rs:14:5 | LL | with(|o| o) | ^^^^^^^^^^^ diff --git a/src/test/ui/regions/regions-ret-borrowed-1.nll.stderr b/src/test/ui/regions/regions-ret-borrowed-1.nll.stderr index 0784e894ea9..4fdadccab15 100644 --- a/src/test/ui/regions/regions-ret-borrowed-1.nll.stderr +++ b/src/test/ui/regions/regions-ret-borrowed-1.nll.stderr @@ -1,5 +1,5 @@ error: lifetime may not live long enough - --> $DIR/regions-ret-borrowed-1.rs:10:14 + --> $DIR/regions-ret-borrowed-1.rs:14:14 | LL | with(|o| o) | -- ^ returning this value requires that `'1` must outlive `'2` diff --git a/src/test/ui/regions/regions-ret-borrowed-1.rs b/src/test/ui/regions/regions-ret-borrowed-1.rs index 1be5edee599..fed631320b4 100644 --- a/src/test/ui/regions/regions-ret-borrowed-1.rs +++ b/src/test/ui/regions/regions-ret-borrowed-1.rs @@ -2,13 +2,18 @@ // some point regions-ret-borrowed reported an error but this file did // not, due to special hardcoding around the anonymous region. +// revisions: base nll +// ignore-compare-mode-nll +//[nll] compile-flags: -Z borrowck=mir + fn with<R, F>(f: F) -> R where F: for<'a> FnOnce(&'a isize) -> R { f(&3) } fn return_it<'a>() -> &'a isize { with(|o| o) - //~^ ERROR cannot infer + //[base]~^ ERROR cannot infer an appropriate lifetime due to conflicting requirements [E0495] + //[nll]~^^ ERROR lifetime may not live long enough } fn main() { diff --git a/src/test/ui/regions/regions-ret-borrowed.stderr b/src/test/ui/regions/regions-ret-borrowed.base.stderr index b9a06d97433..62b42b5dd11 100644 --- a/src/test/ui/regions/regions-ret-borrowed.stderr +++ b/src/test/ui/regions/regions-ret-borrowed.base.stderr @@ -1,28 +1,28 @@ error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements - --> $DIR/regions-ret-borrowed.rs:13:14 + --> $DIR/regions-ret-borrowed.rs:17:14 | LL | with(|o| o) | ^ | note: first, the lifetime cannot outlive the anonymous lifetime #1 defined here... - --> $DIR/regions-ret-borrowed.rs:13:10 + --> $DIR/regions-ret-borrowed.rs:17:10 | LL | with(|o| o) | ^^^^^ note: ...so that the types are compatible - --> $DIR/regions-ret-borrowed.rs:13:14 + --> $DIR/regions-ret-borrowed.rs:17:14 | LL | with(|o| o) | ^ = note: expected `&isize` found `&isize` note: but, the lifetime must be valid for the lifetime `'a` as defined here... - --> $DIR/regions-ret-borrowed.rs:12:14 + --> $DIR/regions-ret-borrowed.rs:16:14 | LL | fn return_it<'a>() -> &'a isize { | ^^ note: ...so that reference does not outlive borrowed content - --> $DIR/regions-ret-borrowed.rs:13:5 + --> $DIR/regions-ret-borrowed.rs:17:5 | LL | with(|o| o) | ^^^^^^^^^^^ diff --git a/src/test/ui/regions/regions-ret-borrowed.nll.stderr b/src/test/ui/regions/regions-ret-borrowed.nll.stderr index d9be5ef89cc..d3ea5bd875f 100644 --- a/src/test/ui/regions/regions-ret-borrowed.nll.stderr +++ b/src/test/ui/regions/regions-ret-borrowed.nll.stderr @@ -1,5 +1,5 @@ error: lifetime may not live long enough - --> $DIR/regions-ret-borrowed.rs:13:14 + --> $DIR/regions-ret-borrowed.rs:17:14 | LL | with(|o| o) | -- ^ returning this value requires that `'1` must outlive `'2` diff --git a/src/test/ui/regions/regions-ret-borrowed.rs b/src/test/ui/regions/regions-ret-borrowed.rs index 5fca92d68b6..2b6855d1c71 100644 --- a/src/test/ui/regions/regions-ret-borrowed.rs +++ b/src/test/ui/regions/regions-ret-borrowed.rs @@ -5,13 +5,18 @@ // used to successfully compile because we failed to account for the // fact that fn(x: &isize) rebound the region &. +// revisions: base nll +// ignore-compare-mode-nll +//[nll] compile-flags: -Z borrowck=mir + fn with<R, F>(f: F) -> R where F: FnOnce(&isize) -> R { f(&3) } fn return_it<'a>() -> &'a isize { with(|o| o) - //~^ ERROR cannot infer + //[base]~^ ERROR cannot infer an appropriate lifetime due to conflicting requirements [E0495] + //[nll]~^^ ERROR lifetime may not live long enough } fn main() { diff --git a/src/test/ui/regions/regions-static-bound-rpass.rs b/src/test/ui/regions/regions-static-bound-rpass.rs index c91c6f87493..25232b455b6 100644 --- a/src/test/ui/regions/regions-static-bound-rpass.rs +++ b/src/test/ui/regions/regions-static-bound-rpass.rs @@ -1,10 +1,17 @@ // run-pass + fn invariant_id<'a,'b>(t: &'b mut &'static ()) -> &'b mut &'a () where 'a: 'static { t } +//~^ WARN unnecessary lifetime parameter `'a` + fn static_id<'a>(t: &'a ()) -> &'static () where 'a: 'static { t } +//~^ WARN unnecessary lifetime parameter `'a` + fn static_id_indirect<'a,'b>(t: &'a ()) -> &'static () where 'a: 'b, 'b: 'static { t } +//~^ WARN unnecessary lifetime parameter `'b` + fn ref_id<'a>(t: &'a ()) -> &'a () where 'static: 'a { t } static UNIT: () = (); diff --git a/src/test/ui/regions/regions-static-bound-rpass.stderr b/src/test/ui/regions/regions-static-bound-rpass.stderr new file mode 100644 index 00000000000..9355a409d50 --- /dev/null +++ b/src/test/ui/regions/regions-static-bound-rpass.stderr @@ -0,0 +1,26 @@ +warning: unnecessary lifetime parameter `'a` + --> $DIR/regions-static-bound-rpass.rs:4:11 + | +LL | where 'a: 'static { t } + | ^^ + | + = help: you can use the `'static` lifetime directly, in place of `'a` + +warning: unnecessary lifetime parameter `'a` + --> $DIR/regions-static-bound-rpass.rs:8:11 + | +LL | where 'a: 'static { t } + | ^^ + | + = help: you can use the `'static` lifetime directly, in place of `'a` + +warning: unnecessary lifetime parameter `'b` + --> $DIR/regions-static-bound-rpass.rs:12:19 + | +LL | where 'a: 'b, 'b: 'static { t } + | ^^ + | + = help: you can use the `'static` lifetime directly, in place of `'b` + +warning: 3 warnings emitted + diff --git a/src/test/ui/regions/regions-static-bound.stderr b/src/test/ui/regions/regions-static-bound.base.stderr index b8e69e02609..6b8120444d0 100644 --- a/src/test/ui/regions/regions-static-bound.stderr +++ b/src/test/ui/regions/regions-static-bound.base.stderr @@ -1,18 +1,34 @@ +warning: unnecessary lifetime parameter `'a` + --> $DIR/regions-static-bound.rs:6:11 + | +LL | where 'a: 'static { t } + | ^^ + | + = help: you can use the `'static` lifetime directly, in place of `'a` + +warning: unnecessary lifetime parameter `'b` + --> $DIR/regions-static-bound.rs:10:19 + | +LL | where 'a: 'b, 'b: 'static { t } + | ^^ + | + = help: you can use the `'static` lifetime directly, in place of `'b` + error[E0312]: lifetime of reference outlives lifetime of borrowed content... - --> $DIR/regions-static-bound.rs:6:5 + --> $DIR/regions-static-bound.rs:14:5 | LL | t | ^ | = note: ...the reference is valid for the static lifetime... note: ...but the borrowed content is only valid for the lifetime `'a` as defined here - --> $DIR/regions-static-bound.rs:5:24 + --> $DIR/regions-static-bound.rs:13:24 | LL | fn static_id_wrong_way<'a>(t: &'a ()) -> &'static () where 'static: 'a { | ^^ error[E0759]: `u` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement - --> $DIR/regions-static-bound.rs:10:5 + --> $DIR/regions-static-bound.rs:20:5 | LL | fn error(u: &(), v: &()) { | --- this data with an anonymous lifetime `'_`... @@ -20,27 +36,27 @@ LL | static_id(&u); | ^^^^^^^^^ -- ...is used here... | note: ...and is required to live as long as `'static` here - --> $DIR/regions-static-bound.rs:10:5 + --> $DIR/regions-static-bound.rs:20:5 | LL | static_id(&u); | ^^^^^^^^^ error[E0759]: `v` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement - --> $DIR/regions-static-bound.rs:11:5 + --> $DIR/regions-static-bound.rs:23:5 | LL | fn error(u: &(), v: &()) { | --- this data with an anonymous lifetime `'_`... -LL | static_id(&u); +... LL | static_id_indirect(&v); | ^^^^^^^^^^^^^^^^^^ -- ...is used here... | note: ...and is required to live as long as `'static` here - --> $DIR/regions-static-bound.rs:11:5 + --> $DIR/regions-static-bound.rs:23:5 | LL | static_id_indirect(&v); | ^^^^^^^^^^^^^^^^^^ -error: aborting due to 3 previous errors +error: aborting due to 3 previous errors; 2 warnings emitted Some errors have detailed explanations: E0312, E0759. For more information about an error, try `rustc --explain E0312`. diff --git a/src/test/ui/regions/regions-static-bound.nll.stderr b/src/test/ui/regions/regions-static-bound.nll.stderr index 699638c7ef9..68e36f3aeea 100644 --- a/src/test/ui/regions/regions-static-bound.nll.stderr +++ b/src/test/ui/regions/regions-static-bound.nll.stderr @@ -1,5 +1,21 @@ +warning: unnecessary lifetime parameter `'a` + --> $DIR/regions-static-bound.rs:6:11 + | +LL | where 'a: 'static { t } + | ^^ + | + = help: you can use the `'static` lifetime directly, in place of `'a` + +warning: unnecessary lifetime parameter `'b` + --> $DIR/regions-static-bound.rs:10:19 + | +LL | where 'a: 'b, 'b: 'static { t } + | ^^ + | + = help: you can use the `'static` lifetime directly, in place of `'b` + error: lifetime may not live long enough - --> $DIR/regions-static-bound.rs:6:5 + --> $DIR/regions-static-bound.rs:14:5 | LL | fn static_id_wrong_way<'a>(t: &'a ()) -> &'static () where 'static: 'a { | -- lifetime `'a` defined here @@ -7,7 +23,7 @@ LL | t | ^ returning this value requires that `'a` must outlive `'static` error[E0521]: borrowed data escapes outside of function - --> $DIR/regions-static-bound.rs:10:5 + --> $DIR/regions-static-bound.rs:20:5 | LL | fn error(u: &(), v: &()) { | - - let's call the lifetime of this reference `'1` @@ -20,19 +36,19 @@ LL | static_id(&u); | argument requires that `'1` must outlive `'static` error[E0521]: borrowed data escapes outside of function - --> $DIR/regions-static-bound.rs:11:5 + --> $DIR/regions-static-bound.rs:23:5 | LL | fn error(u: &(), v: &()) { | - - let's call the lifetime of this reference `'2` | | | `v` is a reference that is only valid in the function body -LL | static_id(&u); +... LL | static_id_indirect(&v); | ^^^^^^^^^^^^^^^^^^^^^^ | | | `v` escapes the function body here | argument requires that `'2` must outlive `'static` -error: aborting due to 3 previous errors +error: aborting due to 3 previous errors; 2 warnings emitted For more information about this error, try `rustc --explain E0521`. diff --git a/src/test/ui/regions/regions-static-bound.rs b/src/test/ui/regions/regions-static-bound.rs index a977a8b36d0..1eed7e71745 100644 --- a/src/test/ui/regions/regions-static-bound.rs +++ b/src/test/ui/regions/regions-static-bound.rs @@ -1,14 +1,28 @@ +// revisions: base nll +// ignore-compare-mode-nll +//[nll] compile-flags: -Z borrowck=mir + fn static_id<'a,'b>(t: &'a ()) -> &'static () where 'a: 'static { t } +//~^ WARN unnecessary lifetime parameter `'a` + fn static_id_indirect<'a,'b>(t: &'a ()) -> &'static () where 'a: 'b, 'b: 'static { t } +//~^ WARN unnecessary lifetime parameter `'b` + fn static_id_wrong_way<'a>(t: &'a ()) -> &'static () where 'static: 'a { - t //~ ERROR E0312 + t + //[base]~^ ERROR E0312 + //[nll]~^^ ERROR lifetime may not live long enough } fn error(u: &(), v: &()) { - static_id(&u); //~ ERROR `u` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement [E0759] - static_id_indirect(&v); //~ ERROR `v` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement [E0759] + static_id(&u); + //[base]~^ ERROR `u` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement [E0759] + //[nll]~^^ ERROR borrowed data escapes outside of function [E0521] + static_id_indirect(&v); + //[base]~^ ERROR `v` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement [E0759] + //[nll]~^^ ERROR borrowed data escapes outside of function [E0521] } fn main() {} diff --git a/src/test/ui/regions/regions-trait-object-subtyping.stderr b/src/test/ui/regions/regions-trait-object-subtyping.base.stderr index d45ca94ad27..9f52136f0c0 100644 --- a/src/test/ui/regions/regions-trait-object-subtyping.stderr +++ b/src/test/ui/regions/regions-trait-object-subtyping.base.stderr @@ -1,43 +1,43 @@ error[E0478]: lifetime bound not satisfied - --> $DIR/regions-trait-object-subtyping.rs:15:5 + --> $DIR/regions-trait-object-subtyping.rs:19:5 | LL | x | ^ | note: lifetime parameter instantiated with the lifetime `'a` as defined here - --> $DIR/regions-trait-object-subtyping.rs:13:9 + --> $DIR/regions-trait-object-subtyping.rs:17:9 | LL | fn foo3<'a,'b>(x: &'a mut dyn Dummy) -> &'b mut dyn Dummy { | ^^ note: but lifetime parameter must outlive the lifetime `'b` as defined here - --> $DIR/regions-trait-object-subtyping.rs:13:12 + --> $DIR/regions-trait-object-subtyping.rs:17:12 | LL | fn foo3<'a,'b>(x: &'a mut dyn Dummy) -> &'b mut dyn Dummy { | ^^ error[E0495]: cannot infer an appropriate lifetime for automatic coercion due to conflicting requirements - --> $DIR/regions-trait-object-subtyping.rs:15:5 + --> $DIR/regions-trait-object-subtyping.rs:19:5 | LL | x | ^ | note: first, the lifetime cannot outlive the lifetime `'a` as defined here... - --> $DIR/regions-trait-object-subtyping.rs:13:9 + --> $DIR/regions-trait-object-subtyping.rs:17:9 | LL | fn foo3<'a,'b>(x: &'a mut dyn Dummy) -> &'b mut dyn Dummy { | ^^ note: ...so that reference does not outlive borrowed content - --> $DIR/regions-trait-object-subtyping.rs:15:5 + --> $DIR/regions-trait-object-subtyping.rs:19:5 | LL | x | ^ note: but, the lifetime must be valid for the lifetime `'b` as defined here... - --> $DIR/regions-trait-object-subtyping.rs:13:12 + --> $DIR/regions-trait-object-subtyping.rs:17:12 | LL | fn foo3<'a,'b>(x: &'a mut dyn Dummy) -> &'b mut dyn Dummy { | ^^ note: ...so that the types are compatible - --> $DIR/regions-trait-object-subtyping.rs:15:5 + --> $DIR/regions-trait-object-subtyping.rs:19:5 | LL | x | ^ @@ -45,7 +45,7 @@ LL | x found `&mut (dyn Dummy + 'b)` error[E0308]: mismatched types - --> $DIR/regions-trait-object-subtyping.rs:22:5 + --> $DIR/regions-trait-object-subtyping.rs:28:5 | LL | x | ^ lifetime mismatch @@ -53,12 +53,12 @@ LL | x = note: expected struct `Wrapper<&'b mut (dyn Dummy + 'b)>` found struct `Wrapper<&'a mut (dyn Dummy + 'a)>` note: the lifetime `'b` as defined here... - --> $DIR/regions-trait-object-subtyping.rs:20:15 + --> $DIR/regions-trait-object-subtyping.rs:26:15 | LL | fn foo4<'a:'b,'b>(x: Wrapper<&'a mut dyn Dummy>) -> Wrapper<&'b mut dyn Dummy> { | ^^ note: ...does not necessarily outlive the lifetime `'a` as defined here - --> $DIR/regions-trait-object-subtyping.rs:20:9 + --> $DIR/regions-trait-object-subtyping.rs:26:9 | LL | fn foo4<'a:'b,'b>(x: Wrapper<&'a mut dyn Dummy>) -> Wrapper<&'b mut dyn Dummy> { | ^^ diff --git a/src/test/ui/regions/regions-trait-object-subtyping.nll.stderr b/src/test/ui/regions/regions-trait-object-subtyping.nll.stderr index 1b3a116d508..c8cec3bd377 100644 --- a/src/test/ui/regions/regions-trait-object-subtyping.nll.stderr +++ b/src/test/ui/regions/regions-trait-object-subtyping.nll.stderr @@ -1,5 +1,5 @@ error: lifetime may not live long enough - --> $DIR/regions-trait-object-subtyping.rs:15:5 + --> $DIR/regions-trait-object-subtyping.rs:19:5 | LL | fn foo3<'a,'b>(x: &'a mut dyn Dummy) -> &'b mut dyn Dummy { | -- -- lifetime `'b` defined here @@ -15,7 +15,7 @@ LL | x = help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance error: lifetime may not live long enough - --> $DIR/regions-trait-object-subtyping.rs:22:5 + --> $DIR/regions-trait-object-subtyping.rs:28:5 | LL | fn foo4<'a:'b,'b>(x: Wrapper<&'a mut dyn Dummy>) -> Wrapper<&'b mut dyn Dummy> { | -- -- lifetime `'b` defined here diff --git a/src/test/ui/regions/regions-trait-object-subtyping.rs b/src/test/ui/regions/regions-trait-object-subtyping.rs index 5b36194870e..f108fc81cea 100644 --- a/src/test/ui/regions/regions-trait-object-subtyping.rs +++ b/src/test/ui/regions/regions-trait-object-subtyping.rs @@ -1,3 +1,7 @@ +// revisions: base nll +// ignore-compare-mode-nll +//[nll] compile-flags: -Z borrowck=mir + trait Dummy { fn dummy(&self); } fn foo1<'a:'b,'b>(x: &'a mut (dyn Dummy+'a)) -> &'b mut (dyn Dummy+'b) { @@ -12,14 +16,18 @@ fn foo2<'a:'b,'b>(x: &'b mut (dyn Dummy+'a)) -> &'b mut (dyn Dummy+'b) { fn foo3<'a,'b>(x: &'a mut dyn Dummy) -> &'b mut dyn Dummy { // Without knowing 'a:'b, we can't coerce - x //~ ERROR lifetime bound not satisfied - //~^ ERROR cannot infer an appropriate lifetime + x + //[base]~^ ERROR lifetime bound not satisfied + //[base]~| ERROR cannot infer an appropriate lifetime + //[nll]~^^^ ERROR lifetime may not live long enough } struct Wrapper<T>(T); fn foo4<'a:'b,'b>(x: Wrapper<&'a mut dyn Dummy>) -> Wrapper<&'b mut dyn Dummy> { // We can't coerce because it is packed in `Wrapper` - x //~ ERROR mismatched types + x + //[base]~^ ERROR mismatched types + //[nll]~^^ ERROR lifetime may not live long enough } fn main() {} diff --git a/src/test/ui/regions/regions-variance-contravariant-use-covariant-in-second-position.stderr b/src/test/ui/regions/regions-variance-contravariant-use-covariant-in-second-position.base.stderr index 98f7a8136da..23b3dea885d 100644 --- a/src/test/ui/regions/regions-variance-contravariant-use-covariant-in-second-position.stderr +++ b/src/test/ui/regions/regions-variance-contravariant-use-covariant-in-second-position.base.stderr @@ -1,5 +1,5 @@ error[E0623]: lifetime mismatch - --> $DIR/regions-variance-contravariant-use-covariant-in-second-position.rs:25:30 + --> $DIR/regions-variance-contravariant-use-covariant-in-second-position.rs:29:30 | LL | fn use_<'short,'long>(c: S<'long, 'short>, | ---------------- this type is declared with multiple lifetimes... diff --git a/src/test/ui/regions/regions-variance-contravariant-use-covariant-in-second-position.nll.stderr b/src/test/ui/regions/regions-variance-contravariant-use-covariant-in-second-position.nll.stderr index 5352be430fb..f364f423f4e 100644 --- a/src/test/ui/regions/regions-variance-contravariant-use-covariant-in-second-position.nll.stderr +++ b/src/test/ui/regions/regions-variance-contravariant-use-covariant-in-second-position.nll.stderr @@ -1,5 +1,5 @@ error: lifetime may not live long enough - --> $DIR/regions-variance-contravariant-use-covariant-in-second-position.rs:25:12 + --> $DIR/regions-variance-contravariant-use-covariant-in-second-position.rs:29:12 | LL | fn use_<'short,'long>(c: S<'long, 'short>, | ------ ----- lifetime `'long` defined here diff --git a/src/test/ui/regions/regions-variance-contravariant-use-covariant-in-second-position.rs b/src/test/ui/regions/regions-variance-contravariant-use-covariant-in-second-position.rs index 8ddd041d457..4bf32ec3082 100644 --- a/src/test/ui/regions/regions-variance-contravariant-use-covariant-in-second-position.rs +++ b/src/test/ui/regions/regions-variance-contravariant-use-covariant-in-second-position.rs @@ -4,6 +4,10 @@ // Note: see variance-regions-*.rs for the tests that check that the // variance inference works in the first place. +// revisions: base nll +// ignore-compare-mode-nll +//[nll] compile-flags: -Z borrowck=mir + // `S` is contravariant with respect to both parameters. struct S<'a, 'b> { f: &'a isize, @@ -22,7 +26,9 @@ fn use_<'short,'long>(c: S<'long, 'short>, // 'short <= 'long, this would be true if the Contravariant type were // covariant with respect to its parameter 'a. - let _: S<'long, 'long> = c; //~ ERROR E0623 + let _: S<'long, 'long> = c; + //[base]~^ ERROR E0623 + //[nll]~^^ ERROR lifetime may not live long enough } fn main() {} diff --git a/src/test/ui/regions/regions-variance-contravariant-use-covariant.stderr b/src/test/ui/regions/regions-variance-contravariant-use-covariant.base.stderr index e7c106cbbe3..8eca0d4d121 100644 --- a/src/test/ui/regions/regions-variance-contravariant-use-covariant.stderr +++ b/src/test/ui/regions/regions-variance-contravariant-use-covariant.base.stderr @@ -1,5 +1,5 @@ error[E0623]: lifetime mismatch - --> $DIR/regions-variance-contravariant-use-covariant.rs:23:35 + --> $DIR/regions-variance-contravariant-use-covariant.rs:27:35 | LL | fn use_<'short,'long>(c: Contravariant<'short>, | --------------------- these two types are declared with different lifetimes... diff --git a/src/test/ui/regions/regions-variance-contravariant-use-covariant.nll.stderr b/src/test/ui/regions/regions-variance-contravariant-use-covariant.nll.stderr index 22c9b915bb9..bc6dd6e69ed 100644 --- a/src/test/ui/regions/regions-variance-contravariant-use-covariant.nll.stderr +++ b/src/test/ui/regions/regions-variance-contravariant-use-covariant.nll.stderr @@ -1,5 +1,5 @@ error: lifetime may not live long enough - --> $DIR/regions-variance-contravariant-use-covariant.rs:23:12 + --> $DIR/regions-variance-contravariant-use-covariant.rs:27:12 | LL | fn use_<'short,'long>(c: Contravariant<'short>, | ------ ----- lifetime `'long` defined here diff --git a/src/test/ui/regions/regions-variance-contravariant-use-covariant.rs b/src/test/ui/regions/regions-variance-contravariant-use-covariant.rs index cbdf62ecb61..ea08a709230 100644 --- a/src/test/ui/regions/regions-variance-contravariant-use-covariant.rs +++ b/src/test/ui/regions/regions-variance-contravariant-use-covariant.rs @@ -4,6 +4,10 @@ // Note: see variance-regions-*.rs for the tests that check that the // variance inference works in the first place. +// revisions: base nll +// ignore-compare-mode-nll +//[nll] compile-flags: -Z borrowck=mir + // This is contravariant with respect to 'a, meaning that // Contravariant<'long> <: Contravariant<'short> iff // 'short <= 'long @@ -20,7 +24,9 @@ fn use_<'short,'long>(c: Contravariant<'short>, // 'short <= 'long, this would be true if the Contravariant type were // covariant with respect to its parameter 'a. - let _: Contravariant<'long> = c; //~ ERROR E0623 + let _: Contravariant<'long> = c; + //[base]~^ ERROR E0623 + //[nll]~^^ ERROR lifetime may not live long enough } fn main() {} diff --git a/src/test/ui/regions/regions-variance-covariant-use-contravariant.stderr b/src/test/ui/regions/regions-variance-covariant-use-contravariant.base.stderr index e5e5261ba99..565de38ee11 100644 --- a/src/test/ui/regions/regions-variance-covariant-use-contravariant.stderr +++ b/src/test/ui/regions/regions-variance-covariant-use-contravariant.base.stderr @@ -1,5 +1,5 @@ error[E0623]: lifetime mismatch - --> $DIR/regions-variance-covariant-use-contravariant.rs:23:32 + --> $DIR/regions-variance-covariant-use-contravariant.rs:27:32 | LL | fn use_<'short,'long>(c: Covariant<'long>, | ---------------- diff --git a/src/test/ui/regions/regions-variance-covariant-use-contravariant.nll.stderr b/src/test/ui/regions/regions-variance-covariant-use-contravariant.nll.stderr index a07181ad553..9d3cebc9a4d 100644 --- a/src/test/ui/regions/regions-variance-covariant-use-contravariant.nll.stderr +++ b/src/test/ui/regions/regions-variance-covariant-use-contravariant.nll.stderr @@ -1,5 +1,5 @@ error: lifetime may not live long enough - --> $DIR/regions-variance-covariant-use-contravariant.rs:23:12 + --> $DIR/regions-variance-covariant-use-contravariant.rs:27:12 | LL | fn use_<'short,'long>(c: Covariant<'long>, | ------ ----- lifetime `'long` defined here diff --git a/src/test/ui/regions/regions-variance-covariant-use-contravariant.rs b/src/test/ui/regions/regions-variance-covariant-use-contravariant.rs index 9aa0c819271..748ad84840a 100644 --- a/src/test/ui/regions/regions-variance-covariant-use-contravariant.rs +++ b/src/test/ui/regions/regions-variance-covariant-use-contravariant.rs @@ -4,6 +4,10 @@ // Note: see variance-regions-*.rs for the tests that check that the // variance inference works in the first place. +// revisions: base nll +// ignore-compare-mode-nll +//[nll] compile-flags: -Z borrowck=mir + // This is covariant with respect to 'a, meaning that // Covariant<'foo> <: Covariant<'static> because // 'foo <= 'static @@ -20,7 +24,9 @@ fn use_<'short,'long>(c: Covariant<'long>, // 'short <= 'long, this would be true if the Covariant type were // contravariant with respect to its parameter 'a. - let _: Covariant<'short> = c; //~ ERROR E0623 + let _: Covariant<'short> = c; + //[base]~^ ERROR E0623 + //[nll]~^^ ERROR lifetime may not live long enough } fn main() {} diff --git a/src/test/ui/regions/regions-variance-invariant-use-contravariant.stderr b/src/test/ui/regions/regions-variance-invariant-use-contravariant.base.stderr index 2a2d5d019a1..e2e8958f53e 100644 --- a/src/test/ui/regions/regions-variance-invariant-use-contravariant.stderr +++ b/src/test/ui/regions/regions-variance-invariant-use-contravariant.base.stderr @@ -1,5 +1,5 @@ error[E0623]: lifetime mismatch - --> $DIR/regions-variance-invariant-use-contravariant.rs:20:32 + --> $DIR/regions-variance-invariant-use-contravariant.rs:24:32 | LL | fn use_<'short,'long>(c: Invariant<'long>, | ---------------- diff --git a/src/test/ui/regions/regions-variance-invariant-use-contravariant.nll.stderr b/src/test/ui/regions/regions-variance-invariant-use-contravariant.nll.stderr index b35a2cb905d..b4ccb1693a7 100644 --- a/src/test/ui/regions/regions-variance-invariant-use-contravariant.nll.stderr +++ b/src/test/ui/regions/regions-variance-invariant-use-contravariant.nll.stderr @@ -1,5 +1,5 @@ error: lifetime may not live long enough - --> $DIR/regions-variance-invariant-use-contravariant.rs:20:12 + --> $DIR/regions-variance-invariant-use-contravariant.rs:24:12 | LL | fn use_<'short,'long>(c: Invariant<'long>, | ------ ----- lifetime `'long` defined here diff --git a/src/test/ui/regions/regions-variance-invariant-use-contravariant.rs b/src/test/ui/regions/regions-variance-invariant-use-contravariant.rs index 663b23b37d4..788f9b1b4d0 100644 --- a/src/test/ui/regions/regions-variance-invariant-use-contravariant.rs +++ b/src/test/ui/regions/regions-variance-invariant-use-contravariant.rs @@ -4,6 +4,10 @@ // Note: see variance-regions-*.rs for the tests that check that the // variance inference works in the first place. +// revisions: base nll +// ignore-compare-mode-nll +//[nll] compile-flags: -Z borrowck=mir + struct Invariant<'a> { f: &'a mut &'a isize } @@ -17,7 +21,9 @@ fn use_<'short,'long>(c: Invariant<'long>, // 'short <= 'long, this would be true if the Invariant type were // contravariant with respect to its parameter 'a. - let _: Invariant<'short> = c; //~ ERROR E0623 + let _: Invariant<'short> = c; + //[base]~^ ERROR E0623 + //[nll]~^^ ERROR lifetime may not live long enough } fn main() { } diff --git a/src/test/ui/regions/regions-variance-invariant-use-covariant.stderr b/src/test/ui/regions/regions-variance-invariant-use-covariant.base.stderr index 7801517595d..da91db1b918 100644 --- a/src/test/ui/regions/regions-variance-invariant-use-covariant.stderr +++ b/src/test/ui/regions/regions-variance-invariant-use-covariant.base.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/regions-variance-invariant-use-covariant.rs:17:33 + --> $DIR/regions-variance-invariant-use-covariant.rs:21:33 | LL | let _: Invariant<'static> = c; | ^ lifetime mismatch @@ -7,7 +7,7 @@ LL | let _: Invariant<'static> = c; = note: expected struct `Invariant<'static>` found struct `Invariant<'b>` note: the lifetime `'b` as defined here... - --> $DIR/regions-variance-invariant-use-covariant.rs:11:9 + --> $DIR/regions-variance-invariant-use-covariant.rs:15:9 | LL | fn use_<'b>(c: Invariant<'b>) { | ^^ diff --git a/src/test/ui/regions/regions-variance-invariant-use-covariant.nll.stderr b/src/test/ui/regions/regions-variance-invariant-use-covariant.nll.stderr index 761e78d179e..7b05c357589 100644 --- a/src/test/ui/regions/regions-variance-invariant-use-covariant.nll.stderr +++ b/src/test/ui/regions/regions-variance-invariant-use-covariant.nll.stderr @@ -1,5 +1,5 @@ error: lifetime may not live long enough - --> $DIR/regions-variance-invariant-use-covariant.rs:17:12 + --> $DIR/regions-variance-invariant-use-covariant.rs:21:12 | LL | fn use_<'b>(c: Invariant<'b>) { | -- lifetime `'b` defined here diff --git a/src/test/ui/regions/regions-variance-invariant-use-covariant.rs b/src/test/ui/regions/regions-variance-invariant-use-covariant.rs index 07482e6fd19..4b7da4493ac 100644 --- a/src/test/ui/regions/regions-variance-invariant-use-covariant.rs +++ b/src/test/ui/regions/regions-variance-invariant-use-covariant.rs @@ -4,6 +4,10 @@ // Note: see variance-regions-*.rs for the tests that check that the // variance inference works in the first place. +// revisions: base nll +// ignore-compare-mode-nll +//[nll] compile-flags: -Z borrowck=mir + struct Invariant<'a> { f: &'a mut &'a isize } @@ -14,7 +18,9 @@ fn use_<'b>(c: Invariant<'b>) { // Since 'b <= 'static, this would be true if Invariant were covariant // with respect to its parameter 'a. - let _: Invariant<'static> = c; //~ ERROR mismatched types + let _: Invariant<'static> = c; + //[base]~^ ERROR mismatched types [E0308] + //[nll]~^^ ERROR lifetime may not live long enough } fn main() { } diff --git a/src/test/ui/repeat-expr/infer.rs b/src/test/ui/repeat-expr/infer.rs new file mode 100644 index 00000000000..8197713b97e --- /dev/null +++ b/src/test/ui/repeat-expr/infer.rs @@ -0,0 +1,16 @@ +// check-pass + +#[derive(Clone, Default)] +struct MaybeCopy<T>(T); + +impl Copy for MaybeCopy<u8> {} + +fn is_copy<T: Copy>(x: T) { + println!("{}", std::any::type_name::<T>()); +} + +fn main() { + is_copy(MaybeCopy::default()); + [MaybeCopy::default(); 13]; + // didn't work, because `Copy` was only checked in the mir +} diff --git a/src/test/ui/repeat-expr-in-static.rs b/src/test/ui/repeat-expr/repeat-expr-in-static.rs index 0b895379330..0b895379330 100644 --- a/src/test/ui/repeat-expr-in-static.rs +++ b/src/test/ui/repeat-expr/repeat-expr-in-static.rs diff --git a/src/test/ui/repeat-to-run-dtor-twice.rs b/src/test/ui/repeat-expr/repeat-to-run-dtor-twice.rs index 0cd8eceefc5..0cd8eceefc5 100644 --- a/src/test/ui/repeat-to-run-dtor-twice.rs +++ b/src/test/ui/repeat-expr/repeat-to-run-dtor-twice.rs diff --git a/src/test/ui/repeat-to-run-dtor-twice.stderr b/src/test/ui/repeat-expr/repeat-to-run-dtor-twice.stderr index 904413712cd..36b93616375 100644 --- a/src/test/ui/repeat-to-run-dtor-twice.stderr +++ b/src/test/ui/repeat-expr/repeat-to-run-dtor-twice.stderr @@ -1,10 +1,10 @@ error[E0277]: the trait bound `Foo: Copy` is not satisfied - --> $DIR/repeat-to-run-dtor-twice.rs:17:13 + --> $DIR/repeat-to-run-dtor-twice.rs:17:15 | LL | let _ = [ a; 5 ]; - | ^^^^^^^^ the trait `Copy` is not implemented for `Foo` + | ^ the trait `Copy` is not implemented for `Foo` | - = note: the `Copy` trait is required because the repeated element will be copied + = note: the `Copy` trait is required because this value will be copied for each element of the array help: consider annotating `Foo` with `#[derive(Copy)]` | LL | #[derive(Copy)] diff --git a/src/test/ui/repeat_count.rs b/src/test/ui/repeat-expr/repeat_count.rs index 96abff4ab41..96abff4ab41 100644 --- a/src/test/ui/repeat_count.rs +++ b/src/test/ui/repeat-expr/repeat_count.rs diff --git a/src/test/ui/repeat_count.stderr b/src/test/ui/repeat-expr/repeat_count.stderr index 59bcd954a1f..59bcd954a1f 100644 --- a/src/test/ui/repeat_count.stderr +++ b/src/test/ui/repeat-expr/repeat_count.stderr diff --git a/src/test/ui/issues/issue-26545.rs b/src/test/ui/resolve/issue-26545.rs index 5652ee74706..5652ee74706 100644 --- a/src/test/ui/issues/issue-26545.rs +++ b/src/test/ui/resolve/issue-26545.rs diff --git a/src/test/ui/issues/issue-26545.stderr b/src/test/ui/resolve/issue-26545.stderr index d3c86692501..d3c86692501 100644 --- a/src/test/ui/issues/issue-26545.stderr +++ b/src/test/ui/resolve/issue-26545.stderr diff --git a/src/test/ui/resolve/resolve-inconsistent-names.rs b/src/test/ui/resolve/resolve-inconsistent-names.rs index b9202f556d1..989d2d45230 100644 --- a/src/test/ui/resolve/resolve-inconsistent-names.rs +++ b/src/test/ui/resolve/resolve-inconsistent-names.rs @@ -2,9 +2,9 @@ enum E { A, B, c } -mod m { +pub mod m { const CONST1: usize = 10; - const Const2: usize = 20; + pub const Const2: usize = 20; } fn main() { @@ -22,15 +22,14 @@ fn main() { //~| ERROR variable `B` is bound inconsistently //~| ERROR mismatched types //~| ERROR variable `c` is not bound in all patterns - //~| HELP consider making the path in the pattern qualified: `?::A` + //~| HELP if you meant to match on unit variant `E::A`, use the full path in the pattern } let z = (10, 20); match z { (CONST1, _) | (_, Const2) => () //~^ ERROR variable `CONST1` is not bound in all patterns - //~| HELP consider making the path in the pattern qualified: `?::CONST1` //~| ERROR variable `Const2` is not bound in all patterns - //~| HELP consider making the path in the pattern qualified: `?::Const2` + //~| HELP if you meant to match on constant `m::Const2`, use the full path in the pattern } } diff --git a/src/test/ui/resolve/resolve-inconsistent-names.stderr b/src/test/ui/resolve/resolve-inconsistent-names.stderr index 70e9c2e5bf5..9de191f7d32 100644 --- a/src/test/ui/resolve/resolve-inconsistent-names.stderr +++ b/src/test/ui/resolve/resolve-inconsistent-names.stderr @@ -23,11 +23,10 @@ LL | (A, B) | (ref B, c) | (c, A) => () | | pattern doesn't bind `A` | variable not in all patterns | -help: if you meant to match on a variant or a `const` item, consider making the path in the pattern qualified: `?::A` - --> $DIR/resolve-inconsistent-names.rs:19:10 +help: if you meant to match on unit variant `E::A`, use the full path in the pattern | -LL | (A, B) | (ref B, c) | (c, A) => () - | ^ +LL | (E::A, B) | (ref B, c) | (c, A) => () + | ~~~~ error[E0408]: variable `B` is not bound in all patterns --> $DIR/resolve-inconsistent-names.rs:19:31 @@ -63,11 +62,11 @@ LL | (CONST1, _) | (_, Const2) => () | | | variable not in all patterns | -help: if you meant to match on a variant or a `const` item, consider making the path in the pattern qualified: `?::CONST1` - --> $DIR/resolve-inconsistent-names.rs:30:10 +note: you might have meant to match on constant `m::CONST1`, which exists but is inaccessible + --> $DIR/resolve-inconsistent-names.rs:6:5 | -LL | (CONST1, _) | (_, Const2) => () - | ^^^^^^ +LL | const CONST1: usize = 10; + | ^^^^^^^^^^^^^^^^^^^^^^^^^ not accessible error[E0408]: variable `Const2` is not bound in all patterns --> $DIR/resolve-inconsistent-names.rs:30:9 @@ -77,11 +76,10 @@ LL | (CONST1, _) | (_, Const2) => () | | | pattern doesn't bind `Const2` | -help: if you meant to match on a variant or a `const` item, consider making the path in the pattern qualified: `?::Const2` - --> $DIR/resolve-inconsistent-names.rs:30:27 +help: if you meant to match on constant `m::Const2`, use the full path in the pattern | -LL | (CONST1, _) | (_, Const2) => () - | ^^^^^^ +LL | (CONST1, _) | (_, m::Const2) => () + | ~~~~~~~~~ error[E0308]: mismatched types --> $DIR/resolve-inconsistent-names.rs:19:19 diff --git a/src/test/ui/rfc-2093-infer-outlives/dont-infer-static.stderr b/src/test/ui/rfc-2093-infer-outlives/dont-infer-static.stderr index 1f387a042e6..950ffd6c89b 100644 --- a/src/test/ui/rfc-2093-infer-outlives/dont-infer-static.stderr +++ b/src/test/ui/rfc-2093-infer-outlives/dont-infer-static.stderr @@ -1,8 +1,6 @@ error[E0310]: the parameter type `U` may not live long enough --> $DIR/dont-infer-static.rs:8:10 | -LL | struct Foo<U> { - | - help: consider adding an explicit lifetime bound...: `U: 'static` LL | bar: Bar<U> | ^^^^^^ ...so that the type `U` will meet its required lifetime bounds... | @@ -11,6 +9,10 @@ note: ...that is required by this bound | LL | struct Bar<T: 'static> { | ^^^^^^^ +help: consider adding an explicit lifetime bound... + | +LL | struct Foo<U: 'static> { + | +++++++++ error: aborting due to previous error diff --git a/src/test/ui/rfc-2093-infer-outlives/regions-enum-not-wf.stderr b/src/test/ui/rfc-2093-infer-outlives/regions-enum-not-wf.stderr index 553a3e71c16..2c660b28500 100644 --- a/src/test/ui/rfc-2093-infer-outlives/regions-enum-not-wf.stderr +++ b/src/test/ui/rfc-2093-infer-outlives/regions-enum-not-wf.stderr @@ -1,27 +1,35 @@ error[E0309]: the parameter type `T` may not live long enough --> $DIR/regions-enum-not-wf.rs:17:18 | -LL | enum Ref1<'a, T> { - | - help: consider adding an explicit lifetime bound...: `T: 'a` LL | Ref1Variant1(RequireOutlives<'a, T>), | ^^^^^^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds + | +help: consider adding an explicit lifetime bound... + | +LL | enum Ref1<'a, T: 'a> { + | ++++ error[E0309]: the parameter type `T` may not live long enough --> $DIR/regions-enum-not-wf.rs:22:25 | -LL | enum Ref2<'a, T> { - | - help: consider adding an explicit lifetime bound...: `T: 'a` -LL | Ref2Variant1, LL | Ref2Variant2(isize, RequireOutlives<'a, T>), | ^^^^^^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds + | +help: consider adding an explicit lifetime bound... + | +LL | enum Ref2<'a, T: 'a> { + | ++++ error[E0309]: the parameter type `T` may not live long enough --> $DIR/regions-enum-not-wf.rs:35:23 | -LL | enum RefDouble<'a, 'b, T> { - | - help: consider adding an explicit lifetime bound...: `T: 'b` LL | RefDoubleVariant1(&'a RequireOutlives<'b, T>), | ^^^^^^^^^^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds + | +help: consider adding an explicit lifetime bound... + | +LL | enum RefDouble<'a, 'b, T: 'b> { + | ++++ error: aborting due to 3 previous errors diff --git a/src/test/ui/rfc-2093-infer-outlives/regions-struct-not-wf.stderr b/src/test/ui/rfc-2093-infer-outlives/regions-struct-not-wf.stderr index f8861262991..34ff1362cf3 100644 --- a/src/test/ui/rfc-2093-infer-outlives/regions-struct-not-wf.stderr +++ b/src/test/ui/rfc-2093-infer-outlives/regions-struct-not-wf.stderr @@ -1,16 +1,17 @@ error[E0309]: the parameter type `T` may not live long enough --> $DIR/regions-struct-not-wf.rs:13:16 | -LL | impl<'a, T> Trait<'a, T> for usize { - | - help: consider adding an explicit lifetime bound...: `T: 'a` LL | type Out = &'a T; | ^^^^^ ...so that the reference type `&'a T` does not outlive the data it points at + | +help: consider adding an explicit lifetime bound... + | +LL | impl<'a, T: 'a> Trait<'a, T> for usize { + | ++++ error[E0309]: the parameter type `T` may not live long enough --> $DIR/regions-struct-not-wf.rs:21:16 | -LL | impl<'a, T> Trait<'a, T> for u32 { - | - help: consider adding an explicit lifetime bound...: `T: 'a` LL | type Out = RefOk<'a, T>; | ^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds... | @@ -19,6 +20,10 @@ note: ...that is required by this bound | LL | struct RefOk<'a, T:'a> { | ^^ +help: consider adding an explicit lifetime bound... + | +LL | impl<'a, T: 'a> Trait<'a, T> for u32 { + | ++++ error[E0491]: in type `&'a &'b T`, reference has a longer lifetime than the data it references --> $DIR/regions-struct-not-wf.rs:25:16 diff --git a/src/test/ui/rfc-2632-const-trait-impl/const-and-non-const-impl.rs b/src/test/ui/rfc-2632-const-trait-impl/const-and-non-const-impl.rs index 961968186de..dd509931766 100644 --- a/src/test/ui/rfc-2632-const-trait-impl/const-and-non-const-impl.rs +++ b/src/test/ui/rfc-2632-const-trait-impl/const-and-non-const-impl.rs @@ -3,7 +3,7 @@ pub struct Int(i32); impl const std::ops::Add for i32 { //~ ERROR type annotations needed - //~^ ERROR only traits defined in the current crate can be implemented for arbitrary types + //~^ ERROR only traits defined in the current crate can be implemented for primitive types type Output = Self; fn add(self, rhs: Self) -> Self { diff --git a/src/test/ui/rfc-2632-const-trait-impl/const-and-non-const-impl.stderr b/src/test/ui/rfc-2632-const-trait-impl/const-and-non-const-impl.stderr index 154a6a35a44..9fd82196e79 100644 --- a/src/test/ui/rfc-2632-const-trait-impl/const-and-non-const-impl.stderr +++ b/src/test/ui/rfc-2632-const-trait-impl/const-and-non-const-impl.stderr @@ -1,4 +1,4 @@ -error[E0117]: only traits defined in the current crate can be implemented for arbitrary types +error[E0117]: only traits defined in the current crate can be implemented for primitive types --> $DIR/const-and-non-const-impl.rs:5:1 | LL | impl const std::ops::Add for i32 { diff --git a/src/test/ui/rfc1623.base.stderr b/src/test/ui/rfc1623.base.stderr index 6d389a1317a..364c8c8f706 100644 --- a/src/test/ui/rfc1623.base.stderr +++ b/src/test/ui/rfc1623.base.stderr @@ -1,5 +1,5 @@ error: implementation of `FnOnce` is not general enough - --> $DIR/rfc1623.rs:36:8 + --> $DIR/rfc1623.rs:32:8 | LL | f: &id, | ^^^ implementation of `FnOnce` is not general enough diff --git a/src/test/ui/rfc1623.nll.stderr b/src/test/ui/rfc1623.nll.stderr index f85b6ff8ff7..2eff4708547 100644 --- a/src/test/ui/rfc1623.nll.stderr +++ b/src/test/ui/rfc1623.nll.stderr @@ -1,63 +1,35 @@ error[E0308]: mismatched types - --> $DIR/rfc1623.rs:29:35 + --> $DIR/rfc1623.rs:32:8 | -LL | static SOME_STRUCT: &SomeStruct = &SomeStruct { - | ___________________________________^ -LL | | -LL | | -LL | | -... | -LL | | -LL | | }; - | |_^ one type is more general than the other +LL | f: &id, + | ^^^ one type is more general than the other | = note: expected type `for<'a, 'b> Fn<(&'a Foo<'b>,)>` found type `Fn<(&Foo<'_>,)>` error[E0308]: mismatched types - --> $DIR/rfc1623.rs:29:35 + --> $DIR/rfc1623.rs:32:8 | -LL | static SOME_STRUCT: &SomeStruct = &SomeStruct { - | ___________________________________^ -LL | | -LL | | -LL | | -... | -LL | | -LL | | }; - | |_^ one type is more general than the other +LL | f: &id, + | ^^^ one type is more general than the other | = note: expected type `for<'a, 'b> Fn<(&'a Foo<'b>,)>` found type `Fn<(&Foo<'_>,)>` error: implementation of `FnOnce` is not general enough - --> $DIR/rfc1623.rs:29:35 + --> $DIR/rfc1623.rs:32:8 | -LL | static SOME_STRUCT: &SomeStruct = &SomeStruct { - | ___________________________________^ -LL | | -LL | | -LL | | -... | -LL | | -LL | | }; - | |_^ implementation of `FnOnce` is not general enough +LL | f: &id, + | ^^^ implementation of `FnOnce` is not general enough | = note: `fn(&'2 Foo<'_>) -> &'2 Foo<'_> {id::<&'2 Foo<'_>>}` must implement `FnOnce<(&'1 Foo<'b>,)>`, for any lifetime `'1`... = note: ...but it actually implements `FnOnce<(&'2 Foo<'_>,)>`, for some specific lifetime `'2` error: implementation of `FnOnce` is not general enough - --> $DIR/rfc1623.rs:29:35 + --> $DIR/rfc1623.rs:32:8 | -LL | static SOME_STRUCT: &SomeStruct = &SomeStruct { - | ___________________________________^ -LL | | -LL | | -LL | | -... | -LL | | -LL | | }; - | |_^ implementation of `FnOnce` is not general enough +LL | f: &id, + | ^^^ implementation of `FnOnce` is not general enough | = note: `fn(&Foo<'2>) -> &Foo<'2> {id::<&Foo<'2>>}` must implement `FnOnce<(&'a Foo<'1>,)>`, for any lifetime `'1`... = note: ...but it actually implements `FnOnce<(&Foo<'2>,)>`, for some specific lifetime `'2` diff --git a/src/test/ui/rfc1623.rs b/src/test/ui/rfc1623.rs index 0e9d2140324..443da0aa955 100644 --- a/src/test/ui/rfc1623.rs +++ b/src/test/ui/rfc1623.rs @@ -27,14 +27,14 @@ fn id<T>(t: T) -> T { } static SOME_STRUCT: &SomeStruct = &SomeStruct { - //[nll]~^ ERROR mismatched types - //[nll]~| ERROR mismatched types - //[nll]~| ERROR implementation of `FnOnce` is not general enough - //[nll]~| ERROR implementation of `FnOnce` is not general enough foo: &Foo { bools: &[false, true] }, bar: &Bar { bools: &[true, true] }, f: &id, //[base]~^ ERROR implementation of `FnOnce` is not general enough + //[nll]~^^ ERROR mismatched types + //[nll]~| ERROR mismatched types + //[nll]~| ERROR implementation of `FnOnce` is not general enough + //[nll]~| ERROR implementation of `FnOnce` is not general enough }; // very simple test for a 'static static with default lifetime diff --git a/src/test/ui/rfcs/rfc-2396-target_feature-11/safe-calls.mir.stderr b/src/test/ui/rfcs/rfc-2396-target_feature-11/safe-calls.mir.stderr index 79273a1dcbf..0ef7b8b09f1 100644 --- a/src/test/ui/rfcs/rfc-2396-target_feature-11/safe-calls.mir.stderr +++ b/src/test/ui/rfcs/rfc-2396-target_feature-11/safe-calls.mir.stderr @@ -7,7 +7,7 @@ LL | sse2(); = note: can only be called if the required target features are available error[E0133]: call to function with `#[target_feature]` is unsafe and requires unsafe function or block - --> $DIR/safe-calls.rs:24:5 + --> $DIR/safe-calls.rs:26:5 | LL | avx_bmi2(); | ^^^^^^^^^^ call to function with `#[target_feature]` @@ -15,7 +15,7 @@ LL | avx_bmi2(); = note: can only be called if the required target features are available error[E0133]: call to function with `#[target_feature]` is unsafe and requires unsafe function or block - --> $DIR/safe-calls.rs:25:5 + --> $DIR/safe-calls.rs:29:5 | LL | Quux.avx_bmi2(); | ^^^^^^^^^^^^^^^ call to function with `#[target_feature]` @@ -23,7 +23,7 @@ LL | Quux.avx_bmi2(); = note: can only be called if the required target features are available error[E0133]: call to function with `#[target_feature]` is unsafe and requires unsafe function or block - --> $DIR/safe-calls.rs:30:5 + --> $DIR/safe-calls.rs:36:5 | LL | avx_bmi2(); | ^^^^^^^^^^ call to function with `#[target_feature]` @@ -31,7 +31,7 @@ LL | avx_bmi2(); = note: can only be called if the required target features are available error[E0133]: call to function with `#[target_feature]` is unsafe and requires unsafe function or block - --> $DIR/safe-calls.rs:31:5 + --> $DIR/safe-calls.rs:39:5 | LL | Quux.avx_bmi2(); | ^^^^^^^^^^^^^^^ call to function with `#[target_feature]` @@ -39,7 +39,7 @@ LL | Quux.avx_bmi2(); = note: can only be called if the required target features are available error[E0133]: call to function with `#[target_feature]` is unsafe and requires unsafe function or block - --> $DIR/safe-calls.rs:36:5 + --> $DIR/safe-calls.rs:46:5 | LL | sse2(); | ^^^^^^ call to function with `#[target_feature]` @@ -47,7 +47,7 @@ LL | sse2(); = note: can only be called if the required target features are available error[E0133]: call to function with `#[target_feature]` is unsafe and requires unsafe function or block - --> $DIR/safe-calls.rs:37:5 + --> $DIR/safe-calls.rs:49:5 | LL | avx_bmi2(); | ^^^^^^^^^^ call to function with `#[target_feature]` @@ -55,7 +55,7 @@ LL | avx_bmi2(); = note: can only be called if the required target features are available error[E0133]: call to function with `#[target_feature]` is unsafe and requires unsafe function or block - --> $DIR/safe-calls.rs:38:5 + --> $DIR/safe-calls.rs:52:5 | LL | Quux.avx_bmi2(); | ^^^^^^^^^^^^^^^ call to function with `#[target_feature]` @@ -63,7 +63,7 @@ LL | Quux.avx_bmi2(); = note: can only be called if the required target features are available error[E0133]: call to function with `#[target_feature]` is unsafe and requires unsafe function or block - --> $DIR/safe-calls.rs:44:5 + --> $DIR/safe-calls.rs:60:5 | LL | sse2(); | ^^^^^^ call to function with `#[target_feature]` @@ -71,7 +71,7 @@ LL | sse2(); = note: can only be called if the required target features are available error[E0133]: call to function with `#[target_feature]` is unsafe and requires unsafe function or block - --> $DIR/safe-calls.rs:47:18 + --> $DIR/safe-calls.rs:65:18 | LL | const name: () = sse2(); | ^^^^^^ call to function with `#[target_feature]` diff --git a/src/test/ui/rfcs/rfc-2396-target_feature-11/safe-calls.rs b/src/test/ui/rfcs/rfc-2396-target_feature-11/safe-calls.rs index de0b89f46ba..cebc6f94784 100644 --- a/src/test/ui/rfcs/rfc-2396-target_feature-11/safe-calls.rs +++ b/src/test/ui/rfcs/rfc-2396-target_feature-11/safe-calls.rs @@ -20,30 +20,50 @@ impl Quux { } fn foo() { - sse2(); //~ ERROR call to function with `#[target_feature]` is unsafe - avx_bmi2(); //~ ERROR call to function with `#[target_feature]` is unsafe - Quux.avx_bmi2(); //~ ERROR call to function with `#[target_feature]` is unsafe + sse2(); + //[mir]~^ ERROR call to function with `#[target_feature]` is unsafe + //[thir]~^^ ERROR call to function `sse2` with `#[target_feature]` is unsafe + avx_bmi2(); + //[mir]~^ ERROR call to function with `#[target_feature]` is unsafe + //[thir]~^^ ERROR call to function `avx_bmi2` with `#[target_feature]` is unsafe + Quux.avx_bmi2(); + //[mir]~^ ERROR call to function with `#[target_feature]` is unsafe + //[thir]~^^ ERROR call to function `Quux::avx_bmi2` with `#[target_feature]` is unsafe } #[target_feature(enable = "sse2")] fn bar() { - avx_bmi2(); //~ ERROR call to function with `#[target_feature]` is unsafe - Quux.avx_bmi2(); //~ ERROR call to function with `#[target_feature]` is unsafe + avx_bmi2(); + //[mir]~^ ERROR call to function with `#[target_feature]` is unsafe + //[thir]~^^ ERROR call to function `avx_bmi2` with `#[target_feature]` is unsafe + Quux.avx_bmi2(); + //[mir]~^ ERROR call to function with `#[target_feature]` is unsafe + //[thir]~^^ ERROR call to function `Quux::avx_bmi2` with `#[target_feature]` is unsafe } #[target_feature(enable = "avx")] fn baz() { - sse2(); //~ ERROR call to function with `#[target_feature]` is unsafe - avx_bmi2(); //~ ERROR call to function with `#[target_feature]` is unsafe - Quux.avx_bmi2(); //~ ERROR call to function with `#[target_feature]` is unsafe + sse2(); + //[mir]~^ ERROR call to function with `#[target_feature]` is unsafe + //[thir]~^^ ERROR call to function `sse2` with `#[target_feature]` is unsafe + avx_bmi2(); + //[mir]~^ ERROR call to function with `#[target_feature]` is unsafe + //[thir]~^^ ERROR call to function `avx_bmi2` with `#[target_feature]` is unsafe + Quux.avx_bmi2(); + //[mir]~^ ERROR call to function with `#[target_feature]` is unsafe + //[thir]~^^ ERROR call to function `Quux::avx_bmi2` with `#[target_feature]` is unsafe } #[target_feature(enable = "avx")] #[target_feature(enable = "bmi2")] fn qux() { - sse2(); //~ ERROR call to function with `#[target_feature]` is unsafe + sse2(); + //[mir]~^ ERROR call to function with `#[target_feature]` is unsafe + //[thir]~^^ ERROR call to function `sse2` with `#[target_feature]` is unsafe } -const name: () = sse2(); //~ ERROR call to function with `#[target_feature]` is unsafe +const name: () = sse2(); +//[mir]~^ ERROR call to function with `#[target_feature]` is unsafe +//[thir]~^^ ERROR call to function `sse2` with `#[target_feature]` is unsafe fn main() {} diff --git a/src/test/ui/rfcs/rfc-2396-target_feature-11/safe-calls.thir.stderr b/src/test/ui/rfcs/rfc-2396-target_feature-11/safe-calls.thir.stderr index 79273a1dcbf..c75ac6e8b9a 100644 --- a/src/test/ui/rfcs/rfc-2396-target_feature-11/safe-calls.thir.stderr +++ b/src/test/ui/rfcs/rfc-2396-target_feature-11/safe-calls.thir.stderr @@ -1,4 +1,4 @@ -error[E0133]: call to function with `#[target_feature]` is unsafe and requires unsafe function or block +error[E0133]: call to function `sse2` with `#[target_feature]` is unsafe and requires unsafe function or block --> $DIR/safe-calls.rs:23:5 | LL | sse2(); @@ -6,72 +6,72 @@ LL | sse2(); | = note: can only be called if the required target features are available -error[E0133]: call to function with `#[target_feature]` is unsafe and requires unsafe function or block - --> $DIR/safe-calls.rs:24:5 +error[E0133]: call to function `avx_bmi2` with `#[target_feature]` is unsafe and requires unsafe function or block + --> $DIR/safe-calls.rs:26:5 | LL | avx_bmi2(); | ^^^^^^^^^^ call to function with `#[target_feature]` | = note: can only be called if the required target features are available -error[E0133]: call to function with `#[target_feature]` is unsafe and requires unsafe function or block - --> $DIR/safe-calls.rs:25:5 +error[E0133]: call to function `Quux::avx_bmi2` with `#[target_feature]` is unsafe and requires unsafe function or block + --> $DIR/safe-calls.rs:29:5 | LL | Quux.avx_bmi2(); | ^^^^^^^^^^^^^^^ call to function with `#[target_feature]` | = note: can only be called if the required target features are available -error[E0133]: call to function with `#[target_feature]` is unsafe and requires unsafe function or block - --> $DIR/safe-calls.rs:30:5 +error[E0133]: call to function `avx_bmi2` with `#[target_feature]` is unsafe and requires unsafe function or block + --> $DIR/safe-calls.rs:36:5 | LL | avx_bmi2(); | ^^^^^^^^^^ call to function with `#[target_feature]` | = note: can only be called if the required target features are available -error[E0133]: call to function with `#[target_feature]` is unsafe and requires unsafe function or block - --> $DIR/safe-calls.rs:31:5 +error[E0133]: call to function `Quux::avx_bmi2` with `#[target_feature]` is unsafe and requires unsafe function or block + --> $DIR/safe-calls.rs:39:5 | LL | Quux.avx_bmi2(); | ^^^^^^^^^^^^^^^ call to function with `#[target_feature]` | = note: can only be called if the required target features are available -error[E0133]: call to function with `#[target_feature]` is unsafe and requires unsafe function or block - --> $DIR/safe-calls.rs:36:5 +error[E0133]: call to function `sse2` with `#[target_feature]` is unsafe and requires unsafe function or block + --> $DIR/safe-calls.rs:46:5 | LL | sse2(); | ^^^^^^ call to function with `#[target_feature]` | = note: can only be called if the required target features are available -error[E0133]: call to function with `#[target_feature]` is unsafe and requires unsafe function or block - --> $DIR/safe-calls.rs:37:5 +error[E0133]: call to function `avx_bmi2` with `#[target_feature]` is unsafe and requires unsafe function or block + --> $DIR/safe-calls.rs:49:5 | LL | avx_bmi2(); | ^^^^^^^^^^ call to function with `#[target_feature]` | = note: can only be called if the required target features are available -error[E0133]: call to function with `#[target_feature]` is unsafe and requires unsafe function or block - --> $DIR/safe-calls.rs:38:5 +error[E0133]: call to function `Quux::avx_bmi2` with `#[target_feature]` is unsafe and requires unsafe function or block + --> $DIR/safe-calls.rs:52:5 | LL | Quux.avx_bmi2(); | ^^^^^^^^^^^^^^^ call to function with `#[target_feature]` | = note: can only be called if the required target features are available -error[E0133]: call to function with `#[target_feature]` is unsafe and requires unsafe function or block - --> $DIR/safe-calls.rs:44:5 +error[E0133]: call to function `sse2` with `#[target_feature]` is unsafe and requires unsafe function or block + --> $DIR/safe-calls.rs:60:5 | LL | sse2(); | ^^^^^^ call to function with `#[target_feature]` | = note: can only be called if the required target features are available -error[E0133]: call to function with `#[target_feature]` is unsafe and requires unsafe function or block - --> $DIR/safe-calls.rs:47:18 +error[E0133]: call to function `sse2` with `#[target_feature]` is unsafe and requires unsafe function or block + --> $DIR/safe-calls.rs:65:18 | LL | const name: () = sse2(); | ^^^^^^ call to function with `#[target_feature]` diff --git a/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch.nll.stderr b/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch.nll.stderr index b06ebf70477..057146e7cb0 100644 --- a/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch.nll.stderr +++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch.nll.stderr @@ -6,6 +6,11 @@ LL | fn a(self: Pin<&Foo>, f: &Foo) -> &Foo { f } | | | | | let's call the lifetime of this reference `'1` | let's call the lifetime of this reference `'2` + | +help: consider introducing a named lifetime parameter and update trait if needed + | +LL | fn a<'a>(self: Pin<&'a Foo>, f: &'a Foo) -> &Foo { f } + | ++++ ++ ++ error: lifetime may not live long enough --> $DIR/arbitrary_self_types_pin_lifetime_mismatch.rs:14:69 @@ -15,6 +20,11 @@ LL | fn c(self: Pin<&Self>, f: &Foo, g: &Foo) -> (Pin<&Foo>, &Foo) { (self, | | | | | let's call the lifetime of this reference `'1` | let's call the lifetime of this reference `'2` + | +help: consider introducing a named lifetime parameter and update trait if needed + | +LL | fn c<'a>(self: Pin<&'a Self>, f: &'a Foo, g: &Foo) -> (Pin<&Foo>, &Foo) { (self, f) } + | ++++ ++ ++ error: lifetime may not live long enough --> $DIR/arbitrary_self_types_pin_lifetime_mismatch.rs:21:58 diff --git a/src/test/ui/self/elision/lt-ref-self.nll.stderr b/src/test/ui/self/elision/lt-ref-self.nll.stderr index 1934207527b..2e26c703b65 100644 --- a/src/test/ui/self/elision/lt-ref-self.nll.stderr +++ b/src/test/ui/self/elision/lt-ref-self.nll.stderr @@ -7,6 +7,11 @@ LL | fn ref_self(&self, f: &u32) -> &u32 { | let's call the lifetime of this reference `'2` LL | f | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | +help: consider introducing a named lifetime parameter and update trait if needed + | +LL | fn ref_self<'a>(&'a self, f: &'a u32) -> &u32 { + | ++++ ++ ++ error: lifetime may not live long enough --> $DIR/lt-ref-self.rs:23:9 @@ -17,6 +22,11 @@ LL | fn ref_Self(self: &Self, f: &u32) -> &u32 { | let's call the lifetime of this reference `'2` LL | f | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | +help: consider introducing a named lifetime parameter and update trait if needed + | +LL | fn ref_Self<'a>(self: &'a Self, f: &'a u32) -> &u32 { + | ++++ ++ ++ error: lifetime may not live long enough --> $DIR/lt-ref-self.rs:29:9 @@ -27,6 +37,11 @@ LL | fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 { | let's call the lifetime of this reference `'2` LL | f | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | +help: consider introducing a named lifetime parameter and update trait if needed + | +LL | fn box_ref_Self<'a>(self: Box<&'a Self>, f: &'a u32) -> &u32 { + | ++++ ++ ++ error: lifetime may not live long enough --> $DIR/lt-ref-self.rs:35:9 @@ -37,6 +52,11 @@ LL | fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 { | let's call the lifetime of this reference `'2` LL | f | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | +help: consider introducing a named lifetime parameter and update trait if needed + | +LL | fn pin_ref_Self<'a>(self: Pin<&'a Self>, f: &'a u32) -> &u32 { + | ++++ ++ ++ error: lifetime may not live long enough --> $DIR/lt-ref-self.rs:41:9 @@ -47,6 +67,11 @@ LL | fn box_box_ref_Self(self: Box<Box<&Self>>, f: &u32) -> &u32 { | let's call the lifetime of this reference `'2` LL | f | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | +help: consider introducing a named lifetime parameter and update trait if needed + | +LL | fn box_box_ref_Self<'a>(self: Box<Box<&'a Self>>, f: &'a u32) -> &u32 { + | ++++ ++ ++ error: lifetime may not live long enough --> $DIR/lt-ref-self.rs:47:9 @@ -57,6 +82,11 @@ LL | fn box_pin_Self(self: Box<Pin<&Self>>, f: &u32) -> &u32 { | let's call the lifetime of this reference `'2` LL | f | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | +help: consider introducing a named lifetime parameter and update trait if needed + | +LL | fn box_pin_Self<'a>(self: Box<Pin<&'a Self>>, f: &'a u32) -> &u32 { + | ++++ ++ ++ error: aborting due to 6 previous errors diff --git a/src/test/ui/self/elision/ref-mut-self.nll.stderr b/src/test/ui/self/elision/ref-mut-self.nll.stderr index f1f4d341b2b..fd4ecae3cfe 100644 --- a/src/test/ui/self/elision/ref-mut-self.nll.stderr +++ b/src/test/ui/self/elision/ref-mut-self.nll.stderr @@ -7,6 +7,11 @@ LL | fn ref_self(&mut self, f: &u32) -> &u32 { | let's call the lifetime of this reference `'2` LL | f | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | +help: consider introducing a named lifetime parameter and update trait if needed + | +LL | fn ref_self<'a>(&'a mut self, f: &'a u32) -> &u32 { + | ++++ ++ ++ error: lifetime may not live long enough --> $DIR/ref-mut-self.rs:23:9 @@ -17,6 +22,11 @@ LL | fn ref_Self(self: &mut Self, f: &u32) -> &u32 { | let's call the lifetime of this reference `'2` LL | f | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | +help: consider introducing a named lifetime parameter and update trait if needed + | +LL | fn ref_Self<'a>(self: &'a mut Self, f: &'a u32) -> &u32 { + | ++++ ++ ++ error: lifetime may not live long enough --> $DIR/ref-mut-self.rs:29:9 @@ -27,6 +37,11 @@ LL | fn box_ref_Self(self: Box<&mut Self>, f: &u32) -> &u32 { | let's call the lifetime of this reference `'2` LL | f | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | +help: consider introducing a named lifetime parameter and update trait if needed + | +LL | fn box_ref_Self<'a>(self: Box<&'a mut Self>, f: &'a u32) -> &u32 { + | ++++ ++ ++ error: lifetime may not live long enough --> $DIR/ref-mut-self.rs:35:9 @@ -37,6 +52,11 @@ LL | fn pin_ref_Self(self: Pin<&mut Self>, f: &u32) -> &u32 { | let's call the lifetime of this reference `'2` LL | f | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | +help: consider introducing a named lifetime parameter and update trait if needed + | +LL | fn pin_ref_Self<'a>(self: Pin<&'a mut Self>, f: &'a u32) -> &u32 { + | ++++ ++ ++ error: lifetime may not live long enough --> $DIR/ref-mut-self.rs:41:9 @@ -47,6 +67,11 @@ LL | fn box_box_ref_Self(self: Box<Box<&mut Self>>, f: &u32) -> &u32 { | let's call the lifetime of this reference `'2` LL | f | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | +help: consider introducing a named lifetime parameter and update trait if needed + | +LL | fn box_box_ref_Self<'a>(self: Box<Box<&'a mut Self>>, f: &'a u32) -> &u32 { + | ++++ ++ ++ error: lifetime may not live long enough --> $DIR/ref-mut-self.rs:47:9 @@ -57,6 +82,11 @@ LL | fn box_pin_ref_Self(self: Box<Pin<&mut Self>>, f: &u32) -> &u32 { | let's call the lifetime of this reference `'2` LL | f | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | +help: consider introducing a named lifetime parameter and update trait if needed + | +LL | fn box_pin_ref_Self<'a>(self: Box<Pin<&'a mut Self>>, f: &'a u32) -> &u32 { + | ++++ ++ ++ error: aborting due to 6 previous errors diff --git a/src/test/ui/self/elision/ref-mut-struct.nll.stderr b/src/test/ui/self/elision/ref-mut-struct.nll.stderr index de7eb02d7a7..ede790c0611 100644 --- a/src/test/ui/self/elision/ref-mut-struct.nll.stderr +++ b/src/test/ui/self/elision/ref-mut-struct.nll.stderr @@ -7,6 +7,11 @@ LL | fn ref_Struct(self: &mut Struct, f: &u32) -> &u32 { | let's call the lifetime of this reference `'2` LL | f | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | +help: consider introducing a named lifetime parameter and update trait if needed + | +LL | fn ref_Struct<'a>(self: &'a mut Struct, f: &'a u32) -> &u32 { + | ++++ ++ ++ error: lifetime may not live long enough --> $DIR/ref-mut-struct.rs:21:9 @@ -17,6 +22,11 @@ LL | fn box_ref_Struct(self: Box<&mut Struct>, f: &u32) -> &u32 { | let's call the lifetime of this reference `'2` LL | f | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | +help: consider introducing a named lifetime parameter and update trait if needed + | +LL | fn box_ref_Struct<'a>(self: Box<&'a mut Struct>, f: &'a u32) -> &u32 { + | ++++ ++ ++ error: lifetime may not live long enough --> $DIR/ref-mut-struct.rs:27:9 @@ -27,6 +37,11 @@ LL | fn pin_ref_Struct(self: Pin<&mut Struct>, f: &u32) -> &u32 { | let's call the lifetime of this reference `'2` LL | f | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | +help: consider introducing a named lifetime parameter and update trait if needed + | +LL | fn pin_ref_Struct<'a>(self: Pin<&'a mut Struct>, f: &'a u32) -> &u32 { + | ++++ ++ ++ error: lifetime may not live long enough --> $DIR/ref-mut-struct.rs:33:9 @@ -37,6 +52,11 @@ LL | fn box_box_ref_Struct(self: Box<Box<&mut Struct>>, f: &u32) -> &u32 { | let's call the lifetime of this reference `'2` LL | f | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | +help: consider introducing a named lifetime parameter and update trait if needed + | +LL | fn box_box_ref_Struct<'a>(self: Box<Box<&'a mut Struct>>, f: &'a u32) -> &u32 { + | ++++ ++ ++ error: lifetime may not live long enough --> $DIR/ref-mut-struct.rs:39:9 @@ -47,6 +67,11 @@ LL | fn box_pin_ref_Struct(self: Box<Pin<&mut Struct>>, f: &u32) -> &u32 { | let's call the lifetime of this reference `'2` LL | f | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | +help: consider introducing a named lifetime parameter and update trait if needed + | +LL | fn box_pin_ref_Struct<'a>(self: Box<Pin<&'a mut Struct>>, f: &'a u32) -> &u32 { + | ++++ ++ ++ error: aborting due to 5 previous errors diff --git a/src/test/ui/self/elision/ref-self.nll.stderr b/src/test/ui/self/elision/ref-self.nll.stderr index f2b7b0ad019..c0efc35fa6c 100644 --- a/src/test/ui/self/elision/ref-self.nll.stderr +++ b/src/test/ui/self/elision/ref-self.nll.stderr @@ -7,6 +7,11 @@ LL | fn ref_self(&self, f: &u32) -> &u32 { | let's call the lifetime of this reference `'2` LL | f | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | +help: consider introducing a named lifetime parameter and update trait if needed + | +LL | fn ref_self<'a>(&'a self, f: &'a u32) -> &u32 { + | ++++ ++ ++ error: lifetime may not live long enough --> $DIR/ref-self.rs:33:9 @@ -17,6 +22,11 @@ LL | fn ref_Self(self: &Self, f: &u32) -> &u32 { | let's call the lifetime of this reference `'2` LL | f | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | +help: consider introducing a named lifetime parameter and update trait if needed + | +LL | fn ref_Self<'a>(self: &'a Self, f: &'a u32) -> &u32 { + | ++++ ++ ++ error: lifetime may not live long enough --> $DIR/ref-self.rs:39:9 @@ -27,6 +37,11 @@ LL | fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 { | let's call the lifetime of this reference `'2` LL | f | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | +help: consider introducing a named lifetime parameter and update trait if needed + | +LL | fn box_ref_Self<'a>(self: Box<&'a Self>, f: &'a u32) -> &u32 { + | ++++ ++ ++ error: lifetime may not live long enough --> $DIR/ref-self.rs:45:9 @@ -37,6 +52,11 @@ LL | fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 { | let's call the lifetime of this reference `'2` LL | f | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | +help: consider introducing a named lifetime parameter and update trait if needed + | +LL | fn pin_ref_Self<'a>(self: Pin<&'a Self>, f: &'a u32) -> &u32 { + | ++++ ++ ++ error: lifetime may not live long enough --> $DIR/ref-self.rs:51:9 @@ -47,6 +67,11 @@ LL | fn box_box_ref_Self(self: Box<Box<&Self>>, f: &u32) -> &u32 { | let's call the lifetime of this reference `'2` LL | f | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | +help: consider introducing a named lifetime parameter and update trait if needed + | +LL | fn box_box_ref_Self<'a>(self: Box<Box<&'a Self>>, f: &'a u32) -> &u32 { + | ++++ ++ ++ error: lifetime may not live long enough --> $DIR/ref-self.rs:57:9 @@ -57,6 +82,11 @@ LL | fn box_pin_ref_Self(self: Box<Pin<&Self>>, f: &u32) -> &u32 { | let's call the lifetime of this reference `'2` LL | f | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | +help: consider introducing a named lifetime parameter and update trait if needed + | +LL | fn box_pin_ref_Self<'a>(self: Box<Pin<&'a Self>>, f: &'a u32) -> &u32 { + | ++++ ++ ++ error: lifetime may not live long enough --> $DIR/ref-self.rs:63:9 @@ -67,6 +97,11 @@ LL | fn wrap_ref_Self_Self(self: Wrap<&Self, Self>, f: &u8) -> &u8 { | let's call the lifetime of this reference `'2` LL | f | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | +help: consider introducing a named lifetime parameter and update trait if needed + | +LL | fn wrap_ref_Self_Self<'a>(self: Wrap<&'a Self, Self>, f: &'a u8) -> &u8 { + | ++++ ++ ++ error: aborting due to 7 previous errors diff --git a/src/test/ui/self/elision/ref-struct.nll.stderr b/src/test/ui/self/elision/ref-struct.nll.stderr index 70453b0ddfc..226923f59ff 100644 --- a/src/test/ui/self/elision/ref-struct.nll.stderr +++ b/src/test/ui/self/elision/ref-struct.nll.stderr @@ -7,6 +7,11 @@ LL | fn ref_Struct(self: &Struct, f: &u32) -> &u32 { | let's call the lifetime of this reference `'2` LL | f | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | +help: consider introducing a named lifetime parameter and update trait if needed + | +LL | fn ref_Struct<'a>(self: &'a Struct, f: &'a u32) -> &u32 { + | ++++ ++ ++ error: lifetime may not live long enough --> $DIR/ref-struct.rs:21:9 @@ -17,6 +22,11 @@ LL | fn box_ref_Struct(self: Box<&Struct>, f: &u32) -> &u32 { | let's call the lifetime of this reference `'2` LL | f | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | +help: consider introducing a named lifetime parameter and update trait if needed + | +LL | fn box_ref_Struct<'a>(self: Box<&'a Struct>, f: &'a u32) -> &u32 { + | ++++ ++ ++ error: lifetime may not live long enough --> $DIR/ref-struct.rs:27:9 @@ -27,6 +37,11 @@ LL | fn pin_ref_Struct(self: Pin<&Struct>, f: &u32) -> &u32 { | let's call the lifetime of this reference `'2` LL | f | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | +help: consider introducing a named lifetime parameter and update trait if needed + | +LL | fn pin_ref_Struct<'a>(self: Pin<&'a Struct>, f: &'a u32) -> &u32 { + | ++++ ++ ++ error: lifetime may not live long enough --> $DIR/ref-struct.rs:33:9 @@ -37,6 +52,11 @@ LL | fn box_box_ref_Struct(self: Box<Box<&Struct>>, f: &u32) -> &u32 { | let's call the lifetime of this reference `'2` LL | f | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | +help: consider introducing a named lifetime parameter and update trait if needed + | +LL | fn box_box_ref_Struct<'a>(self: Box<Box<&'a Struct>>, f: &'a u32) -> &u32 { + | ++++ ++ ++ error: lifetime may not live long enough --> $DIR/ref-struct.rs:39:9 @@ -47,6 +67,11 @@ LL | fn box_pin_Struct(self: Box<Pin<&Struct>>, f: &u32) -> &u32 { | let's call the lifetime of this reference `'2` LL | f | ^ associated function was supposed to return data with lifetime `'2` but it is returning data with lifetime `'1` + | +help: consider introducing a named lifetime parameter and update trait if needed + | +LL | fn box_pin_Struct<'a>(self: Box<Pin<&'a Struct>>, f: &'a u32) -> &u32 { + | ++++ ++ ++ error: aborting due to 5 previous errors diff --git a/src/test/ui/span/issue-39698.stderr b/src/test/ui/span/issue-39698.stderr index 445df90d395..25c35fd5479 100644 --- a/src/test/ui/span/issue-39698.stderr +++ b/src/test/ui/span/issue-39698.stderr @@ -1,3 +1,13 @@ +error[E0408]: variable `d` is not bound in all patterns + --> $DIR/issue-39698.rs:10:37 + | +LL | T::T1(a, d) | T::T2(d, b) | T::T3(c) | T::T4(a) => { println!("{:?}", a); } + | - - ^^^^^^^^ ^^^^^^^^ pattern doesn't bind `d` + | | | | + | | | pattern doesn't bind `d` + | | variable not in all patterns + | variable not in all patterns + error[E0408]: variable `a` is not bound in all patterns --> $DIR/issue-39698.rs:10:23 | @@ -28,16 +38,6 @@ LL | T::T1(a, d) | T::T2(d, b) | T::T3(c) | T::T4(a) => { println!("{:?} | | pattern doesn't bind `c` | pattern doesn't bind `c` -error[E0408]: variable `d` is not bound in all patterns - --> $DIR/issue-39698.rs:10:37 - | -LL | T::T1(a, d) | T::T2(d, b) | T::T3(c) | T::T4(a) => { println!("{:?}", a); } - | - - ^^^^^^^^ ^^^^^^^^ pattern doesn't bind `d` - | | | | - | | | pattern doesn't bind `d` - | | variable not in all patterns - | variable not in all patterns - error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0408`. diff --git a/src/test/ui/static/static-lifetime-bound.stderr b/src/test/ui/static/static-lifetime-bound.stderr index 79d9506619e..ef07a89315f 100644 --- a/src/test/ui/static/static-lifetime-bound.stderr +++ b/src/test/ui/static/static-lifetime-bound.stderr @@ -2,7 +2,7 @@ warning: unnecessary lifetime parameter `'a` --> $DIR/static-lifetime-bound.rs:1:6 | LL | fn f<'a: 'static>(_: &'a i32) {} - | ^^^^^^^^^^^ + | ^^ | = help: you can use the `'static` lifetime directly, in place of `'a` diff --git a/src/test/ui/issues/issue-17233.rs b/src/test/ui/statics/issue-17233.rs index 54a12fdf8e8..54a12fdf8e8 100644 --- a/src/test/ui/issues/issue-17233.rs +++ b/src/test/ui/statics/issue-17233.rs diff --git a/src/test/ui/statics/uninhabited-static.rs b/src/test/ui/statics/uninhabited-static.rs index d5645474891..f5c6f444317 100644 --- a/src/test/ui/statics/uninhabited-static.rs +++ b/src/test/ui/statics/uninhabited-static.rs @@ -11,11 +11,11 @@ extern { static VOID2: Void = unsafe { std::mem::transmute(()) }; //~ ERROR static of uninhabited type //~| WARN: previously accepted -//~| ERROR undefined behavior to use this value +//~| ERROR could not evaluate static initializer //~| WARN: type `Void` does not permit zero-initialization static NEVER2: Void = unsafe { std::mem::transmute(()) }; //~ ERROR static of uninhabited type //~| WARN: previously accepted -//~| ERROR undefined behavior to use this value +//~| ERROR could not evaluate static initializer //~| WARN: type `Void` does not permit zero-initialization fn main() {} diff --git a/src/test/ui/statics/uninhabited-static.stderr b/src/test/ui/statics/uninhabited-static.stderr index c38cf10d6e6..1e0becb7d5a 100644 --- a/src/test/ui/statics/uninhabited-static.stderr +++ b/src/test/ui/statics/uninhabited-static.stderr @@ -43,23 +43,17 @@ LL | static NEVER2: Void = unsafe { std::mem::transmute(()) }; = note: for more information, see issue #74840 <https://github.com/rust-lang/rust/issues/74840> = note: uninhabited statics cannot be initialized, and any access would be an immediate error -error[E0080]: it is undefined behavior to use this value - --> $DIR/uninhabited-static.rs:12:1 +error[E0080]: could not evaluate static initializer + --> $DIR/uninhabited-static.rs:12:31 | LL | static VOID2: Void = unsafe { std::mem::transmute(()) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a value of uninhabited type Void - | - = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. - = note: the raw bytes of the constant (size: 0, align: 1) {} + | ^^^^^^^^^^^^^^^^^^^^^^^ transmuting to uninhabited type -error[E0080]: it is undefined behavior to use this value - --> $DIR/uninhabited-static.rs:16:1 +error[E0080]: could not evaluate static initializer + --> $DIR/uninhabited-static.rs:16:32 | LL | static NEVER2: Void = unsafe { std::mem::transmute(()) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a value of uninhabited type Void - | - = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. - = note: the raw bytes of the constant (size: 0, align: 1) {} + | ^^^^^^^^^^^^^^^^^^^^^^^ transmuting to uninhabited type warning: the type `Void` does not permit zero-initialization --> $DIR/uninhabited-static.rs:12:31 diff --git a/src/test/ui/suggestions/bound-suggestions.fixed b/src/test/ui/suggestions/bound-suggestions.fixed index 31fdd2b67e2..17a019c6984 100644 --- a/src/test/ui/suggestions/bound-suggestions.fixed +++ b/src/test/ui/suggestions/bound-suggestions.fixed @@ -35,7 +35,7 @@ fn test_one_bound_where<X>(x: X) where X: Sized + std::fmt::Debug { } #[allow(dead_code)] -fn test_many_bounds_where<X>(x: X) where X: Sized, X: Sized, X: std::fmt::Debug { +fn test_many_bounds_where<X>(x: X) where X: Sized + std::fmt::Debug, X: Sized { println!("{:?}", x); //~^ ERROR doesn't implement } diff --git a/src/test/ui/suggestions/bound-suggestions.stderr b/src/test/ui/suggestions/bound-suggestions.stderr index 04f233a1e87..e5e19444d24 100644 --- a/src/test/ui/suggestions/bound-suggestions.stderr +++ b/src/test/ui/suggestions/bound-suggestions.stderr @@ -65,10 +65,10 @@ LL | println!("{:?}", x); | ^ `X` cannot be formatted using `{:?}` because it doesn't implement `Debug` | = note: this error originates in the macro `$crate::format_args_nl` (in Nightly builds, run with -Z macro-backtrace for more info) -help: consider further restricting type parameter `X` +help: consider further restricting this bound | -LL | fn test_many_bounds_where<X>(x: X) where X: Sized, X: Sized, X: std::fmt::Debug { - | ++++++++++++++++++++ +LL | fn test_many_bounds_where<X>(x: X) where X: Sized + std::fmt::Debug, X: Sized { + | +++++++++++++++++ error[E0277]: the size for values of type `Self` cannot be known at compilation time --> $DIR/bound-suggestions.rs:44:46 diff --git a/src/test/ui/suggestions/field-has-method.rs b/src/test/ui/suggestions/field-has-method.rs new file mode 100644 index 00000000000..980000151e2 --- /dev/null +++ b/src/test/ui/suggestions/field-has-method.rs @@ -0,0 +1,23 @@ +struct Kind; + +struct Ty { + kind: Kind, +} + +impl Ty { + fn kind(&self) -> Kind { + todo!() + } +} + +struct InferOk<T> { + value: T, + predicates: Vec<()>, +} + +fn foo(i: InferOk<Ty>) { + let k = i.kind(); + //~^ no method named `kind` found for struct `InferOk` in the current scope +} + +fn main() {} diff --git a/src/test/ui/suggestions/field-has-method.stderr b/src/test/ui/suggestions/field-has-method.stderr new file mode 100644 index 00000000000..3a57436f200 --- /dev/null +++ b/src/test/ui/suggestions/field-has-method.stderr @@ -0,0 +1,17 @@ +error[E0599]: no method named `kind` found for struct `InferOk` in the current scope + --> $DIR/field-has-method.rs:19:15 + | +LL | struct InferOk<T> { + | ----------------- method `kind` not found for this +... +LL | let k = i.kind(); + | ^^^^ method not found in `InferOk<Ty>` + | +help: one of the expressions' fields has a method of the same name + | +LL | let k = i.value.kind(); + | ++++++ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0599`. diff --git a/src/test/ui/suggestions/impl-trait-return-trailing-semicolon.rs b/src/test/ui/suggestions/impl-trait-return-trailing-semicolon.rs index 5a17c108ccc..cd3741356f4 100644 --- a/src/test/ui/suggestions/impl-trait-return-trailing-semicolon.rs +++ b/src/test/ui/suggestions/impl-trait-return-trailing-semicolon.rs @@ -8,16 +8,12 @@ impl Bar for Qux {} fn foo() -> impl Bar { //~^ ERROR the trait bound `(): Bar` is not satisfied - //~| ERROR the trait bound `(): Bar` is not satisfied - //~| HELP the following other types implement trait `Bar`: 5; //~^ HELP remove this semicolon } fn bar() -> impl Bar { //~^ ERROR the trait bound `(): Bar` is not satisfied - //~| ERROR the trait bound `(): Bar` is not satisfied - //~| HELP the following other types implement trait `Bar`: //~| HELP the following other types implement trait `Bar`: ""; } diff --git a/src/test/ui/suggestions/impl-trait-return-trailing-semicolon.stderr b/src/test/ui/suggestions/impl-trait-return-trailing-semicolon.stderr index 43f8b7c66f0..e74c2c4214f 100644 --- a/src/test/ui/suggestions/impl-trait-return-trailing-semicolon.stderr +++ b/src/test/ui/suggestions/impl-trait-return-trailing-semicolon.stderr @@ -3,31 +3,14 @@ error[E0277]: the trait bound `(): Bar` is not satisfied | LL | fn foo() -> impl Bar { | ^^^^^^^^ the trait `Bar` is not implemented for `()` -... +LL | LL | 5; | -- help: remove this semicolon | | | this expression has type `{integer}`, which implements `Bar` error[E0277]: the trait bound `(): Bar` is not satisfied - --> $DIR/impl-trait-return-trailing-semicolon.rs:9:22 - | -LL | fn foo() -> impl Bar { - | ______________________^ -LL | | -LL | | -LL | | -LL | | 5; -LL | | -LL | | } - | |_^ the trait `Bar` is not implemented for `()` - | - = help: the following other types implement trait `Bar`: - Qux - i32 - -error[E0277]: the trait bound `(): Bar` is not satisfied - --> $DIR/impl-trait-return-trailing-semicolon.rs:17:13 + --> $DIR/impl-trait-return-trailing-semicolon.rs:15:13 | LL | fn bar() -> impl Bar { | ^^^^^^^^ the trait `Bar` is not implemented for `()` @@ -36,23 +19,6 @@ LL | fn bar() -> impl Bar { Qux i32 -error[E0277]: the trait bound `(): Bar` is not satisfied - --> $DIR/impl-trait-return-trailing-semicolon.rs:17:22 - | -LL | fn bar() -> impl Bar { - | ______________________^ -LL | | -LL | | -LL | | -LL | | -LL | | ""; -LL | | } - | |_^ the trait `Bar` is not implemented for `()` - | - = help: the following other types implement trait `Bar`: - Qux - i32 - -error: aborting due to 4 previous errors +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/suggestions/impl-trait-with-missing-trait-bounds-in-arg.stderr b/src/test/ui/suggestions/impl-trait-with-missing-trait-bounds-in-arg.stderr index 6255df06efb..8ec7b7bf496 100644 --- a/src/test/ui/suggestions/impl-trait-with-missing-trait-bounds-in-arg.stderr +++ b/src/test/ui/suggestions/impl-trait-with-missing-trait-bounds-in-arg.stderr @@ -8,7 +8,7 @@ LL | foo.hello(); help: the following trait defines an item `hello`, perhaps you need to restrict type parameter `impl Foo` with it: | LL | fn test(foo: impl Foo + Bar) { - | ~~~~~~~~~~~~~~ + | +++++ error: aborting due to previous error diff --git a/src/test/ui/suggestions/invalid-bin-op.stderr b/src/test/ui/suggestions/invalid-bin-op.stderr index d18c24e53d0..fe5e2b5816f 100644 --- a/src/test/ui/suggestions/invalid-bin-op.stderr +++ b/src/test/ui/suggestions/invalid-bin-op.stderr @@ -11,11 +11,14 @@ note: an implementation of `PartialEq<_>` might be missing for `S<T>` | LL | struct S<T>(T); | ^^^^^^^^^^^^^^^ must implement `PartialEq<_>` - = note: the trait `std::cmp::PartialEq` is not implemented for `S<T>` help: consider annotating `S<T>` with `#[derive(PartialEq)]` | LL | #[derive(PartialEq)] | +help: consider introducing a `where` bound, but there might be an alternative better way to express this requirement + | +LL | pub fn foo<T>(s: S<T>, t: S<T>) where S<T>: PartialEq { + | +++++++++++++++++++++ error: aborting due to previous error diff --git a/src/test/ui/suggestions/issue-21673.stderr b/src/test/ui/suggestions/issue-21673.stderr index eda29f876d8..0a4aaa61bc7 100644 --- a/src/test/ui/suggestions/issue-21673.stderr +++ b/src/test/ui/suggestions/issue-21673.stderr @@ -7,8 +7,8 @@ LL | x.method() = help: items from traits can only be used if the type parameter is bounded by the trait help: the following trait defines an item `method`, perhaps you need to restrict type parameter `T` with it: | -LL | fn call_method<T: Foo + std::fmt::Debug>(x: &T) { - | ~~~~~~~~ +LL | fn call_method<T: std::fmt::Debug + Foo>(x: &T) { + | +++++ error[E0599]: no method named `method` found for type parameter `T` in the current scope --> $DIR/issue-21673.rs:10:7 @@ -20,7 +20,7 @@ LL | x.method() help: the following trait defines an item `method`, perhaps you need to restrict type parameter `T` with it: | LL | fn call_method_2<T: Foo>(x: T) { - | ~~~~~~ + | +++++ error: aborting due to 2 previous errors diff --git a/src/test/ui/issues/issue-53692.rs b/src/test/ui/suggestions/issue-53692.rs index 30f344e4282..30f344e4282 100644 --- a/src/test/ui/issues/issue-53692.rs +++ b/src/test/ui/suggestions/issue-53692.rs diff --git a/src/test/ui/issues/issue-53692.stderr b/src/test/ui/suggestions/issue-53692.stderr index 09c78da54bc..09c78da54bc 100644 --- a/src/test/ui/issues/issue-53692.stderr +++ b/src/test/ui/suggestions/issue-53692.stderr diff --git a/src/test/ui/suggestions/issue-81098.rs b/src/test/ui/suggestions/issue-81098.rs index 7ca7380a7be..a601b5866f4 100644 --- a/src/test/ui/suggestions/issue-81098.rs +++ b/src/test/ui/suggestions/issue-81098.rs @@ -1,14 +1,12 @@ // Don't suggest removing a semicolon if the last statement isn't an expression with semicolon // (#81098) fn wat() -> impl core::fmt::Display { //~ ERROR: `()` doesn't implement `std::fmt::Display` - //~^ ERROR: `()` doesn't implement `std::fmt::Display` fn why() {} } // Do it if the last statement is an expression with semicolon // (#54771) fn ok() -> impl core::fmt::Display { //~ ERROR: `()` doesn't implement `std::fmt::Display` - //~^ ERROR: `()` doesn't implement `std::fmt::Display` 1; } diff --git a/src/test/ui/suggestions/issue-81098.stderr b/src/test/ui/suggestions/issue-81098.stderr index 8665f2e70a8..4dc47a20282 100644 --- a/src/test/ui/suggestions/issue-81098.stderr +++ b/src/test/ui/suggestions/issue-81098.stderr @@ -8,24 +8,10 @@ LL | fn wat() -> impl core::fmt::Display { = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead error[E0277]: `()` doesn't implement `std::fmt::Display` - --> $DIR/issue-81098.rs:3:37 - | -LL | fn wat() -> impl core::fmt::Display { - | _____________________________________^ -LL | | -LL | | fn why() {} -LL | | } - | |_^ `()` cannot be formatted with the default formatter - | - = help: the trait `std::fmt::Display` is not implemented for `()` - = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead - -error[E0277]: `()` doesn't implement `std::fmt::Display` - --> $DIR/issue-81098.rs:10:12 + --> $DIR/issue-81098.rs:9:12 | LL | fn ok() -> impl core::fmt::Display { | ^^^^^^^^^^^^^^^^^^^^^^^ `()` cannot be formatted with the default formatter -LL | LL | 1; | -- help: remove this semicolon | | @@ -34,19 +20,6 @@ LL | 1; = help: the trait `std::fmt::Display` is not implemented for `()` = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead -error[E0277]: `()` doesn't implement `std::fmt::Display` - --> $DIR/issue-81098.rs:10:36 - | -LL | fn ok() -> impl core::fmt::Display { - | ____________________________________^ -LL | | -LL | | 1; -LL | | } - | |_^ `()` cannot be formatted with the default formatter - | - = help: the trait `std::fmt::Display` is not implemented for `()` - = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead - -error: aborting due to 4 previous errors +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature-2.nll.stderr b/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature-2.nll.stderr index 536494c7344..0212c2d712c 100644 --- a/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature-2.nll.stderr +++ b/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature-2.nll.stderr @@ -12,6 +12,18 @@ note: the parameter type `T` must be valid for the anonymous lifetime defined he | LL | fn func<T: Test>(foo: &Foo, t: T) { | ^^^ +note: ...so that the type `T` will meet its required lifetime bounds + --> $DIR/missing-lifetimes-in-signature-2.rs:20:5 + | +LL | / foo.bar(move |_| { +LL | | +LL | | t.test(); +LL | | }); + | |______^ +help: consider adding an explicit lifetime bound... + | +LL | fn func<T: Test + 'a>(foo: &Foo, t: T) { + | ++++ error: aborting due to previous error diff --git a/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature-2.stderr b/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature-2.stderr index adb928aa8a3..5d195e5ff32 100644 --- a/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature-2.stderr +++ b/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature-2.stderr @@ -1,8 +1,6 @@ error[E0311]: the parameter type `T` may not live long enough --> $DIR/missing-lifetimes-in-signature-2.rs:20:9 | -LL | fn func<T: Test>(foo: &Foo, t: T) { - | -- help: consider adding an explicit lifetime bound...: `T: 'a +` LL | foo.bar(move |_| { | ^^^ | @@ -21,6 +19,10 @@ note: ...that is required by this bound | LL | F: 'a, | ^^ +help: consider adding an explicit lifetime bound... + | +LL | fn func<T: Test + 'a>(foo: &Foo, t: T) { + | ++++ error: aborting due to previous error diff --git a/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature.nll.stderr b/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature.nll.stderr index 0ae629676fe..24eac64d334 100644 --- a/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature.nll.stderr +++ b/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature.nll.stderr @@ -1,5 +1,5 @@ error[E0261]: use of undeclared lifetime name `'a` - --> $DIR/missing-lifetimes-in-signature.rs:38:11 + --> $DIR/missing-lifetimes-in-signature.rs:37:11 | LL | fn baz<G: 'a, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ | - ^^ undeclared lifetime @@ -24,7 +24,7 @@ LL | fn foo<G, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ | ++++ error[E0311]: the parameter type `G` may not live long enough - --> $DIR/missing-lifetimes-in-signature.rs:32:5 + --> $DIR/missing-lifetimes-in-signature.rs:31:5 | LL | / move || { LL | | *dest = g.get(); @@ -36,9 +36,20 @@ note: the parameter type `G` must be valid for the anonymous lifetime defined he | LL | fn bar<G, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ | ^^^^^^ +note: ...so that the type `G` will meet its required lifetime bounds + --> $DIR/missing-lifetimes-in-signature.rs:31:5 + | +LL | / move || { +LL | | *dest = g.get(); +LL | | } + | |_____^ +help: consider adding an explicit lifetime bound... + | +LL | G: Get<T> + 'a, + | ++++ error[E0311]: the parameter type `G` may not live long enough - --> $DIR/missing-lifetimes-in-signature.rs:55:5 + --> $DIR/missing-lifetimes-in-signature.rs:53:5 | LL | / move || { LL | | *dest = g.get(); @@ -46,13 +57,24 @@ LL | | } | |_____^ | note: the parameter type `G` must be valid for the anonymous lifetime defined here... - --> $DIR/missing-lifetimes-in-signature.rs:49:34 + --> $DIR/missing-lifetimes-in-signature.rs:48:34 | LL | fn qux<'a, G: 'a, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ | ^^^^^^ +note: ...so that the type `G` will meet its required lifetime bounds + --> $DIR/missing-lifetimes-in-signature.rs:53:5 + | +LL | / move || { +LL | | *dest = g.get(); +LL | | } + | |_____^ +help: consider adding an explicit lifetime bound... + | +LL | fn qux<'a, G: 'a + 'b, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ + | ++++ error[E0311]: the parameter type `G` may not live long enough - --> $DIR/missing-lifetimes-in-signature.rs:65:9 + --> $DIR/missing-lifetimes-in-signature.rs:62:9 | LL | / move || { LL | | *dest = g.get(); @@ -60,13 +82,24 @@ LL | | } | |_________^ | note: the parameter type `G` must be valid for the anonymous lifetime defined here... - --> $DIR/missing-lifetimes-in-signature.rs:62:47 + --> $DIR/missing-lifetimes-in-signature.rs:60:47 | LL | fn qux<'b, G: Get<T> + 'b, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ { | ^^^^^^ +note: ...so that the type `G` will meet its required lifetime bounds + --> $DIR/missing-lifetimes-in-signature.rs:62:9 + | +LL | / move || { +LL | | *dest = g.get(); +LL | | } + | |_________^ +help: consider adding an explicit lifetime bound... + | +LL | fn qux<'b, G: Get<T> + 'b + 'c, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ { + | ++++ error[E0311]: the parameter type `G` may not live long enough - --> $DIR/missing-lifetimes-in-signature.rs:77:5 + --> $DIR/missing-lifetimes-in-signature.rs:74:5 | LL | / move || { LL | | *dest = g.get(); @@ -74,13 +107,24 @@ LL | | } | |_____^ | note: the parameter type `G` must be valid for the anonymous lifetime defined here... - --> $DIR/missing-lifetimes-in-signature.rs:72:34 + --> $DIR/missing-lifetimes-in-signature.rs:69:34 | LL | fn bat<'a, G: 'a, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ + 'a | ^^^^^^ +note: ...so that the type `G` will meet its required lifetime bounds + --> $DIR/missing-lifetimes-in-signature.rs:74:5 + | +LL | / move || { +LL | | *dest = g.get(); +LL | | } + | |_____^ +help: consider adding an explicit lifetime bound... + | +LL | fn bat<'a, G: 'a + 'b, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ + 'a + | ++++ error[E0621]: explicit lifetime required in the type of `dest` - --> $DIR/missing-lifetimes-in-signature.rs:77:5 + --> $DIR/missing-lifetimes-in-signature.rs:74:5 | LL | fn bat<'a, G: 'a, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ + 'a | ------ help: add explicit lifetime `'a` to the type of `dest`: `&'a mut T` @@ -91,14 +135,17 @@ LL | | } | |_____^ lifetime `'a` required error[E0309]: the parameter type `G` may not live long enough - --> $DIR/missing-lifetimes-in-signature.rs:89:5 + --> $DIR/missing-lifetimes-in-signature.rs:85:5 | LL | / move || { LL | | *dest = g.get(); LL | | } - | |_____^ + | |_____^ ...so that the type `G` will meet its required lifetime bounds + | +help: consider adding an explicit lifetime bound... | - = help: consider adding an explicit lifetime bound `G: 'a`... +LL | G: Get<T> + 'a, + | ++++ error: aborting due to 8 previous errors diff --git a/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature.rs b/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature.rs index 647b343fe06..0a3e6b48163 100644 --- a/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature.rs +++ b/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature.rs @@ -28,7 +28,6 @@ fn bar<G, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ where G: Get<T>, { - //~^ ERROR the parameter type `G` may not live long enough move || { *dest = g.get(); } @@ -51,7 +50,6 @@ fn qux<'a, G: 'a, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ where G: Get<T>, { - //~^ ERROR the parameter type `G` may not live long enough move || { *dest = g.get(); } @@ -61,7 +59,6 @@ where impl<'a> Foo { fn qux<'b, G: Get<T> + 'b, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ { //~^ ERROR the parameter type `G` may not live long enough - //~| ERROR the parameter type `G` may not live long enough move || { *dest = g.get(); } @@ -85,7 +82,6 @@ fn bak<'a, G, T>(g: G, dest: &'a mut T) -> impl FnOnce() + 'a where G: Get<T>, { - //~^ ERROR the parameter type `G` may not live long enough move || { *dest = g.get(); } diff --git a/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature.stderr b/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature.stderr index 6d538dfd609..ae9a020a099 100644 --- a/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature.stderr +++ b/src/test/ui/suggestions/lifetimes/missing-lifetimes-in-signature.stderr @@ -1,5 +1,5 @@ error[E0261]: use of undeclared lifetime name `'a` - --> $DIR/missing-lifetimes-in-signature.rs:38:11 + --> $DIR/missing-lifetimes-in-signature.rs:37:11 | LL | fn baz<G: 'a, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ | - ^^ undeclared lifetime @@ -34,172 +34,63 @@ note: the parameter type `G` must be valid for the anonymous lifetime defined he | LL | fn bar<G, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ | ^^^^^^ -note: ...so that the type `[closure@$DIR/missing-lifetimes-in-signature.rs:32:5: 34:6]` will meet its required lifetime bounds +note: ...so that the type `[closure@$DIR/missing-lifetimes-in-signature.rs:31:5: 33:6]` will meet its required lifetime bounds --> $DIR/missing-lifetimes-in-signature.rs:26:37 | LL | fn bar<G, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ | ^^^^^^^^^^^^^^^^^^ help: consider introducing an explicit lifetime bound | -LL | fn bar<'a, G: 'a, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ + 'a - | ~~~~~ ++++ - -error[E0311]: the parameter type `G` may not live long enough - --> $DIR/missing-lifetimes-in-signature.rs:30:1 - | -LL | / { -LL | | -LL | | move || { -LL | | *dest = g.get(); -LL | | } -LL | | } - | |_^ - | -note: the parameter type `G` must be valid for the anonymous lifetime defined here... - --> $DIR/missing-lifetimes-in-signature.rs:26:26 - | -LL | fn bar<G, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ - | ^^^^^^ -note: ...so that the type `[closure@$DIR/missing-lifetimes-in-signature.rs:32:5: 34:6]` will meet its required lifetime bounds - --> $DIR/missing-lifetimes-in-signature.rs:30:1 - | -LL | / { -LL | | -LL | | move || { -LL | | *dest = g.get(); -LL | | } -LL | | } - | |_^ -help: consider introducing an explicit lifetime bound - | -LL ~ fn bar<'a, G: 'a, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ +LL ~ fn bar<'a, G, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ + 'a LL | LL | where -LL | G: Get<T>, -LL | { -LL | - ... +LL ~ G: Get<T> + 'a, + | error[E0311]: the parameter type `G` may not live long enough - --> $DIR/missing-lifetimes-in-signature.rs:49:45 + --> $DIR/missing-lifetimes-in-signature.rs:48:45 | LL | fn qux<'a, G: 'a, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ | ^^^^^^^^^^^^^^^^^^ | note: the parameter type `G` must be valid for the anonymous lifetime defined here... - --> $DIR/missing-lifetimes-in-signature.rs:49:34 + --> $DIR/missing-lifetimes-in-signature.rs:48:34 | LL | fn qux<'a, G: 'a, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ | ^^^^^^ -note: ...so that the type `[closure@$DIR/missing-lifetimes-in-signature.rs:55:5: 57:6]` will meet its required lifetime bounds - --> $DIR/missing-lifetimes-in-signature.rs:49:45 +note: ...so that the type `[closure@$DIR/missing-lifetimes-in-signature.rs:53:5: 55:6]` will meet its required lifetime bounds + --> $DIR/missing-lifetimes-in-signature.rs:48:45 | LL | fn qux<'a, G: 'a, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ | ^^^^^^^^^^^^^^^^^^ help: consider introducing an explicit lifetime bound | -LL | fn qux<'b, 'a, G: 'b + 'a, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ + 'b - | +++ ~~~~~~~ ++++ - -error[E0311]: the parameter type `G` may not live long enough - --> $DIR/missing-lifetimes-in-signature.rs:53:1 - | -LL | / { -LL | | -LL | | move || { -LL | | *dest = g.get(); -LL | | } -LL | | } - | |_^ - | -note: the parameter type `G` must be valid for the anonymous lifetime defined here... - --> $DIR/missing-lifetimes-in-signature.rs:49:34 - | -LL | fn qux<'a, G: 'a, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ - | ^^^^^^ -note: ...so that the type `[closure@$DIR/missing-lifetimes-in-signature.rs:55:5: 57:6]` will meet its required lifetime bounds - --> $DIR/missing-lifetimes-in-signature.rs:53:1 - | -LL | / { -LL | | -LL | | move || { -LL | | *dest = g.get(); -LL | | } -LL | | } - | |_^ -help: consider introducing an explicit lifetime bound - | -LL ~ fn qux<'b, 'a, G: 'b + 'a, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ -LL | -LL | where -LL | G: Get<T>, -LL | { -LL | - ... +LL | fn qux<'b, 'a, G: 'a + 'b, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ + 'b + | +++ ++++ ++++ error[E0311]: the parameter type `G` may not live long enough - --> $DIR/missing-lifetimes-in-signature.rs:62:58 + --> $DIR/missing-lifetimes-in-signature.rs:60:58 | LL | fn qux<'b, G: Get<T> + 'b, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ { | ^^^^^^^^^^^^^^^^^^ | note: the parameter type `G` must be valid for the anonymous lifetime defined here... - --> $DIR/missing-lifetimes-in-signature.rs:62:47 + --> $DIR/missing-lifetimes-in-signature.rs:60:47 | LL | fn qux<'b, G: Get<T> + 'b, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ { | ^^^^^^ -note: ...so that the type `[closure@$DIR/missing-lifetimes-in-signature.rs:65:9: 67:10]` will meet its required lifetime bounds - --> $DIR/missing-lifetimes-in-signature.rs:62:58 +note: ...so that the type `[closure@$DIR/missing-lifetimes-in-signature.rs:62:9: 64:10]` will meet its required lifetime bounds + --> $DIR/missing-lifetimes-in-signature.rs:60:58 | LL | fn qux<'b, G: Get<T> + 'b, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ { | ^^^^^^^^^^^^^^^^^^ help: consider introducing an explicit lifetime bound | -LL | fn qux<'c, 'b, G: 'c + Get<T> + 'b, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ + 'c { - | +++ ~~~~~~~ ++++ - -error[E0311]: the parameter type `G` may not live long enough - --> $DIR/missing-lifetimes-in-signature.rs:62:77 - | -LL | fn qux<'b, G: Get<T> + 'b, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ { - | _____________________________________________________________________________^ -LL | | -LL | | -LL | | move || { -LL | | *dest = g.get(); -LL | | } -LL | | } - | |_____^ - | -note: the parameter type `G` must be valid for the anonymous lifetime defined here... - --> $DIR/missing-lifetimes-in-signature.rs:62:47 - | -LL | fn qux<'b, G: Get<T> + 'b, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ { - | ^^^^^^ -note: ...so that the type `[closure@$DIR/missing-lifetimes-in-signature.rs:65:9: 67:10]` will meet its required lifetime bounds - --> $DIR/missing-lifetimes-in-signature.rs:62:77 - | -LL | fn qux<'b, G: Get<T> + 'b, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ { - | _____________________________________________________________________________^ -LL | | -LL | | -LL | | move || { -LL | | *dest = g.get(); -LL | | } -LL | | } - | |_____^ -help: consider introducing an explicit lifetime bound - | -LL ~ fn qux<'c, 'b, G: 'c + Get<T> + 'b, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ { -LL | -LL | -LL | move || { -LL | *dest = g.get(); -LL | } - ... +LL | fn qux<'c, 'b, G: Get<T> + 'b + 'c, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ + 'c { + | +++ ++++ ++++ error[E0621]: explicit lifetime required in the type of `dest` - --> $DIR/missing-lifetimes-in-signature.rs:72:45 + --> $DIR/missing-lifetimes-in-signature.rs:69:45 | LL | fn bat<'a, G: 'a, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ + 'a | ------ ^^^^^^^^^^^^^^^^^^^^^^^ lifetime `'a` required @@ -207,28 +98,17 @@ LL | fn bat<'a, G: 'a, T>(g: G, dest: &mut T) -> impl FnOnce() + '_ + 'a | help: add explicit lifetime `'a` to the type of `dest`: `&'a mut T` error[E0309]: the parameter type `G` may not live long enough - --> $DIR/missing-lifetimes-in-signature.rs:83:44 + --> $DIR/missing-lifetimes-in-signature.rs:80:44 | LL | fn bak<'a, G, T>(g: G, dest: &'a mut T) -> impl FnOnce() + 'a - | - ^^^^^^^^^^^^^^^^^^ ...so that the type `[closure@$DIR/missing-lifetimes-in-signature.rs:89:5: 91:6]` will meet its required lifetime bounds - | | - | help: consider adding an explicit lifetime bound...: `G: 'a` - -error[E0309]: the parameter type `G` may not live long enough - --> $DIR/missing-lifetimes-in-signature.rs:87:1 + | ^^^^^^^^^^^^^^^^^^ ...so that the type `[closure@$DIR/missing-lifetimes-in-signature.rs:85:5: 87:6]` will meet its required lifetime bounds | -LL | fn bak<'a, G, T>(g: G, dest: &'a mut T) -> impl FnOnce() + 'a - | - help: consider adding an explicit lifetime bound...: `G: 'a` -... -LL | / { -LL | | -LL | | move || { -LL | | *dest = g.get(); -LL | | } -LL | | } - | |_^ ...so that the type `[closure@$DIR/missing-lifetimes-in-signature.rs:89:5: 91:6]` will meet its required lifetime bounds +help: consider adding an explicit lifetime bound... + | +LL | G: Get<T> + 'a, + | ++++ -error: aborting due to 11 previous errors +error: aborting due to 7 previous errors Some errors have detailed explanations: E0261, E0309, E0621, E0700. For more information about an error, try `rustc --explain E0261`. diff --git a/src/test/ui/suggestions/lifetimes/trait-object-nested-in-impl-trait.nll.stderr b/src/test/ui/suggestions/lifetimes/trait-object-nested-in-impl-trait.nll.stderr index 3ed3827b97d..6c65e4f0175 100644 --- a/src/test/ui/suggestions/lifetimes/trait-object-nested-in-impl-trait.nll.stderr +++ b/src/test/ui/suggestions/lifetimes/trait-object-nested-in-impl-trait.nll.stderr @@ -9,10 +9,14 @@ LL | | remaining: self.0.iter(), LL | | } | |_________^ returning this value requires that `'1` must outlive `'static` | -help: to allow this `impl Trait` to capture borrowed data with lifetime `'1`, add `'_` as a bound +help: to declare that the `impl Trait` captures data from argument `self`, you can add an explicit `'_` lifetime bound | LL | fn iter(&self) -> impl Iterator<Item = Box<dyn Foo>> + '_ { | ++++ +help: to declare that the trait object captures data from argument `self`, you can add an explicit `'_` lifetime bound + | +LL | fn iter(&self) -> impl Iterator<Item = Box<dyn Foo + '_>> { + | ++++ error: lifetime may not live long enough --> $DIR/trait-object-nested-in-impl-trait.rs:39:9 @@ -24,6 +28,11 @@ LL | | current: None, LL | | remaining: self.0.iter(), LL | | } | |_________^ returning this value requires that `'1` must outlive `'static` + | +help: to declare that the trait object captures data from argument `self`, you can add an explicit `'_` lifetime bound + | +LL | fn iter(&self) -> impl Iterator<Item = Box<dyn Foo + '_>> + '_ { + | ++++ error: lifetime may not live long enough --> $DIR/trait-object-nested-in-impl-trait.rs:50:9 @@ -35,6 +44,11 @@ LL | | current: None, LL | | remaining: self.0.iter(), LL | | } | |_________^ returning this value requires that `'a` must outlive `'static` + | +help: to declare that the trait object captures data from argument `self`, you can add an explicit `'a` lifetime bound + | +LL | fn iter<'a>(&'a self) -> impl Iterator<Item = Box<dyn Foo + 'a>> + 'a { + | ++++ error: lifetime may not live long enough --> $DIR/trait-object-nested-in-impl-trait.rs:61:9 @@ -47,10 +61,14 @@ LL | | remaining: self.0.iter(), LL | | } | |_________^ returning this value requires that `'a` must outlive `'static` | -help: to allow this `impl Trait` to capture borrowed data with lifetime `'a`, add `'a` as a bound +help: to declare that the `impl Trait` captures data from argument `self`, you can add an explicit `'a` lifetime bound | LL | fn iter<'a>(&'a self) -> impl Iterator<Item = Box<dyn Foo>> + 'a { | ++++ +help: to declare that the trait object captures data from argument `self`, you can add an explicit `'a` lifetime bound + | +LL | fn iter<'a>(&'a self) -> impl Iterator<Item = Box<dyn Foo + 'a>> { + | ++++ error: aborting due to 4 previous errors diff --git a/src/test/ui/suggestions/restrict-type-argument.stderr b/src/test/ui/suggestions/restrict-type-argument.stderr index 551a7c5060f..01c2de79864 100644 --- a/src/test/ui/suggestions/restrict-type-argument.stderr +++ b/src/test/ui/suggestions/restrict-type-argument.stderr @@ -85,8 +85,8 @@ LL | fn is_send<T: Send>(val: T) {} | ^^^^ required by this bound in `is_send` help: consider further restricting this bound | -LL | fn use_bound_and_where<S: Sync>(val: S) where S: std::fmt::Debug + std::marker::Send { - | +++++++++++++++++++ +LL | fn use_bound_and_where<S: Sync + std::marker::Send>(val: S) where S: std::fmt::Debug { + | +++++++++++++++++++ error[E0277]: `S` cannot be sent between threads safely --> $DIR/restrict-type-argument.rs:28:13 diff --git a/src/test/ui/suggestions/suggest-impl-trait-lifetime.nll.stderr b/src/test/ui/suggestions/suggest-impl-trait-lifetime.nll.stderr index f4eb9813c1a..cf912f4aac2 100644 --- a/src/test/ui/suggestions/suggest-impl-trait-lifetime.nll.stderr +++ b/src/test/ui/suggestions/suggest-impl-trait-lifetime.nll.stderr @@ -2,9 +2,12 @@ error[E0310]: the parameter type `impl Debug` may not live long enough --> $DIR/suggest-impl-trait-lifetime.rs:7:5 | LL | bar(d); - | ^^^^^^ + | ^^^^^^ ...so that the type `impl Debug` will meet its required lifetime bounds | - = help: consider adding an explicit lifetime bound `impl Debug: 'static`... +help: consider adding an explicit lifetime bound... + | +LL | fn foo(d: impl Debug + 'static) { + | +++++++++ error: aborting due to previous error diff --git a/src/test/ui/suggestions/suggest-impl-trait-lifetime.stderr b/src/test/ui/suggestions/suggest-impl-trait-lifetime.stderr index e4a247993c2..4a99c3a14d7 100644 --- a/src/test/ui/suggestions/suggest-impl-trait-lifetime.stderr +++ b/src/test/ui/suggestions/suggest-impl-trait-lifetime.stderr @@ -1,9 +1,6 @@ error[E0310]: the parameter type `impl Debug` may not live long enough --> $DIR/suggest-impl-trait-lifetime.rs:7:5 | -LL | fn foo(d: impl Debug) { - | ---------- help: consider adding an explicit lifetime bound...: `impl Debug + 'static` -LL | LL | bar(d); | ^^^ ...so that the type `impl Debug` will meet its required lifetime bounds... | @@ -12,6 +9,10 @@ note: ...that is required by this bound | LL | fn bar(d: impl Debug + 'static) { | ^^^^^^^ +help: consider adding an explicit lifetime bound... + | +LL | fn foo(d: impl Debug + 'static) { + | +++++++++ error: aborting due to previous error diff --git a/src/test/ui/suggest-using-chars.rs b/src/test/ui/suggestions/suggest-using-chars.rs index 95732881baf..95732881baf 100644 --- a/src/test/ui/suggest-using-chars.rs +++ b/src/test/ui/suggestions/suggest-using-chars.rs diff --git a/src/test/ui/suggest-using-chars.stderr b/src/test/ui/suggestions/suggest-using-chars.stderr index 99bcfb08a08..99bcfb08a08 100644 --- a/src/test/ui/suggest-using-chars.stderr +++ b/src/test/ui/suggestions/suggest-using-chars.stderr diff --git a/src/test/ui/symbol-names/x86-stdcall.rs b/src/test/ui/symbol-names/x86-stdcall.rs new file mode 100644 index 00000000000..9948488c0e9 --- /dev/null +++ b/src/test/ui/symbol-names/x86-stdcall.rs @@ -0,0 +1,13 @@ +// build-pass +// only-x86-windows +#![crate_type = "cdylib"] +#![feature(abi_vectorcall)] + +#[no_mangle] +extern "stdcall" fn foo(_: bool) {} + +#[no_mangle] +extern "fastcall" fn bar(_: u8) {} + +#[no_mangle] +extern "vectorcall" fn baz(_: u16) {} diff --git a/src/test/ui/issues/issue-29488.rs b/src/test/ui/threads-sendsync/issue-29488.rs index 3c9a6a80dbf..3c9a6a80dbf 100644 --- a/src/test/ui/issues/issue-29488.rs +++ b/src/test/ui/threads-sendsync/issue-29488.rs diff --git a/src/test/ui/threads-sendsync/issue-43733.mir.stderr b/src/test/ui/threads-sendsync/issue-43733.mir.stderr index 8dc0e75f1af..1e21a6b37a9 100644 --- a/src/test/ui/threads-sendsync/issue-43733.mir.stderr +++ b/src/test/ui/threads-sendsync/issue-43733.mir.stderr @@ -1,5 +1,5 @@ error[E0133]: call to unsafe function is unsafe and requires unsafe function or block - --> $DIR/issue-43733.rs:19:5 + --> $DIR/issue-43733.rs:21:5 | LL | __KEY.get(Default::default) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ call to unsafe function @@ -7,7 +7,7 @@ LL | __KEY.get(Default::default) = note: consult the function's documentation for information on how to avoid undefined behavior error[E0133]: call to unsafe function is unsafe and requires unsafe function or block - --> $DIR/issue-43733.rs:22:42 + --> $DIR/issue-43733.rs:26:42 | LL | static FOO: std::thread::LocalKey<Foo> = std::thread::LocalKey::new(__getit); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ call to unsafe function diff --git a/src/test/ui/threads-sendsync/issue-43733.rs b/src/test/ui/threads-sendsync/issue-43733.rs index 9926ed09bb4..0ac6f588fb1 100644 --- a/src/test/ui/threads-sendsync/issue-43733.rs +++ b/src/test/ui/threads-sendsync/issue-43733.rs @@ -1,5 +1,7 @@ // revisions: mir thir // [thir]compile-flags: -Z thir-unsafeck +// normalize-stderr-test: "__FastLocalKeyInner::<T>::get" -> "$$LOCALKEYINNER::<T>::get" +// normalize-stderr-test: "__OsLocalKeyInner::<T>::get" -> "$$LOCALKEYINNER::<T>::get" #![feature(thread_local)] #![feature(cfg_target_thread_local, thread_local_internals)] @@ -16,11 +18,14 @@ static __KEY: std::thread::__FastLocalKeyInner<Foo> = std::thread::__FastLocalKe static __KEY: std::thread::__OsLocalKeyInner<Foo> = std::thread::__OsLocalKeyInner::new(); fn __getit(_: Option<&mut Option<RefCell<String>>>) -> std::option::Option<&'static Foo> { - __KEY.get(Default::default) //~ ERROR call to unsafe function is unsafe + __KEY.get(Default::default) + //[mir]~^ ERROR call to unsafe function is unsafe + //[thir]~^^ ERROR call to unsafe function `__ } static FOO: std::thread::LocalKey<Foo> = std::thread::LocalKey::new(__getit); -//~^ ERROR call to unsafe function is unsafe +//[mir]~^ ERROR call to unsafe function is unsafe +//[thir]~^^ ERROR call to unsafe function `LocalKey::<T>::new` fn main() { FOO.with(|foo| println!("{}", foo.borrow())); diff --git a/src/test/ui/threads-sendsync/issue-43733.thir.stderr b/src/test/ui/threads-sendsync/issue-43733.thir.stderr index 8dc0e75f1af..ea7ff408048 100644 --- a/src/test/ui/threads-sendsync/issue-43733.thir.stderr +++ b/src/test/ui/threads-sendsync/issue-43733.thir.stderr @@ -1,13 +1,13 @@ -error[E0133]: call to unsafe function is unsafe and requires unsafe function or block - --> $DIR/issue-43733.rs:19:5 +error[E0133]: call to unsafe function `$LOCALKEYINNER::<T>::get` is unsafe and requires unsafe function or block + --> $DIR/issue-43733.rs:21:5 | LL | __KEY.get(Default::default) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ call to unsafe function | = note: consult the function's documentation for information on how to avoid undefined behavior -error[E0133]: call to unsafe function is unsafe and requires unsafe function or block - --> $DIR/issue-43733.rs:22:42 +error[E0133]: call to unsafe function `LocalKey::<T>::new` is unsafe and requires unsafe function or block + --> $DIR/issue-43733.rs:26:42 | LL | static FOO: std::thread::LocalKey<Foo> = std::thread::LocalKey::new(__getit); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ call to unsafe function diff --git a/src/test/ui/traits/do-not-mention-type-params-by-name-in-suggestion-issue-96292.rs b/src/test/ui/traits/do-not-mention-type-params-by-name-in-suggestion-issue-96292.rs new file mode 100644 index 00000000000..9a444be500c --- /dev/null +++ b/src/test/ui/traits/do-not-mention-type-params-by-name-in-suggestion-issue-96292.rs @@ -0,0 +1,20 @@ +struct Thing<X>(X); + +trait Method<T> { + fn method(self, _: i32) -> T; +} + +impl<X> Method<i32> for Thing<X> { + fn method(self, _: i32) -> i32 { 0 } +} + +impl<X> Method<u32> for Thing<X> { + fn method(self, _: i32) -> u32 { 0 } +} + +fn main() { + let thing = Thing(true); + thing.method(42); + //~^ ERROR type annotations needed + //~| ERROR type annotations needed +} diff --git a/src/test/ui/traits/do-not-mention-type-params-by-name-in-suggestion-issue-96292.stderr b/src/test/ui/traits/do-not-mention-type-params-by-name-in-suggestion-issue-96292.stderr new file mode 100644 index 00000000000..0e52420ec43 --- /dev/null +++ b/src/test/ui/traits/do-not-mention-type-params-by-name-in-suggestion-issue-96292.stderr @@ -0,0 +1,37 @@ +error[E0282]: type annotations needed + --> $DIR/do-not-mention-type-params-by-name-in-suggestion-issue-96292.rs:17:11 + | +LL | thing.method(42); + | ------^^^^^^---- + | | | + | | cannot infer type for type parameter `T` declared on the trait `Method` + | this method call resolves to `T` + +error[E0283]: type annotations needed + --> $DIR/do-not-mention-type-params-by-name-in-suggestion-issue-96292.rs:17:11 + | +LL | thing.method(42); + | ------^^^^^^---- + | | | + | | cannot infer type for type parameter `T` declared on the trait `Method` + | this method call resolves to `T` + | +note: multiple `impl`s satisfying `Thing<bool>: Method<_>` found + --> $DIR/do-not-mention-type-params-by-name-in-suggestion-issue-96292.rs:7:1 + | +LL | impl<X> Method<i32> for Thing<X> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | impl<X> Method<u32> for Thing<X> { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: use the fully qualified path for the potential candidates + | +LL | <Thing<_> as Method<i32>>::method(thing, 42); + | ++++++++++++++++++++++++++++++++++ ~ +LL | <Thing<_> as Method<u32>>::method(thing, 42); + | ++++++++++++++++++++++++++++++++++ ~ + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0282, E0283. +For more information about an error, try `rustc --explain E0282`. diff --git a/src/test/ui/issues/issue-43132.rs b/src/test/ui/traits/issue-43132.rs index c886f4b0a2d..c886f4b0a2d 100644 --- a/src/test/ui/issues/issue-43132.rs +++ b/src/test/ui/traits/issue-43132.rs diff --git a/src/test/ui/traits/issue-65284-suggest-generic-trait-bound.stderr b/src/test/ui/traits/issue-65284-suggest-generic-trait-bound.stderr index cb1128fe5c6..35d41c62667 100644 --- a/src/test/ui/traits/issue-65284-suggest-generic-trait-bound.stderr +++ b/src/test/ui/traits/issue-65284-suggest-generic-trait-bound.stderr @@ -7,8 +7,8 @@ LL | t.foo() = help: items from traits can only be used if the type parameter is bounded by the trait help: the following trait defines an item `foo`, perhaps you need to restrict type parameter `T` with it: | -LL | fn do_stuff<T: Foo + Bar>(t : T) { - | ~~~~~~~~ +LL | fn do_stuff<T : Bar + Foo>(t : T) { + | +++++ error: aborting due to previous error diff --git a/src/test/ui/issues/issue-71036.rs b/src/test/ui/traits/issue-71036.rs index 3d2df6fe997..3d2df6fe997 100644 --- a/src/test/ui/issues/issue-71036.rs +++ b/src/test/ui/traits/issue-71036.rs diff --git a/src/test/ui/issues/issue-71036.stderr b/src/test/ui/traits/issue-71036.stderr index db1f6946660..db1f6946660 100644 --- a/src/test/ui/issues/issue-71036.stderr +++ b/src/test/ui/traits/issue-71036.stderr diff --git a/src/test/ui/traits/issue-77982.stderr b/src/test/ui/traits/issue-77982.stderr index 413225d45a6..63c1cb3791e 100644 --- a/src/test/ui/traits/issue-77982.stderr +++ b/src/test/ui/traits/issue-77982.stderr @@ -37,13 +37,13 @@ LL | opts.get(opt.as_ref()); help: use the fully qualified path for the potential candidates | LL | opts.get(<String as AsRef<OsStr>>::as_ref(opt)); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + | +++++++++++++++++++++++++++++++++ ~ LL | opts.get(<String as AsRef<Path>>::as_ref(opt)); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + | ++++++++++++++++++++++++++++++++ ~ LL | opts.get(<String as AsRef<[u8]>>::as_ref(opt)); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + | ++++++++++++++++++++++++++++++++ ~ LL | opts.get(<String as AsRef<str>>::as_ref(opt)); - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + | +++++++++++++++++++++++++++++++ ~ and 4 other candidates error[E0283]: type annotations needed diff --git a/src/test/ui/traits/issue-95898.stderr b/src/test/ui/traits/issue-95898.stderr index d7d47905396..0a58ad4b663 100644 --- a/src/test/ui/traits/issue-95898.stderr +++ b/src/test/ui/traits/issue-95898.stderr @@ -8,7 +8,7 @@ LL | t.clone(); help: the following trait defines an item `clone`, perhaps you need to restrict type parameter `T` with it: | LL | fn foo<T: Clone>(t: T) { - | ~~~~~~~~ + | +++++ error: aborting due to previous error diff --git a/src/test/ui/traits/resolution-in-overloaded-op.stderr b/src/test/ui/traits/resolution-in-overloaded-op.stderr index 049fffe165a..3ae6bf130cc 100644 --- a/src/test/ui/traits/resolution-in-overloaded-op.stderr +++ b/src/test/ui/traits/resolution-in-overloaded-op.stderr @@ -6,10 +6,10 @@ LL | a * b | | | &T | -help: consider further restricting this bound +help: consider introducing a `where` bound, but there might be an alternative better way to express this requirement | -LL | fn foo<T: MyMul<f64, f64> + std::ops::Mul<Output = f64>>(a: &T, b: f64) -> f64 { - | +++++++++++++++++++++++++++++ +LL | fn foo<T: MyMul<f64, f64>>(a: &T, b: f64) -> f64 where &T: Mul<f64> { + | ++++++++++++++++++ error: aborting due to previous error diff --git a/src/test/ui/try-trait/bad-interconversion.stderr b/src/test/ui/try-trait/bad-interconversion.stderr index 1a4105231dc..1dbf3ebdf82 100644 --- a/src/test/ui/try-trait/bad-interconversion.stderr +++ b/src/test/ui/try-trait/bad-interconversion.stderr @@ -31,7 +31,9 @@ LL | | } | |_- this function returns a `Result` | = help: the trait `FromResidual<Option<Infallible>>` is not implemented for `Result<u64, String>` - = help: the trait `FromResidual<Result<Infallible, E>>` is implemented for `Result<T, F>` + = help: the following other types implement trait `FromResidual<R>`: + <Result<T, F> as FromResidual<Result<Infallible, E>>> + <Result<T, F> as FromResidual<Yeet<E>>> error[E0277]: the `?` operator can only be used on `Result`s in a function that returns `Result` --> $DIR/bad-interconversion.rs:17:31 @@ -44,7 +46,9 @@ LL | | } | |_- this function returns a `Result` | = help: the trait `FromResidual<ControlFlow<{integer}, Infallible>>` is not implemented for `Result<u64, String>` - = help: the trait `FromResidual<Result<Infallible, E>>` is implemented for `Result<T, F>` + = help: the following other types implement trait `FromResidual<R>`: + <Result<T, F> as FromResidual<Result<Infallible, E>>> + <Result<T, F> as FromResidual<Yeet<E>>> error[E0277]: the `?` operator can only be used on `Option`s, not `Result`s, in a function that returns `Option` --> $DIR/bad-interconversion.rs:22:22 @@ -57,7 +61,9 @@ LL | | } | |_- this function returns an `Option` | = help: the trait `FromResidual<Result<Infallible, &str>>` is not implemented for `Option<u16>` - = help: the trait `FromResidual` is implemented for `Option<T>` + = help: the following other types implement trait `FromResidual<R>`: + <Option<T> as FromResidual<Yeet<()>>> + <Option<T> as FromResidual> error[E0277]: the `?` operator can only be used on `Option`s in a function that returns `Option` --> $DIR/bad-interconversion.rs:27:33 @@ -70,7 +76,9 @@ LL | | } | |_- this function returns an `Option` | = help: the trait `FromResidual<ControlFlow<{integer}, Infallible>>` is not implemented for `Option<u64>` - = help: the trait `FromResidual` is implemented for `Option<T>` + = help: the following other types implement trait `FromResidual<R>`: + <Option<T> as FromResidual<Yeet<()>>> + <Option<T> as FromResidual> error[E0277]: the `?` operator can only be used on `ControlFlow`s in a function that returns `ControlFlow` --> $DIR/bad-interconversion.rs:32:39 diff --git a/src/test/ui/try-trait/option-to-result.stderr b/src/test/ui/try-trait/option-to-result.stderr index b0e4de8cb4b..ae5c3ad6282 100644 --- a/src/test/ui/try-trait/option-to-result.stderr +++ b/src/test/ui/try-trait/option-to-result.stderr @@ -10,7 +10,9 @@ LL | | } | |_- this function returns a `Result` | = help: the trait `FromResidual<Option<Infallible>>` is not implemented for `Result<(), ()>` - = help: the trait `FromResidual<Result<Infallible, E>>` is implemented for `Result<T, F>` + = help: the following other types implement trait `FromResidual<R>`: + <Result<T, F> as FromResidual<Result<Infallible, E>>> + <Result<T, F> as FromResidual<Yeet<E>>> error[E0277]: the `?` operator can only be used on `Option`s, not `Result`s, in a function that returns `Option` --> $DIR/option-to-result.rs:11:6 @@ -24,7 +26,9 @@ LL | | } | |_- this function returns an `Option` | = help: the trait `FromResidual<Result<Infallible, i32>>` is not implemented for `Option<i32>` - = help: the trait `FromResidual` is implemented for `Option<T>` + = help: the following other types implement trait `FromResidual<R>`: + <Option<T> as FromResidual<Yeet<()>>> + <Option<T> as FromResidual> error: aborting due to 2 previous errors diff --git a/src/test/ui/try-trait/try-on-option.stderr b/src/test/ui/try-trait/try-on-option.stderr index 7b2a9a16f90..ba85a7cada2 100644 --- a/src/test/ui/try-trait/try-on-option.stderr +++ b/src/test/ui/try-trait/try-on-option.stderr @@ -10,7 +10,9 @@ LL | | } | |_- this function returns a `Result` | = help: the trait `FromResidual<Option<Infallible>>` is not implemented for `Result<u32, ()>` - = help: the trait `FromResidual<Result<Infallible, E>>` is implemented for `Result<T, F>` + = help: the following other types implement trait `FromResidual<R>`: + <Result<T, F> as FromResidual<Result<Infallible, E>>> + <Result<T, F> as FromResidual<Yeet<E>>> error[E0277]: the `?` operator can only be used in a function that returns `Result` or `Option` (or another type that implements `FromResidual`) --> $DIR/try-on-option.rs:11:6 diff --git a/src/test/ui/try-trait/yeet-for-option.rs b/src/test/ui/try-trait/yeet-for-option.rs new file mode 100644 index 00000000000..753fbc1dee7 --- /dev/null +++ b/src/test/ui/try-trait/yeet-for-option.rs @@ -0,0 +1,11 @@ +// run-pass + +#![feature(yeet_expr)] + +fn always_yeet() -> Option<String> { + do yeet; +} + +fn main() { + assert_eq!(always_yeet(), None); +} diff --git a/src/test/ui/try-trait/yeet-for-result.rs b/src/test/ui/try-trait/yeet-for-result.rs new file mode 100644 index 00000000000..b7b113797cd --- /dev/null +++ b/src/test/ui/try-trait/yeet-for-result.rs @@ -0,0 +1,11 @@ +// run-pass + +#![feature(yeet_expr)] + +fn always_yeet() -> Result<i32, String> { + do yeet "hello"; +} + +fn main() { + assert_eq!(always_yeet(), Err("hello".to_string())); +} diff --git a/src/test/ui/type-alias-impl-trait/bounds-are-checked.stderr b/src/test/ui/type-alias-impl-trait/bounds-are-checked.stderr index d87ef2ec79c..920eef11da4 100644 --- a/src/test/ui/type-alias-impl-trait/bounds-are-checked.stderr +++ b/src/test/ui/type-alias-impl-trait/bounds-are-checked.stderr @@ -2,7 +2,7 @@ warning: unnecessary lifetime parameter `'a` --> $DIR/bounds-are-checked.rs:8:6 | LL | fn f<'a: 'static>(t: &'a str) -> X<'a> { - | ^^^^^^^^^^^ + | ^^ | = help: you can use the `'static` lifetime directly, in place of `'a` diff --git a/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.base.stderr b/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.base.stderr index a3b410c2cfb..593fb8af32f 100644 --- a/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.base.stderr +++ b/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.base.stderr @@ -19,10 +19,13 @@ LL | type WrongGeneric<T> = impl 'static; error[E0310]: the parameter type `T` may not live long enough --> $DIR/generic_type_does_not_live_long_enough.rs:18:5 | -LL | fn wrong_generic<T>(t: T) -> WrongGeneric<T> { - | - help: consider adding an explicit lifetime bound...: `T: 'static` LL | t | ^ ...so that the type `T` will meet its required lifetime bounds + | +help: consider adding an explicit lifetime bound... + | +LL | fn wrong_generic<T: 'static>(t: T) -> WrongGeneric<T> { + | +++++++++ error: aborting due to 3 previous errors diff --git a/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.nll.stderr b/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.nll.stderr index db771d21132..593fb8af32f 100644 --- a/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.nll.stderr +++ b/src/test/ui/type-alias-impl-trait/generic_type_does_not_live_long_enough.nll.stderr @@ -20,9 +20,12 @@ error[E0310]: the parameter type `T` may not live long enough --> $DIR/generic_type_does_not_live_long_enough.rs:18:5 | LL | t - | ^ + | ^ ...so that the type `T` will meet its required lifetime bounds | - = help: consider adding an explicit lifetime bound `T: 'static`... +help: consider adding an explicit lifetime bound... + | +LL | fn wrong_generic<T: 'static>(t: T) -> WrongGeneric<T> { + | +++++++++ error: aborting due to 3 previous errors diff --git a/src/test/ui/type-alias-impl-trait/issue-60662.stdout b/src/test/ui/type-alias-impl-trait/issue-60662.stdout index a46047d9174..5b3d7375de0 100644 --- a/src/test/ui/type-alias-impl-trait/issue-60662.stdout +++ b/src/test/ui/type-alias-impl-trait/issue-60662.stdout @@ -10,5 +10,5 @@ extern crate std; trait Animal { } fn main() { - pub type ServeFut = /*impl Trait*/; + type ServeFut = /*impl Trait*/; } diff --git a/src/test/ui/type-alias-impl-trait/nested-tait-inference.rs b/src/test/ui/type-alias-impl-trait/nested-tait-inference.rs index 314e5362a8f..82248971692 100644 --- a/src/test/ui/type-alias-impl-trait/nested-tait-inference.rs +++ b/src/test/ui/type-alias-impl-trait/nested-tait-inference.rs @@ -11,7 +11,6 @@ impl Foo<()> for () { } fn foo() -> impl Foo<FooX> { //~^ ERROR: the trait bound `(): Foo<FooX>` is not satisfied - //~| ERROR: the trait bound `(): Foo<FooX>` is not satisfied // FIXME(type-alias-impl-trait): We could probably make this work. () } diff --git a/src/test/ui/type-alias-impl-trait/nested-tait-inference.stderr b/src/test/ui/type-alias-impl-trait/nested-tait-inference.stderr index 0df2b57d373..f98da9f7f92 100644 --- a/src/test/ui/type-alias-impl-trait/nested-tait-inference.stderr +++ b/src/test/ui/type-alias-impl-trait/nested-tait-inference.stderr @@ -6,20 +6,6 @@ LL | fn foo() -> impl Foo<FooX> { | = help: the trait `Foo<()>` is implemented for `()` -error[E0277]: the trait bound `(): Foo<FooX>` is not satisfied - --> $DIR/nested-tait-inference.rs:12:28 - | -LL | fn foo() -> impl Foo<FooX> { - | ____________________________^ -LL | | -LL | | -LL | | // FIXME(type-alias-impl-trait): We could probably make this work. -LL | | () -LL | | } - | |_^ the trait `Foo<FooX>` is not implemented for `()` - | - = help: the trait `Foo<()>` is implemented for `()` - -error: aborting due to 2 previous errors +error: aborting due to previous error For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/type-alias-impl-trait/nested-tait-inference2.rs b/src/test/ui/type-alias-impl-trait/nested-tait-inference2.rs index 4dc30d9257b..0d7f5bad25f 100644 --- a/src/test/ui/type-alias-impl-trait/nested-tait-inference2.rs +++ b/src/test/ui/type-alias-impl-trait/nested-tait-inference2.rs @@ -12,7 +12,6 @@ impl Foo<u32> for () {} fn foo() -> impl Foo<FooX> { //~^ ERROR: the trait bound `(): Foo<FooX>` is not satisfied - //~| ERROR: the trait bound `(): Foo<FooX>` is not satisfied () } diff --git a/src/test/ui/type-alias-impl-trait/nested-tait-inference2.stderr b/src/test/ui/type-alias-impl-trait/nested-tait-inference2.stderr index 264e8024fac..54f571ad3e3 100644 --- a/src/test/ui/type-alias-impl-trait/nested-tait-inference2.stderr +++ b/src/test/ui/type-alias-impl-trait/nested-tait-inference2.stderr @@ -8,21 +8,6 @@ LL | fn foo() -> impl Foo<FooX> { <() as Foo<()>> <() as Foo<u32>> -error[E0277]: the trait bound `(): Foo<FooX>` is not satisfied - --> $DIR/nested-tait-inference2.rs:13:28 - | -LL | fn foo() -> impl Foo<FooX> { - | ____________________________^ -LL | | -LL | | -LL | | () -LL | | } - | |_^ the trait `Foo<FooX>` is not implemented for `()` - | - = help: the following other types implement trait `Foo<A>`: - <() as Foo<()>> - <() as Foo<u32>> - -error: aborting due to 2 previous errors +error: aborting due to previous error For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/type/type-check/missing_trait_impl.stderr b/src/test/ui/type/type-check/missing_trait_impl.stderr index 59b8692dd4d..2b58cd4180b 100644 --- a/src/test/ui/type/type-check/missing_trait_impl.stderr +++ b/src/test/ui/type/type-check/missing_trait_impl.stderr @@ -8,8 +8,8 @@ LL | let z = x + y; | help: consider restricting type parameter `T` | -LL | fn foo<T: std::ops::Add<Output = T>>(x: T, y: T) { - | +++++++++++++++++++++++++++ +LL | fn foo<T: std::ops::Add>(x: T, y: T) { + | +++++++++++++++ error[E0368]: binary assignment operation `+=` cannot be applied to type `T` --> $DIR/missing_trait_impl.rs:9:5 @@ -32,8 +32,8 @@ LL | let y = -x; | help: consider restricting type parameter `T` | -LL | fn baz<T: std::ops::Neg<Output = T>>(x: T) { - | +++++++++++++++++++++++++++ +LL | fn baz<T: std::ops::Neg>(x: T) { + | +++++++++++++++ error[E0600]: cannot apply unary operator `!` to type `T` --> $DIR/missing_trait_impl.rs:14:13 @@ -43,8 +43,8 @@ LL | let y = !x; | help: consider restricting type parameter `T` | -LL | fn baz<T: std::ops::Not<Output = T>>(x: T) { - | +++++++++++++++++++++++++++ +LL | fn baz<T: std::ops::Not>(x: T) { + | +++++++++++++++ error[E0614]: type `T` cannot be dereferenced --> $DIR/missing_trait_impl.rs:15:13 diff --git a/src/test/ui/typeck/issue-87181/empty-tuple-method.rs b/src/test/ui/typeck/issue-87181/empty-tuple-method.rs new file mode 100644 index 00000000000..1875d8280cb --- /dev/null +++ b/src/test/ui/typeck/issue-87181/empty-tuple-method.rs @@ -0,0 +1,14 @@ +struct Bar<T> { + bar: T +} + +struct Foo(); +impl Foo { + fn foo() { } +} + +fn main() { + let thing = Bar { bar: Foo }; + thing.bar.foo(); + //~^ ERROR no method named `foo` found for fn item `fn() -> Foo {Foo}` in the current scope [E0599] +} diff --git a/src/test/ui/typeck/issue-87181/empty-tuple-method.stderr b/src/test/ui/typeck/issue-87181/empty-tuple-method.stderr new file mode 100644 index 00000000000..6ed70b301e4 --- /dev/null +++ b/src/test/ui/typeck/issue-87181/empty-tuple-method.stderr @@ -0,0 +1,16 @@ +error[E0599]: no method named `foo` found for fn item `fn() -> Foo {Foo}` in the current scope + --> $DIR/empty-tuple-method.rs:12:15 + | +LL | thing.bar.foo(); + | --------- ^^^ method not found in `fn() -> Foo {Foo}` + | | + | this is the constructor of a struct + | +help: call the constructor + | +LL | (thing.bar)().foo(); + | + +++ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0599`. diff --git a/src/test/ui/typeck/issue-87181/enum-variant.rs b/src/test/ui/typeck/issue-87181/enum-variant.rs new file mode 100644 index 00000000000..3b926b90f10 --- /dev/null +++ b/src/test/ui/typeck/issue-87181/enum-variant.rs @@ -0,0 +1,16 @@ +struct Bar<T> { + bar: T +} + +enum Foo{ + Tup() +} +impl Foo { + fn foo() { } +} + +fn main() { + let thing = Bar { bar: Foo::Tup }; + thing.bar.foo(); + //~^ ERROR no method named `foo` found for fn item `fn() -> Foo {Foo::Tup}` in the current scope [E0599] +} diff --git a/src/test/ui/typeck/issue-87181/enum-variant.stderr b/src/test/ui/typeck/issue-87181/enum-variant.stderr new file mode 100644 index 00000000000..a3a818696ab --- /dev/null +++ b/src/test/ui/typeck/issue-87181/enum-variant.stderr @@ -0,0 +1,16 @@ +error[E0599]: no method named `foo` found for fn item `fn() -> Foo {Foo::Tup}` in the current scope + --> $DIR/enum-variant.rs:14:15 + | +LL | thing.bar.foo(); + | --------- ^^^ method not found in `fn() -> Foo {Foo::Tup}` + | | + | this is the constructor of an enum variant + | +help: call the constructor + | +LL | (thing.bar)().foo(); + | + +++ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0599`. diff --git a/src/test/ui/typeck/issue-87181/tuple-field.rs b/src/test/ui/typeck/issue-87181/tuple-field.rs new file mode 100644 index 00000000000..00e3b460ecf --- /dev/null +++ b/src/test/ui/typeck/issue-87181/tuple-field.rs @@ -0,0 +1,14 @@ +struct Bar<T> { + bar: T +} + +struct Foo(char, u16); +impl Foo { + fn foo() { } +} + +fn main() { + let thing = Bar { bar: Foo }; + thing.bar.0; + //~^ ERROR no field `0` on type `fn(char, u16) -> Foo {Foo}` [E0609] +} diff --git a/src/test/ui/typeck/issue-87181/tuple-field.stderr b/src/test/ui/typeck/issue-87181/tuple-field.stderr new file mode 100644 index 00000000000..4d22ada0247 --- /dev/null +++ b/src/test/ui/typeck/issue-87181/tuple-field.stderr @@ -0,0 +1,16 @@ +error[E0609]: no field `0` on type `fn(char, u16) -> Foo {Foo}` + --> $DIR/tuple-field.rs:12:15 + | +LL | thing.bar.0; + | --------- ^ + | | + | this is the constructor of a struct + | +help: call the constructor + | +LL | (thing.bar)(_, _).0; + | + +++++++ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0609`. diff --git a/src/test/ui/typeck/issue-87181/tuple-method.rs b/src/test/ui/typeck/issue-87181/tuple-method.rs new file mode 100644 index 00000000000..e88f642b070 --- /dev/null +++ b/src/test/ui/typeck/issue-87181/tuple-method.rs @@ -0,0 +1,14 @@ +struct Bar<T> { + bar: T +} + +struct Foo(u8, i32); +impl Foo { + fn foo() { } +} + +fn main() { + let thing = Bar { bar: Foo }; + thing.bar.foo(); + //~^ ERROR no method named `foo` found for fn item `fn(u8, i32) -> Foo {Foo}` in the current scope [E0599] +} diff --git a/src/test/ui/typeck/issue-87181/tuple-method.stderr b/src/test/ui/typeck/issue-87181/tuple-method.stderr new file mode 100644 index 00000000000..1e392e17984 --- /dev/null +++ b/src/test/ui/typeck/issue-87181/tuple-method.stderr @@ -0,0 +1,16 @@ +error[E0599]: no method named `foo` found for fn item `fn(u8, i32) -> Foo {Foo}` in the current scope + --> $DIR/tuple-method.rs:12:15 + | +LL | thing.bar.foo(); + | --------- ^^^ method not found in `fn(u8, i32) -> Foo {Foo}` + | | + | this is the constructor of a struct + | +help: call the constructor + | +LL | (thing.bar)(_, _).foo(); + | + +++++++ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0599`. diff --git a/src/test/ui/typeck/typeck-default-trait-impl-cross-crate-coherence.stderr b/src/test/ui/typeck/typeck-default-trait-impl-cross-crate-coherence.stderr index cf5c15df705..fc3778b7967 100644 --- a/src/test/ui/typeck/typeck-default-trait-impl-cross-crate-coherence.stderr +++ b/src/test/ui/typeck/typeck-default-trait-impl-cross-crate-coherence.stderr @@ -26,7 +26,7 @@ error[E0321]: cross-crate traits with a default impl, like `DefaultedTrait`, can LL | impl DefaultedTrait for Box<C> { } | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can't implement cross-crate trait for type in another crate -error[E0117]: only traits defined in the current crate can be implemented for arbitrary types +error[E0117]: only traits defined in the current crate can be implemented for types defined outside of the crate --> $DIR/typeck-default-trait-impl-cross-crate-coherence.rs:22:1 | LL | impl DefaultedTrait for lib::Something<C> { } diff --git a/src/test/ui/typeck/typeck_type_placeholder_item.rs b/src/test/ui/typeck/typeck_type_placeholder_item.rs index ca0876be58d..22fedb22d66 100644 --- a/src/test/ui/typeck/typeck_type_placeholder_item.rs +++ b/src/test/ui/typeck/typeck_type_placeholder_item.rs @@ -57,7 +57,7 @@ unsafe fn test12(x: *const usize) -> *const *const _ { impl Clone for Test9 { fn clone(&self) -> _ { Test9 } - //~^ ERROR the placeholder `_` is not allowed within types on item signatures for return types + //~^ ERROR the placeholder `_` is not allowed within types on item signatures for functions fn clone_from(&mut self, other: _) { *self = Test9; } //~^ ERROR the placeholder `_` is not allowed within types on item signatures for functions @@ -113,7 +113,7 @@ pub fn main() { impl Clone for FnTest9 { fn clone(&self) -> _ { FnTest9 } - //~^ ERROR the placeholder `_` is not allowed within types on item signatures for return types + //~^ ERROR the placeholder `_` is not allowed within types on item signatures for functions fn clone_from(&mut self, other: _) { *self = FnTest9; } //~^ ERROR the placeholder `_` is not allowed within types on item signatures for functions diff --git a/src/test/ui/typeck/typeck_type_placeholder_item.stderr b/src/test/ui/typeck/typeck_type_placeholder_item.stderr index c07b96f9a97..3ea317dfb1a 100644 --- a/src/test/ui/typeck/typeck_type_placeholder_item.stderr +++ b/src/test/ui/typeck/typeck_type_placeholder_item.stderr @@ -545,14 +545,16 @@ help: use type parameters instead LL | fn test10<T>(&self, _x : T) { } | +++ ~ -error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types +error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions --> $DIR/typeck_type_placeholder_item.rs:59:24 | LL | fn clone(&self) -> _ { Test9 } - | ^ - | | - | not allowed in type signatures - | help: replace with the correct return type: `Test9` + | ^ not allowed in type signatures + | +help: try replacing `_` with the type in the corresponding trait method signature + | +LL | fn clone(&self) -> Test9 { Test9 } + | ~~~~~ error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions --> $DIR/typeck_type_placeholder_item.rs:62:37 @@ -560,10 +562,10 @@ error[E0121]: the placeholder `_` is not allowed within types on item signatures LL | fn clone_from(&mut self, other: _) { *self = Test9; } | ^ not allowed in type signatures | -help: use type parameters instead +help: try replacing `_` with the type in the corresponding trait method signature | -LL | fn clone_from<T>(&mut self, other: T) { *self = Test9; } - | +++ ~ +LL | fn clone_from(&mut self, other: &Test9) { *self = Test9; } + | ~~~~~~ error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types --> $DIR/typeck_type_placeholder_item.rs:107:31 @@ -585,14 +587,16 @@ help: use type parameters instead LL | fn fn_test10<T>(&self, _x : T) { } | +++ ~ -error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types +error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions --> $DIR/typeck_type_placeholder_item.rs:115:28 | LL | fn clone(&self) -> _ { FnTest9 } - | ^ - | | - | not allowed in type signatures - | help: replace with the correct return type: `FnTest9` + | ^ not allowed in type signatures + | +help: try replacing `_` with the type in the corresponding trait method signature + | +LL | fn clone(&self) -> FnTest9 { FnTest9 } + | ~~~~~~~ error[E0121]: the placeholder `_` is not allowed within types on item signatures for functions --> $DIR/typeck_type_placeholder_item.rs:118:41 @@ -600,10 +604,10 @@ error[E0121]: the placeholder `_` is not allowed within types on item signatures LL | fn clone_from(&mut self, other: _) { *self = FnTest9; } | ^ not allowed in type signatures | -help: use type parameters instead +help: try replacing `_` with the type in the corresponding trait method signature | -LL | fn clone_from<T>(&mut self, other: T) { *self = FnTest9; } - | +++ ~ +LL | fn clone_from(&mut self, other: &FnTest9) { *self = FnTest9; } + | ~~~~~~~~ error[E0121]: the placeholder `_` is not allowed within types on item signatures for associated types --> $DIR/typeck_type_placeholder_item.rs:201:14 diff --git a/src/test/ui/unboxed-closures/unboxed-closures-static-call-wrong-trait.stderr b/src/test/ui/unboxed-closures/unboxed-closures-static-call-wrong-trait.stderr index 0b6d94e71f0..e9883903674 100644 --- a/src/test/ui/unboxed-closures/unboxed-closures-static-call-wrong-trait.stderr +++ b/src/test/ui/unboxed-closures/unboxed-closures-static-call-wrong-trait.stderr @@ -2,9 +2,9 @@ error[E0599]: no method named `call` found for closure `[closure@$DIR/unboxed-cl --> $DIR/unboxed-closures-static-call-wrong-trait.rs:7:10 | LL | mut_.call((0, )); - | ^^^^ method not found in `[closure@$DIR/unboxed-closures-static-call-wrong-trait.rs:6:26: 6:31]` - | - = note: `mut_` is a function, perhaps you wish to call it + | ---- ^^^^ method not found in `[closure@$DIR/unboxed-closures-static-call-wrong-trait.rs:6:26: 6:31]` + | | + | this is a function, perhaps you wish to call it error: aborting due to previous error diff --git a/src/test/ui/underscore-lifetime/dyn-trait-underscore.nll.stderr b/src/test/ui/underscore-lifetime/dyn-trait-underscore.nll.stderr index 53d45f6a8f2..0ffb77cf021 100644 --- a/src/test/ui/underscore-lifetime/dyn-trait-underscore.nll.stderr +++ b/src/test/ui/underscore-lifetime/dyn-trait-underscore.nll.stderr @@ -6,6 +6,11 @@ LL | fn a<T>(items: &[T]) -> Box<dyn Iterator<Item=&T>> { LL | // ^^^^^^^^^^^^^^^^^^^^^ bound *here* defaults to `'static` LL | Box::new(items.iter()) | ^^^^^^^^^^^^^^^^^^^^^^ returning this value requires that `'1` must outlive `'static` + | +help: to declare that the trait object captures data from argument `items`, you can add an explicit `'_` lifetime bound + | +LL | fn a<T>(items: &[T]) -> Box<dyn Iterator<Item=&T> + '_> { + | ++++ error: aborting due to previous error diff --git a/src/test/ui/underscore-lifetime/underscore-lifetime-elison-mismatch.nll.stderr b/src/test/ui/underscore-lifetime/underscore-lifetime-elison-mismatch.nll.stderr index 8e10242cb13..a4dece320ec 100644 --- a/src/test/ui/underscore-lifetime/underscore-lifetime-elison-mismatch.nll.stderr +++ b/src/test/ui/underscore-lifetime/underscore-lifetime-elison-mismatch.nll.stderr @@ -6,6 +6,11 @@ LL | fn foo(x: &mut Vec<&'_ u8>, y: &'_ u8) { x.push(y); } | | | | | let's call the lifetime of this reference `'1` | let's call the lifetime of this reference `'2` + | +help: consider introducing a named lifetime parameter + | +LL | fn foo<'a>(x: &mut Vec<&'a u8>, y: &'a u8) { x.push(y); } + | ++++ ~~ ~~ error: aborting due to previous error diff --git a/src/test/ui/uninhabited/privately-uninhabited-mir-call.rs b/src/test/ui/uninhabited/privately-uninhabited-mir-call.rs new file mode 100644 index 00000000000..b37ec2696de --- /dev/null +++ b/src/test/ui/uninhabited/privately-uninhabited-mir-call.rs @@ -0,0 +1,29 @@ +// Verifies that MIR building for a call expression respects +// privacy when checking if a call return type is uninhabited. + +pub mod widget { + enum Unimplemented {} + pub struct Widget(Unimplemented); + + impl Widget { + pub fn new() -> Widget { + todo!(); + } + } + + pub fn f() { + let x: &mut u32; + Widget::new(); + // Ok. Widget type returned from new is known to be uninhabited + // and the following code is considered unreachable. + *x = 1; + } +} + +fn main() { + let y: &mut u32; + widget::Widget::new(); + // Error. Widget type is not known to be uninhabited here, + // so the following code is considered reachable. + *y = 2; //~ ERROR use of possibly-uninitialized variable +} diff --git a/src/test/ui/uninhabited/privately-uninhabited-mir-call.stderr b/src/test/ui/uninhabited/privately-uninhabited-mir-call.stderr new file mode 100644 index 00000000000..fb195341168 --- /dev/null +++ b/src/test/ui/uninhabited/privately-uninhabited-mir-call.stderr @@ -0,0 +1,9 @@ +error[E0381]: use of possibly-uninitialized variable: `y` + --> $DIR/privately-uninhabited-mir-call.rs:28:5 + | +LL | *y = 2; + | ^^^^^^ use of possibly-uninitialized `y` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0381`. diff --git a/src/test/ui/unsafe/issue-45087-unreachable-unsafe.mir.stderr b/src/test/ui/unsafe/issue-45087-unreachable-unsafe.mir.stderr index 33f762ccf63..e7960960774 100644 --- a/src/test/ui/unsafe/issue-45087-unreachable-unsafe.mir.stderr +++ b/src/test/ui/unsafe/issue-45087-unreachable-unsafe.mir.stderr @@ -1,11 +1,27 @@ error[E0133]: dereference of raw pointer is unsafe and requires unsafe function or block - --> $DIR/issue-45087-unreachable-unsafe.rs:6:5 + --> $DIR/issue-45087-unreachable-unsafe.rs:7:5 | LL | *(1 as *mut u32) = 42; | ^^^^^^^^^^^^^^^^^^^^^ dereference of raw pointer | = note: raw pointers may be null, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior -error: aborting due to previous error +error[E0133]: dereference of raw pointer is unsafe and requires unsafe function or block + --> $DIR/issue-45087-unreachable-unsafe.rs:17:5 + | +LL | *a = 1; + | ^^^^^^ dereference of raw pointer + | + = note: raw pointers may be null, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior + +error[E0133]: dereference of raw pointer is unsafe and requires unsafe function or block + --> $DIR/issue-45087-unreachable-unsafe.rs:29:5 + | +LL | *b = 1; + | ^^^^^^ dereference of raw pointer + | + = note: raw pointers may be null, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior + +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0133`. diff --git a/src/test/ui/unsafe/issue-45087-unreachable-unsafe.rs b/src/test/ui/unsafe/issue-45087-unreachable-unsafe.rs index 071cea8fbd7..3e3da667c0b 100644 --- a/src/test/ui/unsafe/issue-45087-unreachable-unsafe.rs +++ b/src/test/ui/unsafe/issue-45087-unreachable-unsafe.rs @@ -1,3 +1,4 @@ +// Verify that unreachable code undergoes unsafety checks. // revisions: mir thir // [thir]compile-flags: -Z thir-unsafeck @@ -6,3 +7,25 @@ fn main() { *(1 as *mut u32) = 42; //~^ ERROR dereference of raw pointer is unsafe } + +fn panic() -> ! { + panic!(); +} + +fn f(a: *mut u32) { + panic(); + *a = 1; + //~^ ERROR dereference of raw pointer is unsafe +} + +enum Void {} + +fn uninhabited() -> Void { + panic!(); +} + +fn g(b: *mut u32) { + uninhabited(); + *b = 1; + //~^ ERROR dereference of raw pointer is unsafe +} diff --git a/src/test/ui/unsafe/issue-45087-unreachable-unsafe.thir.stderr b/src/test/ui/unsafe/issue-45087-unreachable-unsafe.thir.stderr index 73a113652b8..e81adad4507 100644 --- a/src/test/ui/unsafe/issue-45087-unreachable-unsafe.thir.stderr +++ b/src/test/ui/unsafe/issue-45087-unreachable-unsafe.thir.stderr @@ -1,11 +1,27 @@ error[E0133]: dereference of raw pointer is unsafe and requires unsafe function or block - --> $DIR/issue-45087-unreachable-unsafe.rs:6:5 + --> $DIR/issue-45087-unreachable-unsafe.rs:7:5 | LL | *(1 as *mut u32) = 42; | ^^^^^^^^^^^^^^^^ dereference of raw pointer | = note: raw pointers may be null, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior -error: aborting due to previous error +error[E0133]: dereference of raw pointer is unsafe and requires unsafe function or block + --> $DIR/issue-45087-unreachable-unsafe.rs:17:5 + | +LL | *a = 1; + | ^^ dereference of raw pointer + | + = note: raw pointers may be null, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior + +error[E0133]: dereference of raw pointer is unsafe and requires unsafe function or block + --> $DIR/issue-45087-unreachable-unsafe.rs:29:5 + | +LL | *b = 1; + | ^^ dereference of raw pointer + | + = note: raw pointers may be null, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior + +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0133`. diff --git a/src/test/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.mir.stderr b/src/test/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.mir.stderr index 163c101772c..fd58e1b1ebe 100644 --- a/src/test/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.mir.stderr +++ b/src/test/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.mir.stderr @@ -12,7 +12,7 @@ LL | #![deny(unsafe_op_in_unsafe_fn)] = note: consult the function's documentation for information on how to avoid undefined behavior error: dereference of raw pointer is unsafe and requires unsafe block (error E0133) - --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:14:5 + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:15:5 | LL | *PTR; | ^^^^ dereference of raw pointer @@ -20,7 +20,7 @@ LL | *PTR; = note: raw pointers may be null, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior error: use of mutable static is unsafe and requires unsafe block (error E0133) - --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:16:5 + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:17:5 | LL | VOID = (); | ^^^^^^^^^ use of mutable static @@ -28,7 +28,7 @@ LL | VOID = (); = note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior error: unnecessary `unsafe` block - --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:19:5 + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:20:5 | LL | unsafe {} | ^^^^^^ unnecessary `unsafe` block @@ -40,13 +40,13 @@ LL | #![deny(unused_unsafe)] | ^^^^^^^^^^^^^ error: call to unsafe function is unsafe and requires unsafe block (error E0133) - --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:27:5 + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:28:5 | LL | unsf(); | ^^^^^^ call to unsafe function | note: the lint level is defined here - --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:25:8 + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:26:8 | LL | #[deny(warnings)] | ^^^^^^^^ @@ -54,7 +54,7 @@ LL | #[deny(warnings)] = note: consult the function's documentation for information on how to avoid undefined behavior error: dereference of raw pointer is unsafe and requires unsafe block (error E0133) - --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:29:5 + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:31:5 | LL | *PTR; | ^^^^ dereference of raw pointer @@ -62,7 +62,7 @@ LL | *PTR; = note: raw pointers may be null, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior error: use of mutable static is unsafe and requires unsafe block (error E0133) - --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:31:5 + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:33:5 | LL | VOID = (); | ^^^^^^^^^ use of mutable static @@ -70,19 +70,19 @@ LL | VOID = (); = note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior error: unnecessary `unsafe` block - --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:33:5 + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:35:5 | LL | unsafe {} | ^^^^^^ unnecessary `unsafe` block error: unnecessary `unsafe` block - --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:47:5 + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:49:5 | LL | unsafe { unsafe { unsf() } } | ^^^^^^ unnecessary `unsafe` block error: unnecessary `unsafe` block - --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:58:5 + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:60:5 | LL | unsafe fn allow_level() { | ----------------------- because it's nested under this `unsafe` fn @@ -92,13 +92,13 @@ LL | unsafe { unsf() } | = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn` note: the lint level is defined here - --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:51:9 + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:53:9 | LL | #[allow(unsafe_op_in_unsafe_fn)] | ^^^^^^^^^^^^^^^^^^^^^^ error: unnecessary `unsafe` block - --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:70:9 + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:72:9 | LL | unsafe fn nested_allow_level() { | ------------------------------ because it's nested under this `unsafe` fn @@ -108,13 +108,13 @@ LL | unsafe { unsf() } | = note: this `unsafe` block does contain unsafe operations, but those are already allowed in an `unsafe fn` note: the lint level is defined here - --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:63:13 + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:65:13 | LL | #[allow(unsafe_op_in_unsafe_fn)] | ^^^^^^^^^^^^^^^^^^^^^^ error[E0133]: call to unsafe function is unsafe and requires unsafe block - --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:76:5 + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:78:5 | LL | unsf(); | ^^^^^^ call to unsafe function @@ -122,7 +122,7 @@ LL | unsf(); = note: consult the function's documentation for information on how to avoid undefined behavior error[E0133]: call to unsafe function is unsafe and requires unsafe function or block - --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:80:9 + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:83:9 | LL | unsf(); | ^^^^^^ call to unsafe function diff --git a/src/test/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.rs b/src/test/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.rs index 7ca714b85c2..30b07234034 100644 --- a/src/test/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.rs +++ b/src/test/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.rs @@ -10,7 +10,8 @@ static mut VOID: () = (); unsafe fn deny_level() { unsf(); - //~^ ERROR call to unsafe function is unsafe and requires unsafe block + //[mir]~^ ERROR call to unsafe function is unsafe and requires unsafe block + //[thir]~^^ ERROR call to unsafe function `unsf` is unsafe and requires unsafe block *PTR; //~^ ERROR dereference of raw pointer is unsafe and requires unsafe block VOID = (); @@ -25,7 +26,8 @@ unsafe fn deny_level() { #[deny(warnings)] unsafe fn warning_level() { unsf(); - //~^ ERROR call to unsafe function is unsafe and requires unsafe block + //[mir]~^ ERROR call to unsafe function is unsafe and requires unsafe block + //[thir]~^^ ERROR call to unsafe function `unsf` is unsafe and requires unsafe block *PTR; //~^ ERROR dereference of raw pointer is unsafe and requires unsafe block VOID = (); @@ -74,10 +76,12 @@ unsafe fn nested_allow_level() { fn main() { unsf(); - //~^ ERROR call to unsafe function is unsafe and requires unsafe block + //[mir]~^ ERROR call to unsafe function is unsafe and requires unsafe block + //[thir]~^^ ERROR call to unsafe function `unsf` is unsafe and requires unsafe block #[allow(unsafe_op_in_unsafe_fn)] { unsf(); - //~^ ERROR call to unsafe function is unsafe and requires unsafe function or block + //[mir]~^ ERROR call to unsafe function is unsafe and requires unsafe function or block + //[thir]~^^ ERROR call to unsafe function `unsf` is unsafe and requires unsafe function or block } } diff --git a/src/test/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.thir.stderr b/src/test/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.thir.stderr index ad87690bb52..2ba6a72930d 100644 --- a/src/test/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.thir.stderr +++ b/src/test/ui/unsafe/rfc-2585-unsafe_op_in_unsafe_fn.thir.stderr @@ -1,4 +1,4 @@ -error: call to unsafe function is unsafe and requires unsafe block (error E0133) +error: call to unsafe function `unsf` is unsafe and requires unsafe block (error E0133) --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:12:5 | LL | unsf(); @@ -12,7 +12,7 @@ LL | #![deny(unsafe_op_in_unsafe_fn)] = note: consult the function's documentation for information on how to avoid undefined behavior error: dereference of raw pointer is unsafe and requires unsafe block (error E0133) - --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:14:5 + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:15:5 | LL | *PTR; | ^^^^ dereference of raw pointer @@ -20,7 +20,7 @@ LL | *PTR; = note: raw pointers may be null, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior error: use of mutable static is unsafe and requires unsafe block (error E0133) - --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:16:5 + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:17:5 | LL | VOID = (); | ^^^^ use of mutable static @@ -28,7 +28,7 @@ LL | VOID = (); = note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior error: unnecessary `unsafe` block - --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:19:5 + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:20:5 | LL | unsafe {} | ^^^^^^ unnecessary `unsafe` block @@ -39,14 +39,14 @@ note: the lint level is defined here LL | #![deny(unused_unsafe)] | ^^^^^^^^^^^^^ -error: call to unsafe function is unsafe and requires unsafe block (error E0133) - --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:27:5 +error: call to unsafe function `unsf` is unsafe and requires unsafe block (error E0133) + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:28:5 | LL | unsf(); | ^^^^^^ call to unsafe function | note: the lint level is defined here - --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:25:8 + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:26:8 | LL | #[deny(warnings)] | ^^^^^^^^ @@ -54,7 +54,7 @@ LL | #[deny(warnings)] = note: consult the function's documentation for information on how to avoid undefined behavior error: dereference of raw pointer is unsafe and requires unsafe block (error E0133) - --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:29:5 + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:31:5 | LL | *PTR; | ^^^^ dereference of raw pointer @@ -62,7 +62,7 @@ LL | *PTR; = note: raw pointers may be null, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior error: use of mutable static is unsafe and requires unsafe block (error E0133) - --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:31:5 + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:33:5 | LL | VOID = (); | ^^^^ use of mutable static @@ -70,13 +70,13 @@ LL | VOID = (); = note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior error: unnecessary `unsafe` block - --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:33:5 + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:35:5 | LL | unsafe {} | ^^^^^^ unnecessary `unsafe` block error: unnecessary `unsafe` block - --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:47:14 + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:49:14 | LL | unsafe { unsafe { unsf() } } | ------ ^^^^^^ unnecessary `unsafe` block @@ -84,7 +84,7 @@ LL | unsafe { unsafe { unsf() } } | because it's nested under this `unsafe` block error: unnecessary `unsafe` block - --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:58:5 + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:60:5 | LL | unsafe fn allow_level() { | ----------------------- because it's nested under this `unsafe` fn @@ -93,7 +93,7 @@ LL | unsafe { unsf() } | ^^^^^^ unnecessary `unsafe` block error: unnecessary `unsafe` block - --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:70:9 + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:72:9 | LL | unsafe fn nested_allow_level() { | ------------------------------ because it's nested under this `unsafe` fn @@ -101,16 +101,16 @@ LL | unsafe fn nested_allow_level() { LL | unsafe { unsf() } | ^^^^^^ unnecessary `unsafe` block -error[E0133]: call to unsafe function is unsafe and requires unsafe block - --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:76:5 +error[E0133]: call to unsafe function `unsf` is unsafe and requires unsafe block + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:78:5 | LL | unsf(); | ^^^^^^ call to unsafe function | = note: consult the function's documentation for information on how to avoid undefined behavior -error[E0133]: call to unsafe function is unsafe and requires unsafe function or block - --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:80:9 +error[E0133]: call to unsafe function `unsf` is unsafe and requires unsafe function or block + --> $DIR/rfc-2585-unsafe_op_in_unsafe_fn.rs:83:9 | LL | unsf(); | ^^^^^^ call to unsafe function diff --git a/src/test/ui/unsafe/unsafe-const-fn.thir.stderr b/src/test/ui/unsafe/unsafe-const-fn.thir.stderr index 3031be720f0..1a77adf4459 100644 --- a/src/test/ui/unsafe/unsafe-const-fn.thir.stderr +++ b/src/test/ui/unsafe/unsafe-const-fn.thir.stderr @@ -1,4 +1,4 @@ -error[E0133]: call to unsafe function is unsafe and requires unsafe function or block +error[E0133]: call to unsafe function `dummy` is unsafe and requires unsafe function or block --> $DIR/unsafe-const-fn.rs:10:18 | LL | const VAL: u32 = dummy(0xFFFF); diff --git a/src/test/ui/unsafe/unsafe-fn-called-from-safe.rs b/src/test/ui/unsafe/unsafe-fn-called-from-safe.rs index df12e441516..55072dcc6c3 100644 --- a/src/test/ui/unsafe/unsafe-fn-called-from-safe.rs +++ b/src/test/ui/unsafe/unsafe-fn-called-from-safe.rs @@ -4,5 +4,7 @@ unsafe fn f() { return; } fn main() { - f(); //~ ERROR call to unsafe function is unsafe + f(); + //[mir]~^ ERROR call to unsafe function is unsafe + //[thir]~^^ ERROR call to unsafe function `f` is unsafe } diff --git a/src/test/ui/unsafe/unsafe-fn-called-from-safe.thir.stderr b/src/test/ui/unsafe/unsafe-fn-called-from-safe.thir.stderr index 1d6fa4cbf40..206dbd90a75 100644 --- a/src/test/ui/unsafe/unsafe-fn-called-from-safe.thir.stderr +++ b/src/test/ui/unsafe/unsafe-fn-called-from-safe.thir.stderr @@ -1,4 +1,4 @@ -error[E0133]: call to unsafe function is unsafe and requires unsafe function or block +error[E0133]: call to unsafe function `f` is unsafe and requires unsafe function or block --> $DIR/unsafe-fn-called-from-safe.rs:7:5 | LL | f(); diff --git a/src/test/ui/unsafe/unsafe-fn-used-as-value.rs b/src/test/ui/unsafe/unsafe-fn-used-as-value.rs index 2af0786617b..9517598c7ce 100644 --- a/src/test/ui/unsafe/unsafe-fn-used-as-value.rs +++ b/src/test/ui/unsafe/unsafe-fn-used-as-value.rs @@ -5,5 +5,7 @@ unsafe fn f() { return; } fn main() { let x = f; - x(); //~ ERROR call to unsafe function is unsafe + x(); + //[mir]~^ ERROR call to unsafe function is unsafe + //[thir]~^^ ERROR call to unsafe function `f` is unsafe } diff --git a/src/test/ui/unsafe/unsafe-fn-used-as-value.thir.stderr b/src/test/ui/unsafe/unsafe-fn-used-as-value.thir.stderr index b08a7109dda..e81dd3b2b41 100644 --- a/src/test/ui/unsafe/unsafe-fn-used-as-value.thir.stderr +++ b/src/test/ui/unsafe/unsafe-fn-used-as-value.thir.stderr @@ -1,4 +1,4 @@ -error[E0133]: call to unsafe function is unsafe and requires unsafe function or block +error[E0133]: call to unsafe function `f` is unsafe and requires unsafe function or block --> $DIR/unsafe-fn-used-as-value.rs:8:5 | LL | x(); diff --git a/src/test/ui/unused-crate-deps/deny-attr.rs b/src/test/ui/unused-crate-deps/deny-attr.rs new file mode 100644 index 00000000000..e9ab18ff63f --- /dev/null +++ b/src/test/ui/unused-crate-deps/deny-attr.rs @@ -0,0 +1,9 @@ +// Check for unused crate dep, no path + +// edition:2018 +// aux-crate:bar=bar.rs + +#![deny(unused_crate_dependencies)] +//~^ ERROR external crate `bar` unused in + +fn main() {} diff --git a/src/test/ui/unused-crate-deps/deny-attr.stderr b/src/test/ui/unused-crate-deps/deny-attr.stderr new file mode 100644 index 00000000000..93694f6827f --- /dev/null +++ b/src/test/ui/unused-crate-deps/deny-attr.stderr @@ -0,0 +1,14 @@ +error: external crate `bar` unused in `deny_attr`: remove the dependency or add `use bar as _;` + --> $DIR/deny-attr.rs:6:1 + | +LL | #![deny(unused_crate_dependencies)] + | ^ + | +note: the lint level is defined here + --> $DIR/deny-attr.rs:6:9 + | +LL | #![deny(unused_crate_dependencies)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/unused-crate-deps/deny-cmdline-json-silent.rs b/src/test/ui/unused-crate-deps/deny-cmdline-json-silent.rs new file mode 100644 index 00000000000..fd9a61d6caa --- /dev/null +++ b/src/test/ui/unused-crate-deps/deny-cmdline-json-silent.rs @@ -0,0 +1,8 @@ +// Check for unused crate dep, json event, deny but we're not reporting that in exit status + +// edition:2018 +// check-pass +// compile-flags: -Dunused-crate-dependencies -Zunstable-options --json unused-externs-silent --error-format=json +// aux-crate:bar=bar.rs + +fn main() {} diff --git a/src/test/ui/unused-crate-deps/deny-cmdline-json-silent.stderr b/src/test/ui/unused-crate-deps/deny-cmdline-json-silent.stderr new file mode 100644 index 00000000000..595619f3a8a --- /dev/null +++ b/src/test/ui/unused-crate-deps/deny-cmdline-json-silent.stderr @@ -0,0 +1 @@ +{"lint_level":"deny","unused_extern_names":["bar"]} diff --git a/src/test/ui/unused-crate-deps/deny-cmdline-json.rs b/src/test/ui/unused-crate-deps/deny-cmdline-json.rs new file mode 100644 index 00000000000..2b369dee5a0 --- /dev/null +++ b/src/test/ui/unused-crate-deps/deny-cmdline-json.rs @@ -0,0 +1,7 @@ +// Check for unused crate dep, json event, deny, expect compile failure + +// edition:2018 +// compile-flags: -Dunused-crate-dependencies -Zunstable-options --json unused-externs --error-format=json +// aux-crate:bar=bar.rs + +fn main() {} diff --git a/src/test/ui/unused-crate-deps/deny-cmdline-json.stderr b/src/test/ui/unused-crate-deps/deny-cmdline-json.stderr new file mode 100644 index 00000000000..595619f3a8a --- /dev/null +++ b/src/test/ui/unused-crate-deps/deny-cmdline-json.stderr @@ -0,0 +1 @@ +{"lint_level":"deny","unused_extern_names":["bar"]} diff --git a/src/test/ui/unused-crate-deps/deny-cmdline.rs b/src/test/ui/unused-crate-deps/deny-cmdline.rs new file mode 100644 index 00000000000..69e28b3319a --- /dev/null +++ b/src/test/ui/unused-crate-deps/deny-cmdline.rs @@ -0,0 +1,8 @@ +// Check for unused crate dep, deny, expect failure + +// edition:2018 +// compile-flags: -Dunused-crate-dependencies +// aux-crate:bar=bar.rs + +fn main() {} +//~^ ERROR external crate `bar` unused in diff --git a/src/test/ui/unused-crate-deps/deny-cmdline.stderr b/src/test/ui/unused-crate-deps/deny-cmdline.stderr new file mode 100644 index 00000000000..0951dc670fe --- /dev/null +++ b/src/test/ui/unused-crate-deps/deny-cmdline.stderr @@ -0,0 +1,10 @@ +error: external crate `bar` unused in `deny_cmdline`: remove the dependency or add `use bar as _;` + --> $DIR/deny-cmdline.rs:7:1 + | +LL | fn main() {} + | ^ + | + = note: requested on the command line with `-D unused-crate-dependencies` + +error: aborting due to previous error + diff --git a/src/test/ui/unused-crate-deps/warn-cmdline-json.rs b/src/test/ui/unused-crate-deps/warn-cmdline-json.rs new file mode 100644 index 00000000000..4826c0062d0 --- /dev/null +++ b/src/test/ui/unused-crate-deps/warn-cmdline-json.rs @@ -0,0 +1,8 @@ +// Check for unused crate dep, warn, json event, expect pass + +// edition:2018 +// check-pass +// compile-flags: -Wunused-crate-dependencies -Zunstable-options --json unused-externs --error-format=json +// aux-crate:bar=bar.rs + +fn main() {} diff --git a/src/test/ui/unused-crate-deps/warn-cmdline-json.stderr b/src/test/ui/unused-crate-deps/warn-cmdline-json.stderr new file mode 100644 index 00000000000..98dbd763927 --- /dev/null +++ b/src/test/ui/unused-crate-deps/warn-cmdline-json.stderr @@ -0,0 +1 @@ +{"lint_level":"warn","unused_extern_names":["bar"]} diff --git a/src/test/ui/wf/wf-impl-associated-type-region.stderr b/src/test/ui/wf/wf-impl-associated-type-region.stderr index 3f324190b7b..b9d4857a3ef 100644 --- a/src/test/ui/wf/wf-impl-associated-type-region.stderr +++ b/src/test/ui/wf/wf-impl-associated-type-region.stderr @@ -1,10 +1,13 @@ error[E0309]: the parameter type `T` may not live long enough --> $DIR/wf-impl-associated-type-region.rs:10:16 | -LL | impl<'a, T> Foo<'a> for T { - | - help: consider adding an explicit lifetime bound...: `T: 'a` LL | type Bar = &'a T; | ^^^^^ ...so that the reference type `&'a T` does not outlive the data it points at + | +help: consider adding an explicit lifetime bound... + | +LL | impl<'a, T: 'a> Foo<'a> for T { + | ++++ error: aborting due to previous error diff --git a/src/test/ui/wf/wf-in-fn-type-static.stderr b/src/test/ui/wf/wf-in-fn-type-static.stderr index 44cacf4ef4d..73fbb9ca670 100644 --- a/src/test/ui/wf/wf-in-fn-type-static.stderr +++ b/src/test/ui/wf/wf-in-fn-type-static.stderr @@ -1,20 +1,24 @@ error[E0310]: the parameter type `T` may not live long enough --> $DIR/wf-in-fn-type-static.rs:13:8 | -LL | struct Foo<T> { - | - help: consider adding an explicit lifetime bound...: `T: 'static` -LL | // needs T: 'static LL | x: fn() -> &'static T | ^^^^^^^^^^^^^^^^^^ ...so that the reference type `&'static T` does not outlive the data it points at + | +help: consider adding an explicit lifetime bound... + | +LL | struct Foo<T: 'static> { + | +++++++++ error[E0310]: the parameter type `T` may not live long enough --> $DIR/wf-in-fn-type-static.rs:18:8 | -LL | struct Bar<T> { - | - help: consider adding an explicit lifetime bound...: `T: 'static` -LL | // needs T: Copy LL | x: fn(&'static T) | ^^^^^^^^^^^^^^ ...so that the reference type `&'static T` does not outlive the data it points at + | +help: consider adding an explicit lifetime bound... + | +LL | struct Bar<T: 'static> { + | +++++++++ error: aborting due to 2 previous errors diff --git a/src/test/ui/wf/wf-in-obj-type-static.stderr b/src/test/ui/wf/wf-in-obj-type-static.stderr index c50a6bb6e4d..c3ad42dd5d5 100644 --- a/src/test/ui/wf/wf-in-obj-type-static.stderr +++ b/src/test/ui/wf/wf-in-obj-type-static.stderr @@ -1,11 +1,13 @@ error[E0310]: the parameter type `T` may not live long enough --> $DIR/wf-in-obj-type-static.rs:14:8 | -LL | struct Foo<T> { - | - help: consider adding an explicit lifetime bound...: `T: 'static` -LL | // needs T: 'static LL | x: dyn Object<&'static T> | ^^^^^^^^^^^^^^^^^^^^^^ ...so that the reference type `&'static T` does not outlive the data it points at + | +help: consider adding an explicit lifetime bound... + | +LL | struct Foo<T: 'static> { + | +++++++++ error: aborting due to previous error diff --git a/src/test/ui/wf/wf-outlives-ty-in-fn-or-trait.stderr b/src/test/ui/wf/wf-outlives-ty-in-fn-or-trait.stderr index 68c1e9091d7..4d4d8b2ab4d 100644 --- a/src/test/ui/wf/wf-outlives-ty-in-fn-or-trait.stderr +++ b/src/test/ui/wf/wf-outlives-ty-in-fn-or-trait.stderr @@ -1,18 +1,24 @@ error[E0309]: the parameter type `T` may not live long enough --> $DIR/wf-outlives-ty-in-fn-or-trait.rs:9:16 | -LL | impl<'a, T> Trait<'a, T> for usize { - | - help: consider adding an explicit lifetime bound...: `T: 'a` LL | type Out = &'a fn(T); | ^^^^^^^^^ ...so that the reference type `&'a fn(T)` does not outlive the data it points at + | +help: consider adding an explicit lifetime bound... + | +LL | impl<'a, T: 'a> Trait<'a, T> for usize { + | ++++ error[E0309]: the parameter type `T` may not live long enough --> $DIR/wf-outlives-ty-in-fn-or-trait.rs:19:16 | -LL | impl<'a, T> Trait<'a, T> for u32 { - | - help: consider adding an explicit lifetime bound...: `T: 'a` LL | type Out = &'a dyn Baz<T>; | ^^^^^^^^^^^^^^ ...so that the reference type `&'a (dyn Baz<T> + 'a)` does not outlive the data it points at + | +help: consider adding an explicit lifetime bound... + | +LL | impl<'a, T: 'a> Trait<'a, T> for u32 { + | ++++ error: aborting due to 2 previous errors diff --git a/src/tools/cargo b/src/tools/cargo -Subproject dba5baf4345858c591517b24801902a062c399f +Subproject f63f23ff1f1a12ede8585bbd1bbf0c536e50293 diff --git a/src/tools/clippy/clippy_lints/src/cognitive_complexity.rs b/src/tools/clippy/clippy_lints/src/cognitive_complexity.rs index 85f95237549..2bf7f868905 100644 --- a/src/tools/clippy/clippy_lints/src/cognitive_complexity.rs +++ b/src/tools/clippy/clippy_lints/src/cognitive_complexity.rs @@ -82,7 +82,7 @@ impl CognitiveComplexity { if rust_cc > self.limit.limit() { let fn_span = match kind { - FnKind::ItemFn(ident, _, _, _) | FnKind::Method(ident, _, _) => ident.span, + FnKind::ItemFn(ident, _, _) | FnKind::Method(ident, _) => ident.span, FnKind::Closure => { let header_span = body_span.with_hi(decl.output.span().lo()); let pos = snippet_opt(cx, header_span).and_then(|snip| { diff --git a/src/tools/clippy/clippy_lints/src/enum_variants.rs b/src/tools/clippy/clippy_lints/src/enum_variants.rs index 1f4353fa4f7..346d03ca556 100644 --- a/src/tools/clippy/clippy_lints/src/enum_variants.rs +++ b/src/tools/clippy/clippy_lints/src/enum_variants.rs @@ -260,7 +260,7 @@ impl LateLintPass<'_> for EnumVariantNames { } // The `module_name_repetitions` lint should only trigger if the item has the module in its // name. Having the same name is accepted. - if item.vis.node.is_pub() && item_camel.len() > mod_camel.len() { + if cx.tcx.visibility(item.def_id).is_public() && item_camel.len() > mod_camel.len() { let matching = count_match_start(mod_camel, &item_camel); let rmatching = count_match_end(mod_camel, &item_camel); let nchars = mod_camel.chars().count(); diff --git a/src/tools/clippy/clippy_lints/src/exhaustive_items.rs b/src/tools/clippy/clippy_lints/src/exhaustive_items.rs index b0f50b5c144..173d41b4b05 100644 --- a/src/tools/clippy/clippy_lints/src/exhaustive_items.rs +++ b/src/tools/clippy/clippy_lints/src/exhaustive_items.rs @@ -78,7 +78,10 @@ impl LateLintPass<'_> for ExhaustiveItems { if !attrs.iter().any(|a| a.has_name(sym::non_exhaustive)); then { let (lint, msg) = if let ItemKind::Struct(ref v, ..) = item.kind { - if v.fields().iter().any(|f| !f.vis.node.is_pub()) { + if v.fields().iter().any(|f| { + let def_id = cx.tcx.hir().local_def_id(f.hir_id); + !cx.tcx.visibility(def_id).is_public() + }) { // skip structs with private fields return; } 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 0709580c8ad..5462d913fb4 100644 --- a/src/tools/clippy/clippy_lints/src/functions/must_use.rs +++ b/src/tools/clippy/clippy_lints/src/functions/must_use.rs @@ -108,7 +108,7 @@ fn check_needless_must_use( diag.span_suggestion( attr.span, "remove the attribute", - "".into(), + "", Applicability::MachineApplicable, ); }, diff --git a/src/tools/clippy/clippy_lints/src/functions/not_unsafe_ptr_arg_deref.rs b/src/tools/clippy/clippy_lints/src/functions/not_unsafe_ptr_arg_deref.rs index 830e3b32cfa..565a1c871d7 100644 --- a/src/tools/clippy/clippy_lints/src/functions/not_unsafe_ptr_arg_deref.rs +++ b/src/tools/clippy/clippy_lints/src/functions/not_unsafe_ptr_arg_deref.rs @@ -17,8 +17,8 @@ pub(super) fn check_fn<'tcx>( hir_id: hir::HirId, ) { let unsafety = match kind { - intravisit::FnKind::ItemFn(_, _, hir::FnHeader { unsafety, .. }, _) => unsafety, - intravisit::FnKind::Method(_, sig, _) => sig.header.unsafety, + intravisit::FnKind::ItemFn(_, _, hir::FnHeader { unsafety, .. }) => unsafety, + intravisit::FnKind::Method(_, sig) => sig.header.unsafety, intravisit::FnKind::Closure => return, }; diff --git a/src/tools/clippy/clippy_lints/src/functions/too_many_arguments.rs b/src/tools/clippy/clippy_lints/src/functions/too_many_arguments.rs index 3af960491ed..5c8d8b8e755 100644 --- a/src/tools/clippy/clippy_lints/src/functions/too_many_arguments.rs +++ b/src/tools/clippy/clippy_lints/src/functions/too_many_arguments.rs @@ -26,9 +26,8 @@ pub(super) fn check_fn( header: hir::FnHeader { abi: Abi::Rust, .. }, .. }, - _, ) - | intravisit::FnKind::ItemFn(_, _, hir::FnHeader { abi: Abi::Rust, .. }, _) => check_arg_number( + | intravisit::FnKind::ItemFn(_, _, hir::FnHeader { abi: Abi::Rust, .. }) => check_arg_number( cx, decl, span.with_hi(decl.output.span().hi()), diff --git a/src/tools/clippy/clippy_lints/src/lifetimes.rs b/src/tools/clippy/clippy_lints/src/lifetimes.rs index b09c23f31e9..662a561f171 100644 --- a/src/tools/clippy/clippy_lints/src/lifetimes.rs +++ b/src/tools/clippy/clippy_lints/src/lifetimes.rs @@ -8,7 +8,7 @@ use rustc_hir::FnRetTy::Return; use rustc_hir::{ BareFnTy, BodyId, FnDecl, GenericArg, GenericBound, GenericParam, GenericParamKind, Generics, ImplItem, ImplItemKind, Item, ItemKind, LangItem, Lifetime, LifetimeName, ParamName, PolyTraitRef, TraitBoundModifier, - TraitFn, TraitItem, TraitItemKind, Ty, TyKind, WhereClause, WherePredicate, + TraitFn, TraitItem, TraitItemKind, Ty, TyKind, WherePredicate, }; use rustc_lint::{LateContext, LateLintPass}; use rustc_session::{declare_lint_pass, declare_tool_lint}; @@ -130,7 +130,7 @@ fn check_fn_inner<'tcx>( span: Span, report_extra_lifetimes: bool, ) { - if span.from_expansion() || has_where_lifetimes(cx, &generics.where_clause) { + if span.from_expansion() || has_where_lifetimes(cx, generics) { return; } @@ -139,28 +139,35 @@ fn check_fn_inner<'tcx>( .iter() .filter(|param| matches!(param.kind, GenericParamKind::Type { .. })); for typ in types { - for bound in typ.bounds { - let mut visitor = RefVisitor::new(cx); - walk_param_bound(&mut visitor, bound); - if visitor.lts.iter().any(|lt| matches!(lt, RefLt::Named(_))) { - return; + for pred in generics.bounds_for_param(cx.tcx.hir().local_def_id(typ.hir_id)) { + if pred.in_where_clause { + // has_where_lifetimes checked that this predicate contains no lifetime. + continue; } - if let GenericBound::Trait(ref trait_ref, _) = *bound { - let params = &trait_ref - .trait_ref - .path - .segments - .last() - .expect("a path must have at least one segment") - .args; - if let Some(params) = *params { - let lifetimes = params.args.iter().filter_map(|arg| match arg { - GenericArg::Lifetime(lt) => Some(lt), - _ => None, - }); - for bound in lifetimes { - if bound.name != LifetimeName::Static && !bound.is_elided() { - return; + + for bound in pred.bounds { + let mut visitor = RefVisitor::new(cx); + walk_param_bound(&mut visitor, bound); + if visitor.lts.iter().any(|lt| matches!(lt, RefLt::Named(_))) { + return; + } + if let GenericBound::Trait(ref trait_ref, _) = *bound { + let params = &trait_ref + .trait_ref + .path + .segments + .last() + .expect("a path must have at least one segment") + .args; + if let Some(params) = *params { + let lifetimes = params.args.iter().filter_map(|arg| match arg { + GenericArg::Lifetime(lt) => Some(lt), + _ => None, + }); + for bound in lifetimes { + if bound.name != LifetimeName::Static && !bound.is_elided() { + return; + } } } } @@ -322,9 +329,7 @@ fn allowed_lts_from(named_generics: &[GenericParam<'_>]) -> FxHashSet<RefLt> { let mut allowed_lts = FxHashSet::default(); for par in named_generics.iter() { if let GenericParamKind::Lifetime { .. } = par.kind { - if par.bounds.is_empty() { - allowed_lts.insert(RefLt::Named(par.name.ident().name)); - } + allowed_lts.insert(RefLt::Named(par.name.ident().name)); } } allowed_lts.insert(RefLt::Unnamed); @@ -445,8 +450,8 @@ impl<'a, 'tcx> Visitor<'tcx> for RefVisitor<'a, 'tcx> { /// Are any lifetimes mentioned in the `where` clause? If so, we don't try to /// reason about elision. -fn has_where_lifetimes<'tcx>(cx: &LateContext<'tcx>, where_clause: &'tcx WhereClause<'_>) -> bool { - for predicate in where_clause.predicates { +fn has_where_lifetimes<'tcx>(cx: &LateContext<'tcx>, generics: &'tcx Generics<'_>) -> bool { + for predicate in generics.predicates { match *predicate { WherePredicate::RegionPredicate(..) => return true, WherePredicate::BoundPredicate(ref pred) => { 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 d29d07da7b0..4034079a90c 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 @@ -85,7 +85,7 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByValue { } match kind { - FnKind::ItemFn(.., header, _) => { + FnKind::ItemFn(.., header) => { let attrs = cx.tcx.hir().attrs(hir_id); if header.abi != Abi::Rust || requires_exact_signature(attrs) { return; @@ -241,7 +241,7 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByValue { |x| Cow::from(format!("change `{}` to", x)), ) .as_ref(), - suggestion.into(), + suggestion, Applicability::Unspecified, ); } @@ -271,7 +271,7 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByValue { |x| Cow::from(format!("change `{}` to", x)) ) .as_ref(), - suggestion.into(), + suggestion, Applicability::Unspecified, ); } 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 9419056be14..96c00c205ff 100644 --- a/src/tools/clippy/clippy_lints/src/new_without_default.rs +++ b/src/tools/clippy/clippy_lints/src/new_without_default.rs @@ -68,7 +68,7 @@ impl<'tcx> LateLintPass<'tcx> for NewWithoutDefault { .. }) = item.kind { - for assoc_item in items { + for assoc_item in *items { if assoc_item.kind == (hir::AssocItemKind::Fn { has_self: false }) { let impl_item = cx.tcx.hir().impl_item(assoc_item.id); if in_external_macro(cx.sess(), impl_item.span) { diff --git a/src/tools/clippy/clippy_lints/src/partialeq_ne_impl.rs b/src/tools/clippy/clippy_lints/src/partialeq_ne_impl.rs index e827cdaae87..1469cb434c0 100644 --- a/src/tools/clippy/clippy_lints/src/partialeq_ne_impl.rs +++ b/src/tools/clippy/clippy_lints/src/partialeq_ne_impl.rs @@ -42,7 +42,7 @@ impl<'tcx> LateLintPass<'tcx> for PartialEqNeImpl { if let Some(eq_trait) = cx.tcx.lang_items().eq_trait(); if trait_ref.path.res.def_id() == eq_trait; then { - for impl_item in impl_items { + for impl_item in *impl_items { if impl_item.ident.name == sym::ne { span_lint_hir( cx, 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 d59249d7f13..9af3059a37f 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 @@ -251,7 +251,7 @@ impl<'tcx> LateLintPass<'tcx> for PassByRefOrValue { } match kind { - FnKind::ItemFn(.., header, _) => { + FnKind::ItemFn(.., header) => { if header.abi != Abi::Rust { return; } diff --git a/src/tools/clippy/clippy_lints/src/redundant_pub_crate.rs b/src/tools/clippy/clippy_lints/src/redundant_pub_crate.rs index 2cee3c14d7f..e2e2400f8e2 100644 --- a/src/tools/clippy/clippy_lints/src/redundant_pub_crate.rs +++ b/src/tools/clippy/clippy_lints/src/redundant_pub_crate.rs @@ -1,8 +1,10 @@ use clippy_utils::diagnostics::span_lint_and_then; use rustc_errors::Applicability; -use rustc_hir::{Item, ItemKind, VisibilityKind}; +use rustc_hir::{Item, ItemKind}; use rustc_lint::{LateContext, LateLintPass}; +use rustc_middle::ty; use rustc_session::{declare_tool_lint, impl_lint_pass}; +use rustc_span::def_id::CRATE_DEF_ID; declare_clippy_lint! { /// ### What it does @@ -41,7 +43,7 @@ impl_lint_pass!(RedundantPubCrate => [REDUNDANT_PUB_CRATE]); impl<'tcx> LateLintPass<'tcx> for RedundantPubCrate { fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) { - if let VisibilityKind::Crate { .. } = item.vis.node { + if cx.tcx.visibility(item.def_id) == ty::Visibility::Restricted(CRATE_DEF_ID.to_def_id()) { if !cx.access_levels.is_exported(item.def_id) && self.is_exported.last() == Some(&false) { let span = item.span.with_hi(item.ident.span.hi()); let descr = cx.tcx.def_kind(item.def_id).descr(item.def_id.to_def_id()); @@ -52,7 +54,7 @@ impl<'tcx> LateLintPass<'tcx> for RedundantPubCrate { &format!("pub(crate) {} inside private module", descr), |diag| { diag.span_suggestion( - item.vis.span, + item.vis_span, "consider using", "pub".to_string(), Applicability::MachineApplicable, diff --git a/src/tools/clippy/clippy_lints/src/return_self_not_must_use.rs b/src/tools/clippy/clippy_lints/src/return_self_not_must_use.rs index 79f104eac0b..91e5e1e8b28 100644 --- a/src/tools/clippy/clippy_lints/src/return_self_not_must_use.rs +++ b/src/tools/clippy/clippy_lints/src/return_self_not_must_use.rs @@ -111,7 +111,7 @@ impl<'tcx> LateLintPass<'tcx> for ReturnSelfNotMustUse { ) { if_chain! { // We are only interested in methods, not in functions or associated functions. - if matches!(kind, FnKind::Method(_, _, _)); + if matches!(kind, FnKind::Method(_, _)); if let Some(fn_def) = cx.tcx.hir().opt_local_def_id(hir_id); if let Some(impl_def) = cx.tcx.impl_of_method(fn_def.to_def_id()); // We don't want this method to be te implementation of a trait because the diff --git a/src/tools/clippy/clippy_lints/src/serde_api.rs b/src/tools/clippy/clippy_lints/src/serde_api.rs index 398e2c200de..fc1c2af9257 100644 --- a/src/tools/clippy/clippy_lints/src/serde_api.rs +++ b/src/tools/clippy/clippy_lints/src/serde_api.rs @@ -36,7 +36,7 @@ impl<'tcx> LateLintPass<'tcx> for SerdeApi { if did == visit_did { let mut seen_str = None; let mut seen_string = None; - for item in items { + for item in *items { match item.ident.as_str() { "visit_str" => seen_str = Some(item.span), "visit_string" => seen_string = Some(item.span), diff --git a/src/tools/clippy/clippy_lints/src/trait_bounds.rs b/src/tools/clippy/clippy_lints/src/trait_bounds.rs index 43e0132a7ec..3d1b2ee925b 100644 --- a/src/tools/clippy/clippy_lints/src/trait_bounds.rs +++ b/src/tools/clippy/clippy_lints/src/trait_bounds.rs @@ -8,8 +8,7 @@ use rustc_data_structures::unhash::UnhashMap; use rustc_errors::Applicability; use rustc_hir::def::Res; use rustc_hir::{ - GenericBound, Generics, Item, ItemKind, Node, ParamName, Path, PathSegment, QPath, TraitItem, Ty, TyKind, - WherePredicate, + GenericBound, Generics, Item, ItemKind, Node, Path, PathSegment, QPath, TraitItem, Ty, TyKind, WherePredicate, }; use rustc_lint::{LateContext, LateLintPass}; use rustc_session::{declare_tool_lint, impl_lint_pass}; @@ -90,10 +89,9 @@ impl<'tcx> LateLintPass<'tcx> for TraitBounds { } fn check_trait_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx TraitItem<'tcx>) { - let Generics { where_clause, .. } = &item.generics; let mut self_bounds_map = FxHashMap::default(); - for predicate in where_clause.predicates { + for predicate in item.generics.predicates { if_chain! { if let WherePredicate::BoundPredicate(ref bound_predicate) = predicate; if !bound_predicate.span.from_expansion(); @@ -166,7 +164,7 @@ impl TraitBounds { } let mut map: UnhashMap<SpanlessTy<'_, '_>, Vec<&GenericBound<'_>>> = UnhashMap::default(); let mut applicability = Applicability::MaybeIncorrect; - for bound in gen.where_clause.predicates { + for bound in gen.predicates { if_chain! { if let WherePredicate::BoundPredicate(ref p) = bound; if p.bounds.len() as u64 <= self.max_trait_bounds; @@ -216,34 +214,23 @@ impl TraitBounds { } fn check_trait_bound_duplication(cx: &LateContext<'_>, gen: &'_ Generics<'_>) { - if gen.span.from_expansion() || gen.params.is_empty() || gen.where_clause.predicates.is_empty() { + if gen.span.from_expansion() || gen.params.is_empty() || gen.predicates.is_empty() { return; } - let mut map = FxHashMap::default(); - for param in gen.params { - if let ParamName::Plain(ref ident) = param.name { - let res = param - .bounds - .iter() - .filter_map(get_trait_info_from_bound) - .collect::<Vec<_>>(); - map.insert(*ident, res); - } - } - - for predicate in gen.where_clause.predicates { + let mut map = FxHashMap::<_, Vec<_>>::default(); + for predicate in gen.predicates { if_chain! { if let WherePredicate::BoundPredicate(ref bound_predicate) = predicate; if !bound_predicate.span.from_expansion(); if let TyKind::Path(QPath::Resolved(_, Path { segments, .. })) = bound_predicate.bounded_ty.kind; if let Some(segment) = segments.first(); - if let Some(trait_resolutions_direct) = map.get(&segment.ident); then { - for (res_where, _, _) in bound_predicate.bounds.iter().filter_map(get_trait_info_from_bound) { - if let Some((_, _, span_direct)) = trait_resolutions_direct + for (res_where, _, span_where) in bound_predicate.bounds.iter().filter_map(get_trait_info_from_bound) { + let trait_resolutions_direct = map.entry(segment.ident).or_default(); + if let Some((_, span_direct)) = trait_resolutions_direct .iter() - .find(|(res_direct, _, _)| *res_direct == res_where) { + .find(|(res_direct, _)| *res_direct == res_where) { span_lint_and_help( cx, TRAIT_DUPLICATION_IN_BOUNDS, @@ -253,6 +240,9 @@ fn check_trait_bound_duplication(cx: &LateContext<'_>, gen: &'_ Generics<'_>) { "consider removing this trait bound", ); } + else { + trait_resolutions_direct.push((res_where, span_where)) + } } } } diff --git a/src/tools/clippy/clippy_lints/src/types/borrowed_box.rs b/src/tools/clippy/clippy_lints/src/types/borrowed_box.rs index 7c06906293b..f35f44eda56 100644 --- a/src/tools/clippy/clippy_lints/src/types/borrowed_box.rs +++ b/src/tools/clippy/clippy_lints/src/types/borrowed_box.rs @@ -104,8 +104,10 @@ fn get_bounds_if_impl_trait<'tcx>(cx: &LateContext<'tcx>, qpath: &QPath<'_>, id: if let Some(Node::GenericParam(generic_param)) = cx.tcx.hir().get_if_local(did); if let GenericParamKind::Type { synthetic, .. } = generic_param.kind; if synthetic; + if let Some(generics) = cx.tcx.hir().get_generics(id.owner); + if let Some(pred) = generics.bounds_for_param(did.expect_local()).next(); then { - Some(generic_param.bounds) + Some(pred.bounds) } else { None } diff --git a/src/tools/clippy/clippy_lints/src/unused_async.rs b/src/tools/clippy/clippy_lints/src/unused_async.rs index 2b89398ecd6..41333bb2add 100644 --- a/src/tools/clippy/clippy_lints/src/unused_async.rs +++ b/src/tools/clippy/clippy_lints/src/unused_async.rs @@ -67,7 +67,7 @@ impl<'tcx> LateLintPass<'tcx> for UnusedAsync { span: Span, hir_id: HirId, ) { - if let FnKind::ItemFn(_, _, FnHeader { asyncness, .. }, _) = &fn_kind { + if let FnKind::ItemFn(_, _, FnHeader { asyncness, .. }) = &fn_kind { if matches!(asyncness, IsAsync::Async) { let mut visitor = AsyncFnVisitor { cx, found_await: false }; walk_fn(&mut visitor, fn_kind, fn_decl, body.id(), span, hir_id); diff --git a/src/tools/clippy/clippy_lints/src/utils/inspector.rs b/src/tools/clippy/clippy_lints/src/utils/inspector.rs index a04288e0a41..37b114a0cfb 100644 --- a/src/tools/clippy/clippy_lints/src/utils/inspector.rs +++ b/src/tools/clippy/clippy_lints/src/utils/inspector.rs @@ -4,6 +4,7 @@ use clippy_utils::get_attr; use rustc_ast::ast::{Attribute, InlineAsmTemplatePiece}; use rustc_hir as hir; use rustc_lint::{LateContext, LateLintPass, LintContext}; +use rustc_middle::ty; use rustc_session::Session; use rustc_session::{declare_lint_pass, declare_tool_lint}; @@ -45,14 +46,16 @@ impl<'tcx> LateLintPass<'tcx> for DeepCodeInspector { return; } println!("impl item `{}`", item.ident.name); - match item.vis.node { - hir::VisibilityKind::Public => println!("public"), - hir::VisibilityKind::Crate(_) => println!("visible crate wide"), - hir::VisibilityKind::Restricted { path, .. } => println!( - "visible in module `{}`", - rustc_hir_pretty::to_string(rustc_hir_pretty::NO_ANN, |s| s.print_path(path, false)) - ), - hir::VisibilityKind::Inherited => println!("visibility inherited from outer item"), + match cx.tcx.visibility(item.def_id) { + ty::Visibility::Public => println!("public"), + ty::Visibility::Restricted(def_id) => { + if def_id.is_top_level_module() { + println!("visible crate wide") + } else { + println!("visible in module `{}`", cx.tcx.def_path_str(def_id)) + } + }, + ty::Visibility::Invisible => println!("invisible"), } match item.kind { hir::ImplItemKind::Const(_, body_id) => { @@ -360,14 +363,16 @@ fn print_expr(cx: &LateContext<'_>, expr: &hir::Expr<'_>, indent: usize) { fn print_item(cx: &LateContext<'_>, item: &hir::Item<'_>) { let did = item.def_id; println!("item `{}`", item.ident.name); - match item.vis.node { - hir::VisibilityKind::Public => println!("public"), - hir::VisibilityKind::Crate(_) => println!("visible crate wide"), - hir::VisibilityKind::Restricted { path, .. } => println!( - "visible in module `{}`", - rustc_hir_pretty::to_string(rustc_hir_pretty::NO_ANN, |s| s.print_path(path, false)) - ), - hir::VisibilityKind::Inherited => println!("visibility inherited from outer item"), + match cx.tcx.visibility(item.def_id) { + ty::Visibility::Public => println!("public"), + ty::Visibility::Restricted(def_id) => { + if def_id.is_top_level_module() { + println!("visible crate wide") + } else { + println!("visible in module `{}`", cx.tcx.def_path_str(def_id)) + } + }, + ty::Visibility::Invisible => println!("invisible"), } match item.kind { hir::ItemKind::ExternCrate(ref _renamed_from) => { diff --git a/src/tools/clippy/clippy_lints/src/wildcard_imports.rs b/src/tools/clippy/clippy_lints/src/wildcard_imports.rs index 832da66a536..2f74eaf3cf5 100644 --- a/src/tools/clippy/clippy_lints/src/wildcard_imports.rs +++ b/src/tools/clippy/clippy_lints/src/wildcard_imports.rs @@ -8,6 +8,7 @@ use rustc_hir::{ Item, ItemKind, PathSegment, UseKind, }; use rustc_lint::{LateContext, LateLintPass}; +use rustc_middle::ty; use rustc_session::{declare_tool_lint, impl_lint_pass}; use rustc_span::symbol::kw; use rustc_span::{sym, BytePos}; @@ -115,7 +116,8 @@ impl LateLintPass<'_> for WildcardImports { if is_test_module_or_function(cx.tcx, item) { self.test_modules_deep = self.test_modules_deep.saturating_add(1); } - if item.vis.node.is_pub() || item.vis.node.is_pub_restricted() { + let module = cx.tcx.parent_module_from_def_id(item.def_id); + if cx.tcx.visibility(item.def_id) != ty::Visibility::Restricted(module.to_def_id()) { return; } if_chain! { diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs index a275bac4ce6..74978720424 100644 --- a/src/tools/clippy/clippy_utils/src/lib.rs +++ b/src/tools/clippy/clippy_utils/src/lib.rs @@ -1690,7 +1690,7 @@ pub fn if_sequence<'tcx>(mut expr: &'tcx Expr<'tcx>) -> (Vec<&'tcx Expr<'tcx>>, /// Checks if the given function kind is an async function. pub fn is_async_fn(kind: FnKind<'_>) -> bool { - matches!(kind, FnKind::ItemFn(_, _, header, _) if header.asyncness == IsAsync::Async) + matches!(kind, FnKind::ItemFn(_, _, header) if header.asyncness == IsAsync::Async) } /// Peels away all the compiler generated code surrounding the body of an async function, diff --git a/src/tools/clippy/clippy_utils/src/sugg.rs b/src/tools/clippy/clippy_utils/src/sugg.rs index 1fc9979f3dd..794d2e1026f 100644 --- a/src/tools/clippy/clippy_utils/src/sugg.rs +++ b/src/tools/clippy/clippy_utils/src/sugg.rs @@ -214,6 +214,7 @@ impl<'a> Sugg<'a> { | ast::ExprKind::Path(..) | ast::ExprKind::Repeat(..) | ast::ExprKind::Ret(..) + | ast::ExprKind::Yeet(..) | ast::ExprKind::Struct(..) | ast::ExprKind::Try(..) | ast::ExprKind::TryBlock(..) diff --git a/src/tools/clippy/tests/ui/extra_unused_lifetimes.stderr b/src/tools/clippy/tests/ui/extra_unused_lifetimes.stderr index ebdb8e74952..9143fb2c208 100644 --- a/src/tools/clippy/tests/ui/extra_unused_lifetimes.stderr +++ b/src/tools/clippy/tests/ui/extra_unused_lifetimes.stderr @@ -7,12 +7,6 @@ LL | fn unused_lt<'a>(x: u8) {} = note: `-D clippy::extra-unused-lifetimes` implied by `-D warnings` error: this lifetime isn't used in the function definition - --> $DIR/extra_unused_lifetimes.rs:16:25 - | -LL | fn unused_lt_transitive<'a, 'b: 'a>(x: &'b u8) { - | ^^ - -error: this lifetime isn't used in the function definition --> $DIR/extra_unused_lifetimes.rs:41:10 | LL | fn x<'a>(&self) {} @@ -24,5 +18,5 @@ error: this lifetime isn't used in the function definition LL | fn unused_lt<'a>(x: u8) {} | ^^ -error: aborting due to 4 previous errors +error: aborting due to 3 previous errors diff --git a/src/tools/clippy/tests/ui/needless_lifetimes.stderr b/src/tools/clippy/tests/ui/needless_lifetimes.stderr index ffa152427a9..a488bc01fff 100644 --- a/src/tools/clippy/tests/ui/needless_lifetimes.stderr +++ b/src/tools/clippy/tests/ui/needless_lifetimes.stderr @@ -109,12 +109,6 @@ LL | fn baz<'a>(&'a self) -> impl Foo + 'a { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: explicit lifetimes given in parameter types where they could be elided (or replaced with `'_` if needed by type declaration) - --> $DIR/needless_lifetimes.rs:307:5 - | -LL | fn impl_trait_elidable_nested_named_lifetimes<'a>(i: &'a i32, f: impl for<'b> Fn(&'b i32) -> &'b i32) -> &'a i32 { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: explicit lifetimes given in parameter types where they could be elided (or replaced with `'_` if needed by type declaration) --> $DIR/needless_lifetimes.rs:310:5 | LL | fn impl_trait_elidable_nested_anonymous_lifetimes<'a>(i: &'a i32, f: impl Fn(&i32) -> &i32) -> &'a i32 { @@ -192,5 +186,5 @@ error: explicit lifetimes given in parameter types where they could be elided (o LL | fn lifetime_elsewhere_provided<'a>(self: Box<Self>, here: &'a ()) -> &'a () { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to 32 previous errors +error: aborting due to 31 previous errors diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs index 1bf6e6d011e..2cb368c6881 100644 --- a/src/tools/compiletest/src/common.rs +++ b/src/tools/compiletest/src/common.rs @@ -198,11 +198,8 @@ pub struct Config { /// The rust-demangler executable. pub rust_demangler_path: Option<PathBuf>, - /// The Python executable to use for LLDB. - pub lldb_python: String, - - /// The Python executable to use for htmldocck. - pub docck_python: String, + /// The Python executable to use for LLDB and htmldocck. + pub python: String, /// The jsondocck executable. pub jsondocck_path: Option<String>, diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs index 858a576dcb4..e6f058569db 100644 --- a/src/tools/compiletest/src/header.rs +++ b/src/tools/compiletest/src/header.rs @@ -157,6 +157,8 @@ pub struct TestProps { pub should_ice: bool, // If true, the stderr is expected to be different across bit-widths. pub stderr_per_bitwidth: bool, + // The MIR opt to unit test, if any + pub mir_unit_test: Option<String>, } mod directives { @@ -189,6 +191,7 @@ mod directives { pub const STDERR_PER_BITWIDTH: &'static str = "stderr-per-bitwidth"; pub const INCREMENTAL: &'static str = "incremental"; pub const KNOWN_BUG: &'static str = "known-bug"; + pub const MIR_UNIT_TEST: &'static str = "unit-test"; // This isn't a real directive, just one that is probably mistyped often pub const INCORRECT_COMPILER_FLAGS: &'static str = "compiler-flags"; } @@ -232,6 +235,7 @@ impl TestProps { assembly_output: None, should_ice: false, stderr_per_bitwidth: false, + mir_unit_test: None, } } @@ -392,6 +396,9 @@ impl TestProps { config.set_name_directive(ln, STDERR_PER_BITWIDTH, &mut self.stderr_per_bitwidth); config.set_name_directive(ln, INCREMENTAL, &mut self.incremental); config.set_name_directive(ln, KNOWN_BUG, &mut self.known_bug); + config.set_name_value_directive(ln, MIR_UNIT_TEST, &mut self.mir_unit_test, |s| { + s.trim().to_string() + }); }); } diff --git a/src/tools/compiletest/src/header/tests.rs b/src/tools/compiletest/src/header/tests.rs index 5b144a1020f..a8fd4880f07 100644 --- a/src/tools/compiletest/src/header/tests.rs +++ b/src/tools/compiletest/src/header/tests.rs @@ -43,8 +43,7 @@ fn config() -> Config { "--compile-lib-path=", "--run-lib-path=", "--rustc-path=", - "--lldb-python=", - "--docck-python=", + "--python=", "--jsondocck-path=", "--src-base=", "--build-base=", diff --git a/src/tools/compiletest/src/json.rs b/src/tools/compiletest/src/json.rs index a5ff779a4ab..10726b98420 100644 --- a/src/tools/compiletest/src/json.rs +++ b/src/tools/compiletest/src/json.rs @@ -23,6 +23,14 @@ struct ArtifactNotification { artifact: PathBuf, } +#[derive(Deserialize)] +struct UnusedExternNotification { + #[allow(dead_code)] + lint_level: String, + #[allow(dead_code)] + unused_extern_names: Vec<String>, +} + #[derive(Deserialize, Clone)] struct DiagnosticSpan { file_name: String, @@ -113,6 +121,9 @@ pub fn extract_rendered(output: &str) -> String { } else if serde_json::from_str::<ArtifactNotification>(line).is_ok() { // Ignore the notification. None + } else if serde_json::from_str::<UnusedExternNotification>(line).is_ok() { + // Ignore the notification. + None } else { print!( "failed to decode compiler output as json: line: {}\noutput: {}", diff --git a/src/tools/compiletest/src/main.rs b/src/tools/compiletest/src/main.rs index 8c1f28f1407..3d11ea21acf 100644 --- a/src/tools/compiletest/src/main.rs +++ b/src/tools/compiletest/src/main.rs @@ -61,8 +61,7 @@ pub fn parse_config(args: Vec<String>) -> Config { .reqopt("", "rustc-path", "path to rustc to use for compiling", "PATH") .optopt("", "rustdoc-path", "path to rustdoc to use for compiling", "PATH") .optopt("", "rust-demangler-path", "path to rust-demangler to use in tests", "PATH") - .reqopt("", "lldb-python", "path to python to use for doc tests", "PATH") - .reqopt("", "docck-python", "path to python to use for doc tests", "PATH") + .reqopt("", "python", "path to python to use for doc tests", "PATH") .optopt("", "jsondocck-path", "path to jsondocck to use for doc tests", "PATH") .optopt("", "valgrind-path", "path to Valgrind executable for Valgrind tests", "PROGRAM") .optflag("", "force-valgrind", "fail if Valgrind tests cannot be run under Valgrind") @@ -222,8 +221,7 @@ pub fn parse_config(args: Vec<String>) -> Config { rustc_path: opt_path(matches, "rustc-path"), rustdoc_path: matches.opt_str("rustdoc-path").map(PathBuf::from), rust_demangler_path: matches.opt_str("rust-demangler-path").map(PathBuf::from), - lldb_python: matches.opt_str("lldb-python").unwrap(), - docck_python: matches.opt_str("docck-python").unwrap(), + python: matches.opt_str("python").unwrap(), jsondocck_path: matches.opt_str("jsondocck-path"), valgrind_path: matches.opt_str("valgrind-path"), force_valgrind: matches.opt_present("force-valgrind"), @@ -667,6 +665,40 @@ fn stamp(config: &Config, testpaths: &TestPaths, revision: Option<&str>) -> Path output_base_dir(config, testpaths, revision).join("stamp") } +fn files_related_to_test( + config: &Config, + testpaths: &TestPaths, + props: &EarlyProps, + revision: Option<&str>, +) -> Vec<PathBuf> { + let mut related = vec![]; + + if testpaths.file.is_dir() { + // run-make tests use their individual directory + for entry in WalkDir::new(&testpaths.file) { + let path = entry.unwrap().into_path(); + if path.is_file() { + related.push(path); + } + } + } else { + related.push(testpaths.file.clone()); + } + + for aux in &props.aux { + let path = testpaths.file.parent().unwrap().join("auxiliary").join(aux); + related.push(path); + } + + // UI test files. + for extension in UI_EXTENSIONS { + let path = expected_output_path(testpaths, revision, &config.compare_mode, extension); + related.push(path); + } + + related +} + fn is_up_to_date( config: &Config, testpaths: &TestPaths, @@ -688,20 +720,10 @@ fn is_up_to_date( // Check timestamps. let mut inputs = inputs.clone(); - // Use `add_dir` to account for run-make tests, which use their individual directory - inputs.add_dir(&testpaths.file); - - for aux in &props.aux { - let path = testpaths.file.parent().unwrap().join("auxiliary").join(aux); + for path in files_related_to_test(config, testpaths, props, revision) { inputs.add_path(&path); } - // UI test files. - for extension in UI_EXTENSIONS { - let path = &expected_output_path(testpaths, revision, &config.compare_mode, extension); - inputs.add_path(path); - } - inputs < Stamp::from_path(&stamp_name) } diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index 6b27d1ecbf5..6d94fe3ebb9 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -179,7 +179,7 @@ pub fn compute_stamp_hash(config: &Config) -> String { } Some(Debugger::Lldb) => { - config.lldb_python.hash(&mut hash); + config.python.hash(&mut hash); config.lldb_python_dir.hash(&mut hash); env::var_os("PATH").hash(&mut hash); env::var_os("PYTHONPATH").hash(&mut hash); @@ -1141,7 +1141,7 @@ impl<'test> TestCx<'test> { // Prepare the lldb_batchmode which executes the debugger script let lldb_script_path = rust_src_root.join("src/etc/lldb_batchmode.py"); self.cmd2procres( - Command::new(&self.config.lldb_python) + Command::new(&self.config.python) .arg(&lldb_script_path) .arg(test_executable) .arg(debugger_script) @@ -1856,10 +1856,14 @@ impl<'test> TestCx<'test> { rustc.args(&[ "-Copt-level=1", "-Zdump-mir=all", - "-Zmir-opt-level=4", "-Zvalidate-mir", "-Zdump-mir-exclude-pass-number", ]); + if let Some(pass) = &self.props.mir_unit_test { + rustc.args(&["-Zmir-opt-level=0", &format!("-Zmir-enable-passes=+{}", pass)]); + } else { + rustc.arg("-Zmir-opt-level=4"); + } let mir_dump_dir = self.get_mir_dump_dir(); let _ = fs::remove_dir_all(&mir_dump_dir); @@ -2256,7 +2260,7 @@ impl<'test> TestCx<'test> { self.check_rustdoc_test_option(proc_res); } else { let root = self.config.find_rust_src_root().unwrap(); - let mut cmd = Command::new(&self.config.docck_python); + let mut cmd = Command::new(&self.config.python); cmd.arg(root.join("src/etc/htmldocck.py")).arg(&out_dir).arg(&self.testpaths.file); if self.config.bless { cmd.arg("--bless"); @@ -2457,7 +2461,7 @@ impl<'test> TestCx<'test> { let mut json_out = out_dir.join(self.testpaths.file.file_stem().unwrap()); json_out.set_extension("json"); let res = self.cmd2procres( - Command::new(&self.config.docck_python) + Command::new(&self.config.python) .arg(root.join("src/etc/check_missing_items.py")) .arg(&json_out), ); @@ -2852,7 +2856,7 @@ impl<'test> TestCx<'test> { .stdout(Stdio::piped()) .stderr(Stdio::piped()) .env("TARGET", &self.config.target) - .env("PYTHON", &self.config.docck_python) + .env("PYTHON", &self.config.python) .env("S", src_root) .env("RUST_BUILD_STAGE", &self.config.stage_id) .env("RUSTC", cwd.join(&self.config.rustc_path)) diff --git a/src/tools/miri b/src/tools/miri -Subproject 1ef91e122775060acb1fbda2c9a366891af3ea8 +Subproject a71a0083937671d79e16bfac4c7b8cab9c8ab9b diff --git a/src/tools/rustdoc-js/tester.js b/src/tools/rustdoc-js/tester.js index dbf5cf9650c..98d0f5dc656 100644 --- a/src/tools/rustdoc-js/tester.js +++ b/src/tools/rustdoc-js/tester.js @@ -58,7 +58,8 @@ function extractFunction(content, functionName) { } while (pos < content.length && content[pos] !== '/' && content[pos - 1] !== '*'); // Eat quoted strings - } else if (content[pos] === '"' || content[pos] === "'" || content[pos] === "`") { + } else if ((content[pos] === '"' || content[pos] === "'" || content[pos] === "`") && + (pos === 0 || content[pos - 1] !== '/')) { stop = content[pos]; do { if (content[pos] === '\\') { @@ -84,8 +85,11 @@ function extractFunction(content, functionName) { } // Stupid function extractor for array. -function extractArrayVariable(content, arrayName) { - var splitter = "var " + arrayName; +function extractArrayVariable(content, arrayName, kind) { + if (typeof kind === "undefined") { + kind = "let "; + } + var splitter = kind + arrayName; while (true) { var start = content.indexOf(splitter); if (start === -1) { @@ -125,12 +129,18 @@ function extractArrayVariable(content, arrayName) { } content = content.slice(start + 1); } + if (kind === "let ") { + return extractArrayVariable(content, arrayName, "const "); + } return null; } // Stupid function extractor for variable. -function extractVariable(content, varName) { - var splitter = "var " + varName; +function extractVariable(content, varName, kind) { + if (typeof kind === "undefined") { + kind = "let "; + } + var splitter = kind + varName; while (true) { var start = content.indexOf(splitter); if (start === -1) { @@ -161,6 +171,9 @@ function extractVariable(content, varName) { } content = content.slice(start + 1); } + if (kind === "let ") { + return extractVariable(content, varName, "const "); + } return null; } @@ -269,8 +282,13 @@ function loadSearchJsAndIndex(searchJs, searchIndex, storageJs, crate) { // execQuery last parameter is built in buildIndex. // buildIndex requires the hashmap from search-index. var functionsToLoad = ["buildHrefAndPath", "pathSplitter", "levenshtein", "validateResult", - "handleAliases", "getQuery", "buildIndex", "execQuery", "execSearch", - "removeEmptyStringsFromArray"]; + "buildIndex", "execQuery", "parseQuery", "createQueryResults", + "isWhitespace", "isSpecialStartCharacter", "isStopCharacter", + "parseInput", "getItemsBefore", "getNextElem", "createQueryElement", + "isReturnArrow", "isPathStart", "getStringElem", "newParsedQuery", + "itemTypeFromName", "isEndCharacter", "isErrorCharacter", + "isIdentCharacter", "isSeparatorCharacter", "getIdentEndPosition", + "checkExtraTypeFilterCharacters", "isWhitespaceCharacter"]; const functions = ["hasOwnPropertyRustdoc", "onEach"]; ALIASES = {}; @@ -286,12 +304,99 @@ function loadSearchJsAndIndex(searchJs, searchIndex, storageJs, crate) { return [loaded, index]; } +// This function checks if `expected` has all the required fields needed for the checks. +function checkNeededFields(fullPath, expected, error_text, queryName, position) { + let fieldsToCheck; + if (fullPath.length === 0) { + fieldsToCheck = [ + "foundElems", + "original", + "returned", + "typeFilter", + "userQuery", + "error", + ]; + } else if (fullPath.endsWith("elems") || fullPath.endsWith("generics")) { + fieldsToCheck = [ + "name", + "fullPath", + "pathWithoutLast", + "pathLast", + "generics", + ]; + } else { + fieldsToCheck = []; + } + for (var i = 0; i < fieldsToCheck.length; ++i) { + const field = fieldsToCheck[i]; + if (!expected.hasOwnProperty(field)) { + let text = `${queryName}==> Mandatory key \`${field}\` is not present`; + if (fullPath.length > 0) { + text += ` in field \`${fullPath}\``; + if (position != null) { + text += ` (position ${position})`; + } + } + error_text.push(text); + } + } +} + +function valueCheck(fullPath, expected, result, error_text, queryName) { + if (Array.isArray(expected)) { + for (var i = 0; i < expected.length; ++i) { + checkNeededFields(fullPath, expected[i], error_text, queryName, i); + if (i >= result.length) { + error_text.push(`${queryName}==> EXPECTED has extra value in array from field ` + + `\`${fullPath}\` (position ${i}): \`${JSON.stringify(expected[i])}\``); + } else { + valueCheck(fullPath + '[' + i + ']', expected[i], result[i], error_text, queryName); + } + } + for (; i < result.length; ++i) { + error_text.push(`${queryName}==> RESULT has extra value in array from field ` + + `\`${fullPath}\` (position ${i}): \`${JSON.stringify(result[i])}\` ` + + 'compared to EXPECTED'); + } + } else if (expected !== null && typeof expected !== "undefined" && + expected.constructor == Object) + { + for (const key in expected) { + if (!expected.hasOwnProperty(key)) { + continue; + } + if (!result.hasOwnProperty(key)) { + error_text.push('==> Unknown key "' + key + '"'); + break; + } + const obj_path = fullPath + (fullPath.length > 0 ? '.' : '') + key; + valueCheck(obj_path, expected[key], result[key], error_text, queryName); + } + } else { + expectedValue = JSON.stringify(expected); + resultValue = JSON.stringify(result); + if (expectedValue != resultValue) { + error_text.push(`${queryName}==> Different values for field \`${fullPath}\`:\n` + + `EXPECTED: \`${expectedValue}\`\nRESULT: \`${resultValue}\``); + } + } +} + +function runParser(query, expected, loaded, loadedFile, queryName) { + var error_text = []; + checkNeededFields("", expected, error_text, queryName, null); + if (error_text.length === 0) { + valueCheck('', expected, loaded.parseQuery(query), error_text, queryName); + } + return error_text; +} + function runSearch(query, expected, index, loaded, loadedFile, queryName) { const filter_crate = loadedFile.FILTER_CRATE; const ignore_order = loadedFile.ignore_order; const exact_check = loadedFile.exact_check; - var results = loaded.execSearch(loaded.getQuery(query), index, filter_crate); + var results = loaded.execQuery(loaded.parseQuery(query), index, filter_crate); var error_text = []; for (var key in expected) { @@ -353,40 +458,75 @@ function checkResult(error_text, loadedFile, displaySuccess) { return 1; } -function runChecks(testFile, loaded, index) { - var testFileContent = readFile(testFile) + 'exports.QUERY = QUERY;exports.EXPECTED = EXPECTED;'; - if (testFileContent.indexOf("FILTER_CRATE") !== -1) { - testFileContent += "exports.FILTER_CRATE = FILTER_CRATE;"; - } else { - testFileContent += "exports.FILTER_CRATE = null;"; - } - var loadedFile = loadContent(testFileContent); - - const expected = loadedFile.EXPECTED; +function runCheck(loadedFile, key, callback) { + const expected = loadedFile[key]; const query = loadedFile.QUERY; if (Array.isArray(query)) { if (!Array.isArray(expected)) { console.log("FAILED"); - console.log("==> If QUERY variable is an array, EXPECTED should be an array too"); + console.log(`==> If QUERY variable is an array, ${key} should be an array too`); return 1; } else if (query.length !== expected.length) { console.log("FAILED"); - console.log("==> QUERY variable should have the same length as EXPECTED"); + console.log(`==> QUERY variable should have the same length as ${key}`); return 1; } for (var i = 0; i < query.length; ++i) { - var error_text = runSearch(query[i], expected[i], index, loaded, loadedFile, - "[ query `" + query[i] + "`]"); + var error_text = callback(query[i], expected[i], "[ query `" + query[i] + "`]"); if (checkResult(error_text, loadedFile, false) !== 0) { return 1; } } console.log("OK"); - return 0; + } else { + var error_text = callback(query, expected, ""); + if (checkResult(error_text, loadedFile, true) !== 0) { + return 1; + } + } + return 0; +} + +function runChecks(testFile, loaded, index) { + var checkExpected = false; + var checkParsed = false; + var testFileContent = readFile(testFile) + 'exports.QUERY = QUERY;'; + + if (testFileContent.indexOf("FILTER_CRATE") !== -1) { + testFileContent += "exports.FILTER_CRATE = FILTER_CRATE;"; + } else { + testFileContent += "exports.FILTER_CRATE = null;"; + } + + if (testFileContent.indexOf("\nconst EXPECTED") !== -1) { + testFileContent += 'exports.EXPECTED = EXPECTED;'; + checkExpected = true; + } + if (testFileContent.indexOf("\nconst PARSED") !== -1) { + testFileContent += 'exports.PARSED = PARSED;'; + checkParsed = true; + } + if (!checkParsed && !checkExpected) { + console.log("FAILED"); + console.log("==> At least `PARSED` or `EXPECTED` is needed!"); + return 1; + } + + const loadedFile = loadContent(testFileContent); + var res = 0; + + if (checkExpected) { + res += runCheck(loadedFile, "EXPECTED", (query, expected, text) => { + return runSearch(query, expected, index, loaded, loadedFile, text); + }); + } + if (checkParsed) { + res += runCheck(loadedFile, "PARSED", (query, expected, text) => { + return runParser(query, expected, loaded, loadedFile, text); + }); } - var error_text = runSearch(query, expected, index, loaded, loadedFile, ""); - return checkResult(error_text, loadedFile, true); + return res; } function load_files(doc_folder, resource_suffix, crate) { diff --git a/src/tools/rustfmt/src/expr.rs b/src/tools/rustfmt/src/expr.rs index 4f333cd27ce..e4cc93026f1 100644 --- a/src/tools/rustfmt/src/expr.rs +++ b/src/tools/rustfmt/src/expr.rs @@ -2,7 +2,7 @@ use std::borrow::Cow; use std::cmp::min; use itertools::Itertools; -use rustc_ast::token::{DelimToken, LitKind}; +use rustc_ast::token::{Delimiter, LitKind}; use rustc_ast::{ast, ptr}; use rustc_span::{BytePos, Span}; @@ -225,6 +225,10 @@ pub(crate) fn format_expr( ast::ExprKind::Ret(Some(ref expr)) => { rewrite_unary_prefix(context, "return ", &**expr, shape) } + ast::ExprKind::Yeet(None) => Some("do yeet".to_owned()), + ast::ExprKind::Yeet(Some(ref expr)) => { + rewrite_unary_prefix(context, "do yeet ", &**expr, shape) + } ast::ExprKind::Box(ref expr) => rewrite_unary_prefix(context, "box ", &**expr, shape), ast::ExprKind::AddrOf(borrow_kind, mutability, ref expr) => { rewrite_expr_addrof(context, borrow_kind, mutability, expr, shape) @@ -412,7 +416,7 @@ pub(crate) fn rewrite_array<'a, T: 'a + IntoOverflowableItem<'a>>( context: &'a RewriteContext<'_>, shape: Shape, force_separator_tactic: Option<SeparatorTactic>, - delim_token: Option<DelimToken>, + delim_token: Option<Delimiter>, ) -> Option<String> { overflow::rewrite_with_square_brackets( context, @@ -1325,7 +1329,7 @@ pub(crate) fn can_be_overflowed_expr( } ast::ExprKind::MacCall(ref mac) => { match ( - rustc_ast::ast::MacDelimiter::from_token(mac.args.delim()), + rustc_ast::ast::MacDelimiter::from_token(mac.args.delim().unwrap()), context.config.overflow_delimited_expr(), ) { (Some(ast::MacDelimiter::Bracket), true) diff --git a/src/tools/rustfmt/src/macros.rs b/src/tools/rustfmt/src/macros.rs index 664f152e8be..26c429eb94f 100644 --- a/src/tools/rustfmt/src/macros.rs +++ b/src/tools/rustfmt/src/macros.rs @@ -12,7 +12,7 @@ use std::collections::HashMap; use std::panic::{catch_unwind, AssertUnwindSafe}; -use rustc_ast::token::{BinOpToken, DelimToken, Token, TokenKind}; +use rustc_ast::token::{BinOpToken, Delimiter, Token, TokenKind}; use rustc_ast::tokenstream::{Cursor, Spacing, TokenStream, TokenTree}; use rustc_ast::{ast, ptr}; use rustc_ast_pretty::pprust; @@ -203,7 +203,7 @@ fn rewrite_macro_inner( let is_forced_bracket = FORCED_BRACKET_MACROS.contains(&¯o_name[..]); let style = if is_forced_bracket && !is_nested_macro { - DelimToken::Bracket + Delimiter::Bracket } else { original_style }; @@ -212,15 +212,15 @@ fn rewrite_macro_inner( let has_comment = contains_comment(context.snippet(mac.span())); if ts.is_empty() && !has_comment { return match style { - DelimToken::Paren if position == MacroPosition::Item => { + Delimiter::Parenthesis if position == MacroPosition::Item => { Some(format!("{}();", macro_name)) } - DelimToken::Bracket if position == MacroPosition::Item => { + Delimiter::Bracket if position == MacroPosition::Item => { Some(format!("{}[];", macro_name)) } - DelimToken::Paren => Some(format!("{}()", macro_name)), - DelimToken::Bracket => Some(format!("{}[]", macro_name)), - DelimToken::Brace => Some(format!("{} {{}}", macro_name)), + Delimiter::Parenthesis => Some(format!("{}()", macro_name)), + Delimiter::Bracket => Some(format!("{}[]", macro_name)), + Delimiter::Brace => Some(format!("{} {{}}", macro_name)), _ => unreachable!(), }; } @@ -260,7 +260,7 @@ fn rewrite_macro_inner( } match style { - DelimToken::Paren => { + Delimiter::Parenthesis => { // Handle special case: `vec!(expr; expr)` if vec_with_semi { handle_vec_semi(context, shape, arg_vec, macro_name, style) @@ -286,7 +286,7 @@ fn rewrite_macro_inner( }) } } - DelimToken::Bracket => { + Delimiter::Bracket => { // Handle special case: `vec![expr; expr]` if vec_with_semi { handle_vec_semi(context, shape, arg_vec, macro_name, style) @@ -323,7 +323,7 @@ fn rewrite_macro_inner( Some(format!("{}{}", rewrite, comma)) } } - DelimToken::Brace => { + Delimiter::Brace => { // For macro invocations with braces, always put a space between // the `macro_name!` and `{ /* macro_body */ }` but skip modifying // anything in between the braces (for now). @@ -342,11 +342,11 @@ fn handle_vec_semi( shape: Shape, arg_vec: Vec<MacroArg>, macro_name: String, - delim_token: DelimToken, + delim_token: Delimiter, ) -> Option<String> { let (left, right) = match delim_token { - DelimToken::Paren => ("(", ")"), - DelimToken::Bracket => ("[", "]"), + Delimiter::Parenthesis => ("(", ")"), + Delimiter::Bracket => ("[", "]"), _ => unreachable!(), }; @@ -528,7 +528,7 @@ enum MacroArgKind { /// e.g., `$($foo: expr),*` Repeat( /// `()`, `[]` or `{}`. - DelimToken, + Delimiter, /// Inner arguments inside delimiters. Vec<ParsedMacroArg>, /// Something after the closing delimiter and the repeat token, if available. @@ -537,7 +537,7 @@ enum MacroArgKind { Token, ), /// e.g., `[derive(Debug)]` - Delimited(DelimToken, Vec<ParsedMacroArg>), + Delimited(Delimiter, Vec<ParsedMacroArg>), /// A possible separator. e.g., `,` or `;`. Separator(String, String), /// Other random stuff that does not fit to other kinds. @@ -547,22 +547,22 @@ enum MacroArgKind { fn delim_token_to_str( context: &RewriteContext<'_>, - delim_token: DelimToken, + delim_token: Delimiter, shape: Shape, use_multiple_lines: bool, inner_is_empty: bool, ) -> (String, String) { let (lhs, rhs) = match delim_token { - DelimToken::Paren => ("(", ")"), - DelimToken::Bracket => ("[", "]"), - DelimToken::Brace => { + Delimiter::Parenthesis => ("(", ")"), + Delimiter::Bracket => ("[", "]"), + Delimiter::Brace => { if inner_is_empty || use_multiple_lines { ("{", "}") } else { ("{ ", " }") } } - DelimToken::NoDelim => ("", ""), + Delimiter::Invisible => unreachable!(), }; if use_multiple_lines { let indent_str = shape.indent.to_string_with_newline(context.config); @@ -583,8 +583,8 @@ impl MacroArgKind { fn starts_with_brace(&self) -> bool { matches!( *self, - MacroArgKind::Repeat(DelimToken::Brace, _, _, _) - | MacroArgKind::Delimited(DelimToken::Brace, _) + MacroArgKind::Repeat(Delimiter::Brace, _, _, _) + | MacroArgKind::Delimited(Delimiter::Brace, _) ) } @@ -753,7 +753,7 @@ impl MacroArgParser { } } - fn add_delimited(&mut self, inner: Vec<ParsedMacroArg>, delim: DelimToken) { + fn add_delimited(&mut self, inner: Vec<ParsedMacroArg>, delim: Delimiter) { self.result.push(ParsedMacroArg { kind: MacroArgKind::Delimited(delim, inner), }); @@ -763,7 +763,7 @@ impl MacroArgParser { fn add_repeat( &mut self, inner: Vec<ParsedMacroArg>, - delim: DelimToken, + delim: Delimiter, iter: &mut Cursor, ) -> Option<()> { let mut buffer = String::new(); @@ -1083,18 +1083,18 @@ pub(crate) fn convert_try_mac( } } -pub(crate) fn macro_style(mac: &ast::MacCall, context: &RewriteContext<'_>) -> DelimToken { +pub(crate) fn macro_style(mac: &ast::MacCall, context: &RewriteContext<'_>) -> Delimiter { let snippet = context.snippet(mac.span()); let paren_pos = snippet.find_uncommented("(").unwrap_or(usize::max_value()); let bracket_pos = snippet.find_uncommented("[").unwrap_or(usize::max_value()); let brace_pos = snippet.find_uncommented("{").unwrap_or(usize::max_value()); if paren_pos < bracket_pos && paren_pos < brace_pos { - DelimToken::Paren + Delimiter::Parenthesis } else if bracket_pos < brace_pos { - DelimToken::Bracket + Delimiter::Bracket } else { - DelimToken::Brace + Delimiter::Brace } } @@ -1174,7 +1174,7 @@ struct Macro { // rather than clone them, if we can make the borrowing work out. struct MacroBranch { span: Span, - args_paren_kind: DelimToken, + args_paren_kind: Delimiter, args: TokenStream, body: Span, whole_body: Span, @@ -1188,7 +1188,7 @@ impl MacroBranch { multi_branch_style: bool, ) -> Option<String> { // Only attempt to format function-like macros. - if self.args_paren_kind != DelimToken::Paren { + if self.args_paren_kind != Delimiter::Parenthesis { // FIXME(#1539): implement for non-sugared macros. return None; } @@ -1350,18 +1350,18 @@ fn rewrite_macro_with_items( items: &[MacroArg], macro_name: &str, shape: Shape, - style: DelimToken, + style: Delimiter, position: MacroPosition, span: Span, ) -> Option<String> { let (opener, closer) = match style { - DelimToken::Paren => ("(", ")"), - DelimToken::Bracket => ("[", "]"), - DelimToken::Brace => (" {", "}"), + Delimiter::Parenthesis => ("(", ")"), + Delimiter::Bracket => ("[", "]"), + Delimiter::Brace => (" {", "}"), _ => return None, }; let trailing_semicolon = match style { - DelimToken::Paren | DelimToken::Bracket if position == MacroPosition::Item => ";", + Delimiter::Parenthesis | Delimiter::Bracket if position == MacroPosition::Item => ";", _ => "", }; diff --git a/src/tools/rustfmt/src/overflow.rs b/src/tools/rustfmt/src/overflow.rs index 80aed998d73..f115e7d0261 100644 --- a/src/tools/rustfmt/src/overflow.rs +++ b/src/tools/rustfmt/src/overflow.rs @@ -3,7 +3,7 @@ use std::cmp::min; use itertools::Itertools; -use rustc_ast::token::DelimToken; +use rustc_ast::token::Delimiter; use rustc_ast::{ast, ptr}; use rustc_span::Span; @@ -297,11 +297,11 @@ pub(crate) fn rewrite_with_square_brackets<'a, T: 'a + IntoOverflowableItem<'a>> shape: Shape, span: Span, force_separator_tactic: Option<SeparatorTactic>, - delim_token: Option<DelimToken>, + delim_token: Option<Delimiter>, ) -> Option<String> { let (lhs, rhs) = match delim_token { - Some(DelimToken::Paren) => ("(", ")"), - Some(DelimToken::Brace) => ("{", "}"), + Some(Delimiter::Parenthesis) => ("(", ")"), + Some(Delimiter::Brace) => ("{", "}"), _ => ("[", "]"), }; Context::new( diff --git a/src/tools/rustfmt/src/parse/macros/cfg_if.rs b/src/tools/rustfmt/src/parse/macros/cfg_if.rs index 306b6bb745e..09b3e32df31 100644 --- a/src/tools/rustfmt/src/parse/macros/cfg_if.rs +++ b/src/tools/rustfmt/src/parse/macros/cfg_if.rs @@ -1,7 +1,7 @@ use std::panic::{catch_unwind, AssertUnwindSafe}; use rustc_ast::ast; -use rustc_ast::token::{DelimToken, TokenKind}; +use rustc_ast::token::{Delimiter, TokenKind}; use rustc_parse::parser::ForceCollect; use rustc_span::symbol::kw; @@ -47,11 +47,11 @@ fn parse_cfg_if_inner<'a>( .map_err(|_| "Failed to parse attributes")?; } - if !parser.eat(&TokenKind::OpenDelim(DelimToken::Brace)) { + if !parser.eat(&TokenKind::OpenDelim(Delimiter::Brace)) { return Err("Expected an opening brace"); } - while parser.token != TokenKind::CloseDelim(DelimToken::Brace) + while parser.token != TokenKind::CloseDelim(Delimiter::Brace) && parser.token.kind != TokenKind::Eof { let item = match parser.parse_item(ForceCollect::No) { @@ -70,7 +70,7 @@ fn parse_cfg_if_inner<'a>( } } - if !parser.eat(&TokenKind::CloseDelim(DelimToken::Brace)) { + if !parser.eat(&TokenKind::CloseDelim(Delimiter::Brace)) { return Err("Expected a closing brace"); } diff --git a/src/tools/rustfmt/src/parse/macros/mod.rs b/src/tools/rustfmt/src/parse/macros/mod.rs index 3728f3a19b4..d4dbf21f8ca 100644 --- a/src/tools/rustfmt/src/parse/macros/mod.rs +++ b/src/tools/rustfmt/src/parse/macros/mod.rs @@ -1,4 +1,4 @@ -use rustc_ast::token::{DelimToken, TokenKind}; +use rustc_ast::token::{Delimiter, TokenKind}; use rustc_ast::tokenstream::TokenStream; use rustc_ast::{ast, ptr}; use rustc_parse::parser::{ForceCollect, Parser}; @@ -81,7 +81,7 @@ fn check_keyword<'a, 'b: 'a>(parser: &'a mut Parser<'b>) -> Option<MacroArg> { && parser.look_ahead(1, |t| { t.kind == TokenKind::Eof || t.kind == TokenKind::Comma - || t.kind == TokenKind::CloseDelim(DelimToken::NoDelim) + || t.kind == TokenKind::CloseDelim(Delimiter::Invisible) }) { parser.bump(); @@ -97,7 +97,7 @@ fn check_keyword<'a, 'b: 'a>(parser: &'a mut Parser<'b>) -> Option<MacroArg> { pub(crate) fn parse_macro_args( context: &RewriteContext<'_>, tokens: TokenStream, - style: DelimToken, + style: Delimiter, forced_bracket: bool, ) -> Option<ParsedMacroArgs> { let mut parser = build_parser(context, tokens); @@ -105,7 +105,7 @@ pub(crate) fn parse_macro_args( let mut vec_with_semi = false; let mut trailing_comma = false; - if DelimToken::Brace != style { + if Delimiter::Brace != style { loop { if let Some(arg) = check_keyword(&mut parser) { args.push(arg); diff --git a/src/tools/rustfmt/src/utils.rs b/src/tools/rustfmt/src/utils.rs index 35512e78fa6..ed418fb1fec 100644 --- a/src/tools/rustfmt/src/utils.rs +++ b/src/tools/rustfmt/src/utils.rs @@ -512,6 +512,7 @@ pub(crate) fn is_block_expr(context: &RewriteContext<'_>, expr: &ast::Expr, repr | ast::ExprKind::Range(..) | ast::ExprKind::Repeat(..) | ast::ExprKind::Ret(..) + | ast::ExprKind::Yeet(..) | ast::ExprKind::Tup(..) | ast::ExprKind::Type(..) | ast::ExprKind::Yield(None) diff --git a/src/tools/rustfmt/src/visitor.rs b/src/tools/rustfmt/src/visitor.rs index 1621eb406b1..f04fb2e0446 100644 --- a/src/tools/rustfmt/src/visitor.rs +++ b/src/tools/rustfmt/src/visitor.rs @@ -1,7 +1,7 @@ use std::cell::{Cell, RefCell}; use std::rc::Rc; -use rustc_ast::{ast, token::DelimToken, visit, AstLike}; +use rustc_ast::{ast, token::Delimiter, visit, AstLike}; use rustc_data_structures::sync::Lrc; use rustc_span::{symbol, BytePos, Pos, Span}; @@ -689,7 +689,7 @@ impl<'b, 'a: 'b> FmtVisitor<'a> { // with whitespace between the delimiters and trailing semi (i.e. `foo!(abc) ;`) // are formatted correctly. let (span, rewrite) = match macro_style(mac, &self.get_context()) { - DelimToken::Bracket | DelimToken::Paren if MacroPosition::Item == pos => { + Delimiter::Bracket | Delimiter::Parenthesis if MacroPosition::Item == pos => { let search_span = mk_sp(mac.span().hi(), self.snippet_provider.end_pos()); let hi = self.snippet_provider.span_before(search_span, ";"); let target_span = mk_sp(mac.span().lo(), hi + BytePos(1)); diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs index ea6e01e577c..4bf932563aa 100644 --- a/src/tools/tidy/src/deps.rs +++ b/src/tools/tidy/src/deps.rs @@ -42,6 +42,9 @@ const EXCEPTIONS: &[(&str, &str)] = &[ ("self_cell", "Apache-2.0"), // rustc (fluent translations) // FIXME: this dependency violates the documentation comment above: ("fortanix-sgx-abi", "MPL-2.0"), // libstd but only for `sgx` target + ("dunce", "CC0-1.0"), // cargo (dev dependency) + ("similar", "Apache-2.0"), // cargo (dev dependency) + ("normalize-line-endings", "Apache-2.0"), // cargo (dev dependency) ]; const EXCEPTIONS_CRANELIFT: &[(&str, &str)] = &[ @@ -174,7 +177,6 @@ const PERMITTED_DEPENDENCIES: &[&str] = &[ "rand_chacha", "rand_core", "rand_hc", - "rand_pcg", "rand_xorshift", "rand_xoshiro", "redox_syscall", diff --git a/src/tools/tidy/src/ui_tests.rs b/src/tools/tidy/src/ui_tests.rs index 63a8909c662..6b715f727b2 100644 --- a/src/tools/tidy/src/ui_tests.rs +++ b/src/tools/tidy/src/ui_tests.rs @@ -7,8 +7,8 @@ use std::path::Path; const ENTRY_LIMIT: usize = 1000; // FIXME: The following limits should be reduced eventually. -const ROOT_ENTRY_LIMIT: usize = 986; -const ISSUES_ENTRY_LIMIT: usize = 2310; +const ROOT_ENTRY_LIMIT: usize = 977; +const ISSUES_ENTRY_LIMIT: usize = 2278; fn check_entries(path: &Path, bad: &mut bool) { let dirs = walkdir::WalkDir::new(&path.join("test/ui")) |
