diff options
| author | Artyom Pavlov <newpavlov@gmail.com> | 2019-08-24 22:50:20 +0000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2019-08-24 22:50:20 +0000 |
| commit | 37721461d47d3840adc6d931b848a9db8e66ceaa (patch) | |
| tree | 4424a43dce056c6000de36eacc524cceccd822c9 | |
| parent | 926f36400f1667edec92959d8b640dea5084674c (diff) | |
| parent | eeba189cfb2cfc5c5898513352d4ca8f1df06e05 (diff) | |
| download | rust-37721461d47d3840adc6d931b848a9db8e66ceaa.tar.gz rust-37721461d47d3840adc6d931b848a9db8e66ceaa.zip | |
Merge branch 'master' into wasi
388 files changed, 4546 insertions, 4945 deletions
diff --git a/.gitattributes b/.gitattributes index f0b1c67bd0f..a7de7ce8559 100644 --- a/.gitattributes +++ b/.gitattributes @@ -8,7 +8,7 @@ src/etc/installer/gfx/* binary *.woff binary src/vendor/** -text -Cargo.lock -merge linguist-generated=false +Cargo.lock linguist-generated=false # Older git versions try to fix line endings on images, this prevents it. *.png binary diff --git a/.mailmap b/.mailmap index c5ecfb54fca..72c76006f7c 100644 --- a/.mailmap +++ b/.mailmap @@ -117,6 +117,9 @@ Jason Toffaletti <toffaletti@gmail.com> Jason Toffaletti <jason@topsy.com> Jauhien Piatlicki <jauhien@gentoo.org> Jauhien Piatlicki <jpiatlicki@zertisa.com> Jay True <glacjay@gmail.com> Jeremy Letang <letang.jeremy@gmail.com> +Jeremy Stucki <dev@jeremystucki.ch> <stucki.jeremy@gmail.com> +Jeremy Stucki <dev@jeremystucki.ch> <jeremy@myelin.ch> +Jeremy Stucki <dev@jeremystucki.ch> Jethro Beekman <github@jbeekman.nl> Jihyun Yu <j.yu@navercorp.com> <yjh0502@gmail.com> Jihyun Yu <j.yu@navercorp.com> jihyun <jihyun@nablecomm.com> diff --git a/Cargo.lock b/Cargo.lock index 9e7dd54e135..8ae21c86637 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -185,7 +185,7 @@ dependencies = [ "serde", "serde_json", "time", - "toml 0.4.10", + "toml", ] [[package]] @@ -202,7 +202,7 @@ name = "build-manifest" version = "0.1.0" dependencies = [ "serde", - "toml 0.4.10", + "toml", ] [[package]] @@ -265,7 +265,7 @@ dependencies = [ [[package]] name = "cargo" -version = "0.39.0" +version = "0.40.0" dependencies = [ "atty", "bytesize", @@ -287,7 +287,7 @@ dependencies = [ "git2-curl", "glob", "hex", - "home", + "home 0.4.2", "ignore", "im-rc", "jobserver", @@ -309,16 +309,16 @@ dependencies = [ "same-file", "semver", "serde", - "serde_ignored", + "serde_ignored 0.1.0", "serde_json", "shell-escape", "strip-ansi-escapes", "tar", "tempfile", "termcolor", - "toml 0.5.1", + "toml", "unicode-width", - "url 2.0.0", + "url 2.1.0", "walkdir", "winapi 0.3.6", ] @@ -442,9 +442,9 @@ dependencies = [ "semver", "serde", "smallvec", - "toml 0.5.1", + "toml", "unicode-normalization", - "url 1.7.2", + "url 2.1.0", ] [[package]] @@ -574,7 +574,7 @@ checksum = "e7ca8a5221364ef15ce201e8ed2f609fc312682a8f4e0e3d4aa5879764e0fa3b" [[package]] name = "crates-io" -version = "0.27.0" +version = "0.28.0" dependencies = [ "curl", "failure", @@ -583,7 +583,7 @@ dependencies = [ "serde", "serde_derive", "serde_json", - "url 2.0.0", + "url 2.1.0", ] [[package]] @@ -946,6 +946,7 @@ name = "error_index_generator" version = "0.0.0" dependencies = [ "rustdoc", + "walkdir", ] [[package]] @@ -1138,10 +1139,12 @@ dependencies = [ [[package]] name = "getopts" -version = "0.2.19" +version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72327b15c228bfe31f1390f93dd5e9279587f0463836393c9df719ce62a3e450" +checksum = "14dbbfd5c71d70241ecf9e6f13737f7b5ce823821063188d7e46c41d371eebd5" dependencies = [ + "rustc-std-workspace-core", + "rustc-std-workspace-std", "unicode-width", ] @@ -1167,7 +1170,7 @@ dependencies = [ "log", "openssl-probe", "openssl-sys", - "url 2.0.0", + "url 2.1.0", ] [[package]] @@ -1179,7 +1182,7 @@ dependencies = [ "curl", "git2", "log", - "url 2.0.0", + "url 2.1.0", ] [[package]] @@ -1278,6 +1281,16 @@ dependencies = [ ] [[package]] +name = "home" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "013e4e6e9134211bb4d6bf53dd8cfb75d9e2715cc33614b9c0827718c6fbe0b8" +dependencies = [ + "scopeguard 1.0.0", + "winapi 0.3.6", +] + +[[package]] name = "html5ever" version = "0.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1569,9 +1582,9 @@ checksum = "b294d6fa9ee409a054354afc4352b0b9ef7ca222c69b8812cbea9e7d2bf3783f" [[package]] name = "libc" -version = "0.2.60" +version = "0.2.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d44e80633f007889c7eff624b709ab43c92d708caad982295768a7b13ca3b5eb" +checksum = "c665266eb592905e8503ba3403020f4b8794d26263f412ca33171600eca9a6fa" dependencies = [ "rustc-std-workspace-core", ] @@ -1775,7 +1788,7 @@ dependencies = [ "serde_json", "shlex", "tempfile", - "toml 0.5.1", + "toml", "toml-query", ] @@ -2364,6 +2377,9 @@ dependencies = [ [[package]] name = "proc_macro" version = "0.0.0" +dependencies = [ + "std", +] [[package]] name = "profiler_builtins" @@ -2720,7 +2736,7 @@ dependencies = [ "failure", "futures", "heck", - "home", + "home 0.3.3", "itertools 0.8.0", "jsonrpc-core", "lazy_static 1.3.0", @@ -2744,13 +2760,13 @@ dependencies = [ "rustfmt-nightly", "serde", "serde_derive", - "serde_ignored", + "serde_ignored 0.0.4", "serde_json", "tempfile", "tokio", "tokio-process", "tokio-timer", - "toml 0.5.1", + "toml", "url 1.7.2", "walkdir", ] @@ -3053,6 +3069,13 @@ dependencies = [ ] [[package]] +name = "rustc-std-workspace-std" +version = "1.0.0" +dependencies = [ + "std", +] + +[[package]] name = "rustc-workspace-hack" version = "1.0.0" dependencies = [ @@ -3189,6 +3212,7 @@ dependencies = [ "rustc_interface", "rustc_metadata", "rustc_mir", + "rustc_plugin", "rustc_plugin_impl", "rustc_save_analysis", "rustc_target", @@ -3373,6 +3397,13 @@ dependencies = [ ] [[package]] +name = "rustc_plugin" +version = "0.0.0" +dependencies = [ + "rustc_plugin_impl", +] + +[[package]] name = "rustc_plugin_impl" version = "0.0.0" dependencies = [ @@ -3546,7 +3577,7 @@ dependencies = [ [[package]] name = "rustfmt-nightly" -version = "1.4.4" +version = "1.4.5" dependencies = [ "annotate-snippets", "atty", @@ -3572,7 +3603,7 @@ dependencies = [ "serde_json", "structopt", "term 0.6.0", - "toml 0.5.1", + "toml", "unicode-segmentation", "unicode-width", "unicode_categories", @@ -3666,9 +3697,9 @@ checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" [[package]] name = "serde" -version = "1.0.92" +version = "1.0.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32746bf0f26eab52f06af0d0aa1984f641341d06d8d673c693871da2d188c9be" +checksum = "fec2851eb56d010dc9a21b89ca53ee75e6528bab60c11e89d38390904982da9f" dependencies = [ "serde_derive", ] @@ -3694,6 +3725,15 @@ dependencies = [ ] [[package]] +name = "serde_ignored" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c24bbb8f4b81834f618cd3e28698235c2fba06ddf7f4fbe30519dd081364e59" +dependencies = [ + "serde", +] + +[[package]] name = "serde_json" version = "1.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -4040,6 +4080,10 @@ dependencies = [ [[package]] name = "term" version = "0.0.0" +dependencies = [ + "core", + "std", +] [[package]] name = "term" @@ -4086,8 +4130,13 @@ dependencies = [ name = "test" version = "0.0.0" dependencies = [ + "core", "getopts", + "libc", + "panic_abort", + "panic_unwind", "proc_macro", + "std", "term 0.0.0", ] @@ -4357,18 +4406,9 @@ dependencies = [ [[package]] name = "toml" -version = "0.4.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "758664fc71a3a69038656bee8b6be6477d2a6c315a6b81f7081f591bffa4111f" -dependencies = [ - "serde", -] - -[[package]] -name = "toml" -version = "0.5.1" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8c96d7873fa7ef8bdeb3a9cda3ac48389b4154f32b9803b4bc26220b677b039" +checksum = "c7aabe75941d914b72bf3e5d3932ed92ce0664d49d8432305a8b547c37227724" dependencies = [ "serde", ] @@ -4384,7 +4424,7 @@ dependencies = [ "is-match", "lazy_static 1.3.0", "regex", - "toml 0.5.1", + "toml", "toml-query_derive", ] @@ -4464,9 +4504,14 @@ checksum = "aa6024fc12ddfd1c6dbc14a80fa2324d4568849869b779f6bd37e5e4c03344d1" [[package]] name = "unicode-width" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "882386231c45df4700b275c7ff55b6f3698780a650026380e72dabe76fa46526" +checksum = "7007dbd421b92cc6e28410fe7362e2e0a2503394908f417b68ec8d1c364c4e20" +dependencies = [ + "compiler_builtins", + "rustc-std-workspace-core", + "rustc-std-workspace-std", +] [[package]] name = "unicode-xid" @@ -4512,9 +4557,9 @@ dependencies = [ [[package]] name = "url" -version = "2.0.0" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77ddaf52e65c6b81c56b7e957c0b1970f7937f21c5c6774c4e56fcb4e20b48c6" +checksum = "75b414f6c464c879d7f9babf951f23bc3743fb7313c081b2e6ca719067ea9d61" dependencies = [ "idna 0.2.0", "matches", diff --git a/Cargo.toml b/Cargo.toml index ccd7e8b7654..a242f090fbc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -68,6 +68,7 @@ rustc-workspace-hack = { path = 'src/tools/rustc-workspace-hack' } # here rustc-std-workspace-core = { path = 'src/tools/rustc-std-workspace-core' } rustc-std-workspace-alloc = { path = 'src/tools/rustc-std-workspace-alloc' } +rustc-std-workspace-std = { path = 'src/tools/rustc-std-workspace-std' } [patch."https://github.com/rust-lang/rust-clippy"] clippy_lints = { path = "src/tools/clippy/clippy_lints" } diff --git a/src/bootstrap/Cargo.toml b/src/bootstrap/Cargo.toml index 589ee9276a5..c27c318f5ad 100644 --- a/src/bootstrap/Cargo.toml +++ b/src/bootstrap/Cargo.toml @@ -44,7 +44,7 @@ cc = "1.0.35" libc = "0.2" serde = { version = "1.0.8", features = ["derive"] } serde_json = "1.0.2" -toml = "0.4" +toml = "0.5" lazy_static = "1.3.0" time = "0.1" petgraph = "0.4.13" diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index f0054c36c0c..4f5de1ecd2b 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -337,7 +337,6 @@ impl<'a> Builder<'a> { match kind { Kind::Build => describe!( compile::Std, - compile::Test, compile::Rustc, compile::CodegenBackend, compile::StartupObjects, @@ -363,7 +362,6 @@ impl<'a> Builder<'a> { ), Kind::Check | Kind::Clippy | Kind::Fix => describe!( check::Std, - check::Test, check::Rustc, check::CodegenBackend, check::Rustdoc @@ -425,8 +423,6 @@ impl<'a> Builder<'a> { doc::TheBook, doc::Standalone, doc::Std, - doc::Test, - doc::WhitelistedRustc, doc::Rustc, doc::Rustdoc, doc::ErrorIndex, @@ -618,13 +614,7 @@ impl<'a> Builder<'a> { } fn run(self, builder: &Builder<'_>) -> Interned<PathBuf> { - let compiler = self.compiler; - let config = &builder.build.config; - let lib = if compiler.stage >= 1 && config.libdir_relative().is_some() { - builder.build.config.libdir_relative().unwrap() - } else { - Path::new("lib") - }; + let lib = builder.sysroot_libdir_relative(self.compiler); let sysroot = builder .sysroot(self.compiler) .join(lib) @@ -678,6 +668,18 @@ impl<'a> Builder<'a> { } } + /// Returns the compiler's relative libdir where the standard library and other artifacts are + /// found for a compiler's sysroot. + /// + /// For example this returns `lib` on Unix and Windows. + pub fn sysroot_libdir_relative(&self, compiler: Compiler) -> &Path { + match self.config.libdir_relative() { + Some(relative_libdir) if compiler.stage >= 1 + => relative_libdir, + _ => Path::new("lib") + } + } + /// Adds the compiler's directory of dynamic libraries to `cmd`'s dynamic /// library lookup path. pub fn add_rustc_lib_path(&self, compiler: Compiler, cmd: &mut Command) { @@ -795,7 +797,7 @@ impl<'a> Builder<'a> { } match mode { - Mode::Std | Mode::Test | Mode::ToolBootstrap | Mode::ToolStd | Mode::ToolTest=> {}, + Mode::Std | Mode::ToolBootstrap | Mode::ToolStd => {}, Mode::Rustc | Mode::Codegen | Mode::ToolRustc => { // Build proc macros both for the host and the target if target != compiler.host && cmd != "check" { @@ -846,7 +848,6 @@ impl<'a> Builder<'a> { // things still build right, please do! match mode { Mode::Std => metadata.push_str("std"), - Mode::Test => metadata.push_str("test"), _ => {}, } cargo.env("__CARGO_DEFAULT_LIB_METADATA", &metadata); @@ -859,18 +860,17 @@ impl<'a> Builder<'a> { stage = compiler.stage; } - let mut extra_args = env::var(&format!("RUSTFLAGS_STAGE_{}", stage)).unwrap_or_default(); + let mut extra_args = String::new(); if stage != 0 { - let s = env::var("RUSTFLAGS_STAGE_NOT_0").unwrap_or_default(); - if !extra_args.is_empty() { - extra_args.push_str(" "); - } + let s = env::var("RUSTFLAGS_NOT_BOOTSTRAP").unwrap_or_default(); + extra_args.push_str(&s); + } else { + let s = env::var("RUSTFLAGS_BOOTSTRAP").unwrap_or_default(); extra_args.push_str(&s); } if cmd == "clippy" { - extra_args.push_str("-Zforce-unstable-if-unmarked -Zunstable-options \ - --json-rendered=termcolor"); + extra_args.push_str("-Zforce-unstable-if-unmarked"); } if !extra_args.is_empty() { @@ -943,9 +943,9 @@ impl<'a> Builder<'a> { let debuginfo_level = match mode { Mode::Rustc | Mode::Codegen => self.config.rust_debuginfo_level_rustc, - Mode::Std | Mode::Test => self.config.rust_debuginfo_level_std, + Mode::Std => self.config.rust_debuginfo_level_std, Mode::ToolBootstrap | Mode::ToolStd | - Mode::ToolTest | Mode::ToolRustc => self.config.rust_debuginfo_level_tools, + Mode::ToolRustc => self.config.rust_debuginfo_level_tools, }; cargo.env("RUSTC_DEBUGINFO_LEVEL", debuginfo_level.to_string()); @@ -1145,7 +1145,6 @@ impl<'a> Builder<'a> { match (mode, self.config.rust_codegen_units_std, self.config.rust_codegen_units) { (Mode::Std, Some(n), _) | - (Mode::Test, Some(n), _) | (_, _, Some(n)) => { cargo.env("RUSTC_CODEGEN_UNITS", n.to_string()); } diff --git a/src/bootstrap/builder/tests.rs b/src/bootstrap/builder/tests.rs index d1542b1fca6..2bb90fdb04e 100644 --- a/src/bootstrap/builder/tests.rs +++ b/src/bootstrap/builder/tests.rs @@ -366,27 +366,6 @@ fn dist_with_same_targets_and_hosts() { ] ); assert_eq!( - first(builder.cache.all::<compile::Test>()), - &[ - compile::Test { - compiler: Compiler { host: a, stage: 0 }, - target: a, - }, - compile::Test { - compiler: Compiler { host: a, stage: 1 }, - target: a, - }, - compile::Test { - compiler: Compiler { host: a, stage: 2 }, - target: a, - }, - compile::Test { - compiler: Compiler { host: a, stage: 1 }, - target: b, - }, - ] - ); - assert_eq!( first(builder.cache.all::<compile::Assemble>()), &[ compile::Assemble { @@ -415,7 +394,47 @@ fn build_default() { let b = INTERNER.intern_str("B"); let c = INTERNER.intern_str("C"); - assert!(!builder.cache.all::<compile::Std>().is_empty()); + assert_eq!( + first(builder.cache.all::<compile::Std>()), + &[ + compile::Std { + compiler: Compiler { host: a, stage: 0 }, + target: a, + }, + compile::Std { + compiler: Compiler { host: a, stage: 1 }, + target: a, + }, + compile::Std { + compiler: Compiler { host: a, stage: 2 }, + target: a, + }, + compile::Std { + compiler: Compiler { host: b, stage: 2 }, + target: a, + }, + compile::Std { + compiler: Compiler { host: a, stage: 1 }, + target: b, + }, + compile::Std { + compiler: Compiler { host: a, stage: 2 }, + target: b, + }, + compile::Std { + compiler: Compiler { host: b, stage: 2 }, + target: b, + }, + compile::Std { + compiler: Compiler { host: a, stage: 2 }, + target: c, + }, + compile::Std { + compiler: Compiler { host: b, stage: 2 }, + target: c, + }, + ] + ); assert!(!builder.cache.all::<compile::Assemble>().is_empty()); assert_eq!( first(builder.cache.all::<compile::Rustc>()), @@ -450,63 +469,61 @@ fn build_default() { }, ] ); +} + +#[test] +fn build_with_target_flag() { + let mut config = configure(&["B"], &["C"]); + config.skip_only_host_steps = true; + let build = Build::new(config); + let mut builder = Builder::new(&build); + builder.run_step_descriptions(&Builder::get_step_descriptions(Kind::Build), &[]); + + let a = INTERNER.intern_str("A"); + let b = INTERNER.intern_str("B"); + let c = INTERNER.intern_str("C"); assert_eq!( - first(builder.cache.all::<compile::Test>()), + first(builder.cache.all::<compile::Std>()), &[ - compile::Test { + compile::Std { compiler: Compiler { host: a, stage: 0 }, target: a, }, - compile::Test { + compile::Std { compiler: Compiler { host: a, stage: 1 }, target: a, }, - compile::Test { + compile::Std { compiler: Compiler { host: a, stage: 2 }, target: a, }, - compile::Test { + compile::Std { compiler: Compiler { host: b, stage: 2 }, target: a, }, - compile::Test { + compile::Std { compiler: Compiler { host: a, stage: 1 }, target: b, }, - compile::Test { + compile::Std { compiler: Compiler { host: a, stage: 2 }, target: b, }, - compile::Test { + compile::Std { compiler: Compiler { host: b, stage: 2 }, target: b, }, - compile::Test { + compile::Std { compiler: Compiler { host: a, stage: 2 }, target: c, }, - compile::Test { + compile::Std { compiler: Compiler { host: b, stage: 2 }, target: c, }, ] ); -} - -#[test] -fn build_with_target_flag() { - let mut config = configure(&["B"], &["C"]); - config.skip_only_host_steps = true; - let build = Build::new(config); - let mut builder = Builder::new(&build); - builder.run_step_descriptions(&Builder::get_step_descriptions(Kind::Build), &[]); - - let a = INTERNER.intern_str("A"); - let b = INTERNER.intern_str("B"); - let c = INTERNER.intern_str("C"); - - assert!(!builder.cache.all::<compile::Std>().is_empty()); assert_eq!( first(builder.cache.all::<compile::Assemble>()), &[ @@ -541,48 +558,6 @@ fn build_with_target_flag() { }, ] ); - - assert_eq!( - first(builder.cache.all::<compile::Test>()), - &[ - compile::Test { - compiler: Compiler { host: a, stage: 0 }, - target: a, - }, - compile::Test { - compiler: Compiler { host: a, stage: 1 }, - target: a, - }, - compile::Test { - compiler: Compiler { host: a, stage: 2 }, - target: a, - }, - compile::Test { - compiler: Compiler { host: b, stage: 2 }, - target: a, - }, - compile::Test { - compiler: Compiler { host: a, stage: 1 }, - target: b, - }, - compile::Test { - compiler: Compiler { host: a, stage: 2 }, - target: b, - }, - compile::Test { - compiler: Compiler { host: b, stage: 2 }, - target: b, - }, - compile::Test { - compiler: Compiler { host: a, stage: 2 }, - target: c, - }, - compile::Test { - compiler: Compiler { host: b, stage: 2 }, - target: c, - }, - ] - ); } #[test] diff --git a/src/bootstrap/check.rs b/src/bootstrap/check.rs index 6e6fea6b831..e9a9b7881a0 100644 --- a/src/bootstrap/check.rs +++ b/src/bootstrap/check.rs @@ -1,6 +1,6 @@ //! Implementation of compiling the compiler and standard library, in "check"-based modes. -use crate::compile::{run_cargo, std_cargo, test_cargo, rustc_cargo, rustc_cargo_env, +use crate::compile::{run_cargo, std_cargo, rustc_cargo, rustc_cargo_env, add_to_sysroot}; use crate::builder::{RunConfig, Builder, Kind, ShouldRun, Step}; use crate::tool::{prepare_tool_cargo, SourceType}; @@ -92,7 +92,7 @@ impl Step for Rustc { let compiler = builder.compiler(0, builder.config.build); let target = self.target; - builder.ensure(Test { target }); + builder.ensure(Std { target }); let mut cargo = builder.cargo(compiler, Mode::Rustc, target, cargo_subcommand(builder.kind)); @@ -160,47 +160,6 @@ impl Step for CodegenBackend { } #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] -pub struct Test { - pub target: Interned<String>, -} - -impl Step for Test { - type Output = (); - const DEFAULT: bool = true; - - fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { - run.all_krates("test") - } - - fn make_run(run: RunConfig<'_>) { - run.builder.ensure(Test { - target: run.target, - }); - } - - fn run(self, builder: &Builder<'_>) { - let compiler = builder.compiler(0, builder.config.build); - let target = self.target; - - builder.ensure(Std { target }); - - let mut cargo = builder.cargo(compiler, Mode::Test, target, cargo_subcommand(builder.kind)); - test_cargo(builder, &compiler, target, &mut cargo); - - builder.info(&format!("Checking test artifacts ({} -> {})", &compiler.host, target)); - run_cargo(builder, - &mut cargo, - args(builder.kind), - &libtest_stamp(builder, compiler, target), - true); - - let libdir = builder.sysroot_libdir(compiler, target); - let hostdir = builder.sysroot_libdir(compiler, compiler.host); - add_to_sysroot(builder, &libdir, &hostdir, &libtest_stamp(builder, compiler, target)); - } -} - -#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] pub struct Rustdoc { pub target: Interned<String>, } @@ -258,16 +217,6 @@ pub fn libstd_stamp( builder.cargo_out(compiler, Mode::Std, target).join(".libstd-check.stamp") } -/// Cargo's output path for libtest in a given stage, compiled by a particular -/// compiler for the specified target. -pub fn libtest_stamp( - builder: &Builder<'_>, - compiler: Compiler, - target: Interned<String>, -) -> PathBuf { - builder.cargo_out(compiler, Mode::Test, target).join(".libtest-check.stamp") -} - /// Cargo's output path for librustc in a given stage, compiled by a particular /// compiler for the specified target. pub fn librustc_stamp( diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs index 96987d08159..7dad146b48d 100644 --- a/src/bootstrap/compile.rs +++ b/src/bootstrap/compile.rs @@ -216,7 +216,7 @@ pub fn std_cargo(builder: &Builder<'_>, cargo.arg("--features").arg(features) .arg("--manifest-path") - .arg(builder.src.join("src/libstd/Cargo.toml")); + .arg(builder.src.join("src/libtest/Cargo.toml")); if target.contains("musl") { if let Some(p) = builder.musl_root(target) { @@ -359,129 +359,6 @@ impl Step for StartupObjects { } #[derive(Debug, PartialOrd, Ord, Copy, Clone, PartialEq, Eq, Hash)] -pub struct Test { - pub target: Interned<String>, - pub compiler: Compiler, -} - -impl Step for Test { - type Output = (); - const DEFAULT: bool = true; - - fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { - run.all_krates("test") - } - - fn make_run(run: RunConfig<'_>) { - run.builder.ensure(Test { - compiler: run.builder.compiler(run.builder.top_stage, run.host), - target: run.target, - }); - } - - /// Builds libtest. - /// - /// This will build libtest and supporting libraries for a particular stage of - /// the build using the `compiler` targeting the `target` architecture. The - /// artifacts created will also be linked into the sysroot directory. - fn run(self, builder: &Builder<'_>) { - let target = self.target; - let compiler = self.compiler; - - builder.ensure(Std { compiler, target }); - - if builder.config.keep_stage.contains(&compiler.stage) { - builder.info("Warning: Using a potentially old libtest. This may not behave well."); - builder.ensure(TestLink { - compiler, - target_compiler: compiler, - target, - }); - return; - } - - let compiler_to_use = builder.compiler_for(compiler.stage, compiler.host, target); - if compiler_to_use != compiler { - builder.ensure(Test { - compiler: compiler_to_use, - target, - }); - builder.info( - &format!("Uplifting stage1 test ({} -> {})", builder.config.build, target)); - builder.ensure(TestLink { - compiler: compiler_to_use, - target_compiler: compiler, - target, - }); - return; - } - - let mut cargo = builder.cargo(compiler, Mode::Test, target, "build"); - test_cargo(builder, &compiler, target, &mut cargo); - - builder.info(&format!("Building stage{} test artifacts ({} -> {})", compiler.stage, - &compiler.host, target)); - run_cargo(builder, - &mut cargo, - vec![], - &libtest_stamp(builder, compiler, target), - false); - - builder.ensure(TestLink { - compiler: builder.compiler(compiler.stage, builder.config.build), - target_compiler: compiler, - target, - }); - } -} - -/// Same as `std_cargo`, but for libtest -pub fn test_cargo(builder: &Builder<'_>, - _compiler: &Compiler, - _target: Interned<String>, - cargo: &mut Command) { - if let Some(target) = env::var_os("MACOSX_STD_DEPLOYMENT_TARGET") { - cargo.env("MACOSX_DEPLOYMENT_TARGET", target); - } - cargo.arg("--manifest-path") - .arg(builder.src.join("src/libtest/Cargo.toml")); -} - -#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)] -pub struct TestLink { - pub compiler: Compiler, - pub target_compiler: Compiler, - pub target: Interned<String>, -} - -impl Step for TestLink { - type Output = (); - - fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { - run.never() - } - - /// Same as `std_link`, only for libtest - fn run(self, builder: &Builder<'_>) { - let compiler = self.compiler; - let target_compiler = self.target_compiler; - let target = self.target; - builder.info(&format!("Copying stage{} test from stage{} ({} -> {} / {})", - target_compiler.stage, - compiler.stage, - &compiler.host, - target_compiler.host, - target)); - add_to_sysroot( - builder, - &builder.sysroot_libdir(target_compiler, target), - &builder.sysroot_libdir(target_compiler, compiler.host), - &libtest_stamp(builder, compiler, target) - ); - } -} - -#[derive(Debug, PartialOrd, Ord, Copy, Clone, PartialEq, Eq, Hash)] pub struct Rustc { pub target: Interned<String>, pub compiler: Compiler, @@ -512,7 +389,7 @@ impl Step for Rustc { let compiler = self.compiler; let target = self.target; - builder.ensure(Test { compiler, target }); + builder.ensure(Std { compiler, target }); if builder.config.keep_stage.contains(&compiler.stage) { builder.info("Warning: Using a potentially old librustc. This may not behave well."); @@ -541,7 +418,7 @@ impl Step for Rustc { } // Ensure that build scripts and proc macros have a std / libproc_macro to link against. - builder.ensure(Test { + builder.ensure(Std { compiler: builder.compiler(self.compiler.stage, builder.config.build), target: builder.config.build, }); @@ -872,16 +749,6 @@ pub fn libstd_stamp( builder.cargo_out(compiler, Mode::Std, target).join(".libstd.stamp") } -/// Cargo's output path for libtest in a given stage, compiled by a particular -/// compiler for the specified target. -pub fn libtest_stamp( - builder: &Builder<'_>, - compiler: Compiler, - target: Interned<String>, -) -> PathBuf { - builder.cargo_out(compiler, Mode::Test, target).join(".libtest.stamp") -} - /// Cargo's output path for librustc in a given stage, compiled by a particular /// compiler for the specified target. pub fn librustc_stamp( diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs index bd012a887c2..0f4ac63651c 100644 --- a/src/bootstrap/dist.rs +++ b/src/bootstrap/dist.rs @@ -469,7 +469,6 @@ impl Step for Rustc { fn prepare_image(builder: &Builder<'_>, compiler: Compiler, image: &Path) { let host = compiler.host; let src = builder.sysroot(compiler); - let libdir = builder.rustc_libdir(compiler); // Copy rustc/rustdoc binaries t!(fs::create_dir_all(image.join("bin"))); @@ -481,11 +480,14 @@ impl Step for Rustc { // Copy runtime DLLs needed by the compiler if libdir_relative.to_str() != Some("bin") { + let libdir = builder.rustc_libdir(compiler); for entry in builder.read_dir(&libdir) { let name = entry.file_name(); if let Some(s) = name.to_str() { if is_dylib(s) { - builder.install(&entry.path(), &image.join(&libdir_relative), 0o644); + // Don't use custom libdir here because ^lib/ will be resolved again + // with installer + builder.install(&entry.path(), &image.join("lib"), 0o644); } } } @@ -493,8 +495,11 @@ impl Step for Rustc { // Copy over the codegen backends let backends_src = builder.sysroot_codegen_backends(compiler); - let backends_rel = backends_src.strip_prefix(&src).unwrap(); - let backends_dst = image.join(&backends_rel); + let backends_rel = backends_src.strip_prefix(&src).unwrap() + .strip_prefix(builder.sysroot_libdir_relative(compiler)).unwrap(); + // Don't use custom libdir here because ^lib/ will be resolved again with installer + let backends_dst = image.join("lib").join(&backends_rel); + t!(fs::create_dir_all(&backends_dst)); builder.cp_r(&backends_src, &backends_dst); @@ -673,12 +678,7 @@ impl Step for Std { if builder.hosts.iter().any(|t| t == target) { builder.ensure(compile::Rustc { compiler, target }); } else { - if builder.no_std(target) == Some(true) { - // the `test` doesn't compile for no-std targets - builder.ensure(compile::Std { compiler, target }); - } else { - builder.ensure(compile::Test { compiler, target }); - } + builder.ensure(compile::Std { compiler, target }); } let image = tmpdir(builder).join(format!("{}-{}-image", name, target)); @@ -907,6 +907,7 @@ impl Step for Src { "src/libproc_macro", "src/tools/rustc-std-workspace-core", "src/tools/rustc-std-workspace-alloc", + "src/tools/rustc-std-workspace-std", "src/librustc", "src/libsyntax", ]; diff --git a/src/bootstrap/doc.rs b/src/bootstrap/doc.rs index 36229720e42..6805474aa04 100644 --- a/src/bootstrap/doc.rs +++ b/src/bootstrap/doc.rs @@ -478,139 +478,13 @@ impl Step for Std { builder.run(&mut cargo); builder.cp_r(&my_out, &out); }; - for krate in &["alloc", "core", "std"] { + for krate in &["alloc", "core", "std", "proc_macro", "test"] { run_cargo_rustdoc_for(krate); } } } #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] -pub struct Test { - stage: u32, - target: Interned<String>, -} - -impl Step for Test { - type Output = (); - const DEFAULT: bool = true; - - fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { - let builder = run.builder; - run.krate("test").default_condition(builder.config.docs) - } - - fn make_run(run: RunConfig<'_>) { - run.builder.ensure(Test { - stage: run.builder.top_stage, - target: run.target, - }); - } - - /// Compile all libtest documentation. - /// - /// This will generate all documentation for libtest and its dependencies. This - /// is largely just a wrapper around `cargo doc`. - fn run(self, builder: &Builder<'_>) { - let stage = self.stage; - let target = self.target; - builder.info(&format!("Documenting stage{} test ({})", stage, target)); - let out = builder.doc_out(target); - t!(fs::create_dir_all(&out)); - let compiler = builder.compiler_for(stage, builder.config.build, target); - - // Build libstd docs so that we generate relative links - builder.ensure(Std { stage, target }); - - builder.ensure(compile::Test { compiler, target }); - let out_dir = builder.stage_out(compiler, Mode::Test) - .join(target).join("doc"); - - // See docs in std above for why we symlink - let my_out = builder.crate_doc_out(target); - t!(symlink_dir_force(&builder.config, &my_out, &out_dir)); - - let mut cargo = builder.cargo(compiler, Mode::Test, target, "doc"); - compile::test_cargo(builder, &compiler, target, &mut cargo); - - cargo.arg("--no-deps") - .arg("-p").arg("test") - .env("RUSTDOC_RESOURCE_SUFFIX", crate::channel::CFG_RELEASE_NUM) - .env("RUSTDOC_GENERATE_REDIRECT_PAGES", "1"); - - builder.run(&mut cargo); - builder.cp_r(&my_out, &out); - } -} - -#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] -pub struct WhitelistedRustc { - stage: u32, - target: Interned<String>, -} - -impl Step for WhitelistedRustc { - type Output = (); - const DEFAULT: bool = true; - const ONLY_HOSTS: bool = true; - - fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { - let builder = run.builder; - run.krate("rustc-main").default_condition(builder.config.docs) - } - - fn make_run(run: RunConfig<'_>) { - run.builder.ensure(WhitelistedRustc { - stage: run.builder.top_stage, - target: run.target, - }); - } - - /// Generates whitelisted compiler crate documentation. - /// - /// This will generate all documentation for crates that are whitelisted - /// to be included in the standard documentation. This documentation is - /// included in the standard Rust documentation, so we should always - /// document it and symlink to merge with the rest of the std and test - /// documentation. We don't build other compiler documentation - /// here as we want to be able to keep it separate from the standard - /// documentation. This is largely just a wrapper around `cargo doc`. - fn run(self, builder: &Builder<'_>) { - let stage = self.stage; - let target = self.target; - builder.info(&format!("Documenting stage{} whitelisted compiler ({})", stage, target)); - let out = builder.doc_out(target); - t!(fs::create_dir_all(&out)); - let compiler = builder.compiler_for(stage, builder.config.build, target); - - // Build libstd docs so that we generate relative links - builder.ensure(Std { stage, target }); - - builder.ensure(compile::Rustc { compiler, target }); - let out_dir = builder.stage_out(compiler, Mode::Rustc) - .join(target).join("doc"); - - // See docs in std above for why we symlink - let my_out = builder.crate_doc_out(target); - t!(symlink_dir_force(&builder.config, &my_out, &out_dir)); - - let mut cargo = builder.cargo(compiler, Mode::Rustc, target, "doc"); - compile::rustc_cargo(builder, &mut cargo); - - // We don't want to build docs for internal compiler dependencies in this - // step (there is another step for that). Therefore, we whitelist the crates - // for which docs must be built. - for krate in &["proc_macro"] { - cargo.arg("-p").arg(krate) - .env("RUSTDOC_RESOURCE_SUFFIX", crate::channel::CFG_RELEASE_NUM) - .env("RUSTDOC_GENERATE_REDIRECT_PAGES", "1"); - } - - builder.run(&mut cargo); - builder.cp_r(&my_out, &out); - } -} - -#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] pub struct Rustc { stage: u32, target: Interned<String>, @@ -825,8 +699,7 @@ impl Step for ErrorIndex { index.arg(crate::channel::CFG_RELEASE_NUM); // FIXME: shouldn't have to pass this env var - index.env("CFG_BUILD", &builder.config.build) - .env("RUSTC_ERROR_METADATA_DST", builder.extended_error_dir()); + index.env("CFG_BUILD", &builder.config.build); builder.run(&mut index); } diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index b72aa78f3de..c0e0ad1a857 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -297,9 +297,6 @@ pub enum Mode { /// Build the standard library, placing output in the "stageN-std" directory. Std, - /// Build libtest, placing output in the "stageN-test" directory. - Test, - /// Build librustc, and compiler libraries, placing output in the "stageN-rustc" directory. Rustc, @@ -315,7 +312,6 @@ pub enum Mode { /// Compile a tool which uses all libraries we compile (up to rustc). /// Doesn't use the stage0 compiler libraries like "other", and includes /// tools like rustdoc, cargo, rls, etc. - ToolTest, ToolStd, ToolRustc, } @@ -536,11 +532,10 @@ impl Build { fn stage_out(&self, compiler: Compiler, mode: Mode) -> PathBuf { let suffix = match mode { Mode::Std => "-std", - Mode::Test => "-test", Mode::Rustc => "-rustc", Mode::Codegen => "-codegen", Mode::ToolBootstrap => "-bootstrap-tools", - Mode::ToolStd | Mode::ToolTest | Mode::ToolRustc => "-tools", + Mode::ToolStd | Mode::ToolRustc => "-tools", }; self.out.join(&*compiler.host) .join(format!("stage{}{}", compiler.stage, suffix)) diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs index c2c134bfd1d..2bb053cc2b0 100644 --- a/src/bootstrap/test.rs +++ b/src/bootstrap/test.rs @@ -1040,21 +1040,10 @@ impl Step for Compiletest { builder.ensure(compile::Rustc { compiler, target }); } - if builder.no_std(target) == Some(true) { - // the `test` doesn't compile for no-std targets - builder.ensure(compile::Std { compiler, target }); - } else { - builder.ensure(compile::Test { compiler, target }); - } - - if builder.no_std(target) == Some(true) { - // for no_std run-make (e.g., thumb*), - // we need a host compiler which is called by cargo. - builder.ensure(compile::Std { compiler, target: compiler.host }); - } + builder.ensure(compile::Std { compiler, target }); + // ensure that `libproc_macro` is available on the host. + builder.ensure(compile::Std { compiler, target: compiler.host }); - // HACK(eddyb) ensure that `libproc_macro` is available on the host. - builder.ensure(compile::Test { compiler, target: compiler.host }); // Also provide `rust_test_helpers` for the host. builder.ensure(native::TestHelpers { target: compiler.host }); @@ -1399,7 +1388,7 @@ impl Step for DocTest { fn run(self, builder: &Builder<'_>) { let compiler = self.compiler; - builder.ensure(compile::Test { + builder.ensure(compile::Std { compiler, target: compiler.host, }); @@ -1535,8 +1524,7 @@ impl Step for ErrorIndex { ); tool.arg("markdown") .arg(&output) - .env("CFG_BUILD", &builder.config.build) - .env("RUSTC_ERROR_METADATA_DST", builder.extended_error_dir()); + .env("CFG_BUILD", &builder.config.build); builder.info(&format!("Testing error-index stage{}", compiler.stage)); let _time = util::timeit(&builder); @@ -1710,8 +1698,7 @@ impl Step for Crate { fn should_run(mut run: ShouldRun<'_>) -> ShouldRun<'_> { let builder = run.builder; - run = run.krate("test"); - for krate in run.builder.in_tree_crates("std") { + for krate in run.builder.in_tree_crates("test") { if !(krate.name.starts_with("rustc_") && krate.name.ends_with("san")) { run = run.path(krate.local_path(&builder).to_str().unwrap()); } @@ -1735,14 +1722,9 @@ impl Step for Crate { }); }; - for krate in builder.in_tree_crates("std") { - if run.path.ends_with(&krate.local_path(&builder)) { - make(Mode::Std, krate); - } - } for krate in builder.in_tree_crates("test") { if run.path.ends_with(&krate.local_path(&builder)) { - make(Mode::Test, krate); + make(Mode::Std, krate); } } } @@ -1762,7 +1744,7 @@ impl Step for Crate { let test_kind = self.test_kind; let krate = self.krate; - builder.ensure(compile::Test { compiler, target }); + builder.ensure(compile::Std { compiler, target }); builder.ensure(RemoteCopyLibs { compiler, target }); // If we're not doing a full bootstrap but we're testing a stage2 @@ -1776,9 +1758,6 @@ impl Step for Crate { Mode::Std => { compile::std_cargo(builder, &compiler, target, &mut cargo); } - Mode::Test => { - compile::test_cargo(builder, &compiler, target, &mut cargo); - } Mode::Rustc => { builder.ensure(compile::Rustc { compiler, target }); compile::rustc_cargo(builder, &mut cargo); @@ -1980,7 +1959,7 @@ impl Step for RemoteCopyLibs { return; } - builder.ensure(compile::Test { compiler, target }); + builder.ensure(compile::Std { compiler, target }); builder.info(&format!("REMOTE copy libs to emulator ({})", target)); t!(fs::create_dir_all(builder.out.join("tmp"))); diff --git a/src/bootstrap/tool.rs b/src/bootstrap/tool.rs index df7eb7c455d..54fe26f18e7 100644 --- a/src/bootstrap/tool.rs +++ b/src/bootstrap/tool.rs @@ -577,12 +577,6 @@ impl Step for Cargo { } fn run(self, builder: &Builder<'_>) -> PathBuf { - // Cargo depends on procedural macros, so make sure the host - // libstd/libproc_macro is available. - builder.ensure(compile::Test { - compiler: self.compiler, - target: builder.config.build, - }); builder.ensure(ToolBuild { compiler: self.compiler, target: self.target, @@ -650,31 +644,10 @@ macro_rules! tool_extended { tool_extended!((self, builder), Cargofmt, rustfmt, "src/tools/rustfmt", "cargo-fmt", {}; - CargoClippy, clippy, "src/tools/clippy", "cargo-clippy", { - // Clippy depends on procedural macros, so make sure that's built for - // the compiler itself. - builder.ensure(compile::Test { - compiler: self.compiler, - target: builder.config.build, - }); - }; - Clippy, clippy, "src/tools/clippy", "clippy-driver", { - // Clippy depends on procedural macros, so make sure that's built for - // the compiler itself. - builder.ensure(compile::Test { - compiler: self.compiler, - target: builder.config.build, - }); - }; + CargoClippy, clippy, "src/tools/clippy", "cargo-clippy", {}; + Clippy, clippy, "src/tools/clippy", "clippy-driver", {}; Miri, miri, "src/tools/miri", "miri", {}; - CargoMiri, miri, "src/tools/miri", "cargo-miri", { - // Miri depends on procedural macros, so make sure that's built for - // the compiler itself. - builder.ensure(compile::Test { - compiler: self.compiler, - target: builder.config.build, - }); - }; + CargoMiri, miri, "src/tools/miri", "cargo-miri", {}; Rls, rls, "src/tools/rls", "rls", { let clippy = builder.ensure(Clippy { compiler: self.compiler, @@ -684,12 +657,6 @@ tool_extended!((self, builder), if clippy.is_some() { self.extra_features.push("clippy".to_owned()); } - // RLS depends on procedural macros, so make sure that's built for - // the compiler itself. - builder.ensure(compile::Test { - compiler: self.compiler, - target: builder.config.build, - }); }; Rustfmt, rustfmt, "src/tools/rustfmt", "rustfmt", {}; ); diff --git a/src/build_helper/lib.rs b/src/build_helper/lib.rs index a1aa18922b5..131d2034675 100644 --- a/src/build_helper/lib.rs +++ b/src/build_helper/lib.rs @@ -262,7 +262,7 @@ pub fn native_lib_boilerplate( if !up_to_date(Path::new("build.rs"), ×tamp) || !up_to_date(src_dir, ×tamp) { Ok(NativeLibBoilerplate { src_dir: src_dir.to_path_buf(), - out_dir: out_dir, + out_dir, }) } else { Err(()) diff --git a/src/ci/docker/dist-various-1/Dockerfile b/src/ci/docker/dist-various-1/Dockerfile index ae2ea8ef95a..10579119462 100644 --- a/src/ci/docker/dist-various-1/Dockerfile +++ b/src/ci/docker/dist-various-1/Dockerfile @@ -104,9 +104,7 @@ ENV TARGETS=$TARGETS,armv5te-unknown-linux-musleabi ENV TARGETS=$TARGETS,armv7-unknown-linux-musleabihf ENV TARGETS=$TARGETS,aarch64-unknown-linux-musl ENV TARGETS=$TARGETS,sparc64-unknown-linux-gnu -# FIXME: temporarily disable the redox builder, -# see: https://github.com/rust-lang/rust/issues/63160 -# ENV TARGETS=$TARGETS,x86_64-unknown-redox +ENV TARGETS=$TARGETS,x86_64-unknown-redox ENV TARGETS=$TARGETS,thumbv6m-none-eabi ENV TARGETS=$TARGETS,thumbv7m-none-eabi ENV TARGETS=$TARGETS,thumbv7em-none-eabi @@ -132,7 +130,7 @@ ENV CC_mipsel_unknown_linux_musl=mipsel-openwrt-linux-gcc \ CC_thumbv7neon_unknown_linux_gnueabihf=arm-linux-gnueabihf-gcc \ AR_thumbv7neon_unknown_linux_gnueabihf=arm-linux-gnueabihf-ar \ CXX_thumbv7neon_unknown_linux_gnueabihf=arm-linux-gnueabihf-g++ - + ENV RUST_CONFIGURE_ARGS \ --musl-root-armv5te=/musl-armv5te \ --musl-root-arm=/musl-arm \ diff --git a/src/ci/docker/dist-various-1/install-mipsel-musl.sh b/src/ci/docker/dist-various-1/install-mipsel-musl.sh index 9ae41218ee4..de8c359d167 100755 --- a/src/ci/docker/dist-various-1/install-mipsel-musl.sh +++ b/src/ci/docker/dist-various-1/install-mipsel-musl.sh @@ -5,7 +5,7 @@ mkdir /usr/local/mipsel-linux-musl # Note that this originally came from: # https://downloads.openwrt.org/snapshots/trunk/malta/generic/ # OpenWrt-Toolchain-malta-le_gcc-5.3.0_musl-1.1.15.Linux-x86_64.tar.bz2 -URL="https://rust-lang-ci2.s3.amazonaws.com/libc" +URL="https://rust-lang-ci-mirrors.s3-us-west-1.amazonaws.com/rustc" FILE="OpenWrt-Toolchain-malta-le_gcc-5.3.0_musl-1.1.15.Linux-x86_64.tar.bz2" curl -L "$URL/$FILE" | tar xjf - -C /usr/local/mipsel-linux-musl --strip-components=2 diff --git a/src/doc/embedded-book b/src/doc/embedded-book -Subproject c5da1e11915d3f28266168baaf55822f7e3fe99 +Subproject 432ca26686c11d396eed6a59499f93ce1bf2433 diff --git a/src/doc/nomicon b/src/doc/nomicon -Subproject 8a7d05615e5bc0a7fb961b4919c44f5221ee54d +Subproject 38b9a76bc8b59ac862663807fc51c9b757337fd diff --git a/src/doc/reference b/src/doc/reference -Subproject b4b3536839042a6743fc76f0d9ad2a812020aea +Subproject d191a0cdd3b92648e0f1e53b13140a14677cc65 diff --git a/src/doc/rust-by-example b/src/doc/rust-by-example -Subproject f2c15ba5ee89ae9469a2cf60494977749901d76 +Subproject 580839d90aacd537f0293697096fa8355bc4e67 diff --git a/src/doc/rustc-guide b/src/doc/rustc-guide -Subproject 6f4ba673ff9d4613e98415bc095347a6a0031e9 +Subproject 6e25a3d0d3573eb42b2e2339f1219e969d1b3de diff --git a/src/doc/rustc/src/command-line-arguments.md b/src/doc/rustc/src/command-line-arguments.md index d774e465118..5eea9c86879 100644 --- a/src/doc/rustc/src/command-line-arguments.md +++ b/src/doc/rustc/src/command-line-arguments.md @@ -304,3 +304,10 @@ to customize the output: Note that it is invalid to combine the `--json` argument with the `--color` argument, and it is required to combine `--json` with `--error-format=json`. + +## `@path`: load command-line flags from a path + +If you specify `@path` on the command-line, then it will open `path` and read +command line options from it. These options are one per line; a blank line indicates +an empty option. The file can use Unix or Windows style line endings, and must be +encoded as UTF-8. diff --git a/src/doc/rustc/src/lints/listing/allowed-by-default.md b/src/doc/rustc/src/lints/listing/allowed-by-default.md index a6e4e166d7b..d3dfc3197e2 100644 --- a/src/doc/rustc/src/lints/listing/allowed-by-default.md +++ b/src/doc/rustc/src/lints/listing/allowed-by-default.md @@ -208,7 +208,7 @@ error: missing documentation for a function To fix the lint, add documentation to all items. -## single-use-lifetime +## single-use-lifetimes This lint detects lifetimes that are only used once. Some example code that triggers this lint: diff --git a/src/liballoc/collections/vec_deque.rs b/src/liballoc/collections/vec_deque.rs index 7315963cc8b..a4a0fbb194d 100644 --- a/src/liballoc/collections/vec_deque.rs +++ b/src/liballoc/collections/vec_deque.rs @@ -1810,7 +1810,7 @@ impl<T> VecDeque<T> { other } - /// Moves all the elements of `other` into `Self`, leaving `other` empty. + /// Moves all the elements of `other` into `self`, leaving `other` empty. /// /// # Panics /// @@ -1847,7 +1847,7 @@ impl<T> VecDeque<T> { /// /// let mut buf = VecDeque::new(); /// buf.extend(1..5); - /// buf.retain(|&x| x%2 == 0); + /// buf.retain(|&x| x % 2 == 0); /// assert_eq!(buf, [2, 4]); /// ``` /// diff --git a/src/libcore/cmp.rs b/src/libcore/cmp.rs index cb9feb074dd..167a9dd1c36 100644 --- a/src/libcore/cmp.rs +++ b/src/libcore/cmp.rs @@ -1012,9 +1012,11 @@ mod impls { impl Ord for $t { #[inline] fn cmp(&self, other: &$t) -> Ordering { - if *self == *other { Equal } - else if *self < *other { Less } - else { Greater } + // The order here is important to generate more optimal assembly. + // See <https://github.com/rust-lang/rust/issues/63758> for more info. + if *self < *other { Less } + else if *self > *other { Greater } + else { Equal } } } )*) diff --git a/src/libcore/iter/adapters/chain.rs b/src/libcore/iter/adapters/chain.rs index 0b9f7f6b609..c9612596b1b 100644 --- a/src/libcore/iter/adapters/chain.rs +++ b/src/libcore/iter/adapters/chain.rs @@ -173,17 +173,23 @@ impl<A, B> Iterator for Chain<A, B> where #[inline] fn size_hint(&self) -> (usize, Option<usize>) { - let (a_lower, a_upper) = self.a.size_hint(); - let (b_lower, b_upper) = self.b.size_hint(); + match self.state { + ChainState::Both => { + let (a_lower, a_upper) = self.a.size_hint(); + let (b_lower, b_upper) = self.b.size_hint(); - let lower = a_lower.saturating_add(b_lower); + let lower = a_lower.saturating_add(b_lower); - let upper = match (a_upper, b_upper) { - (Some(x), Some(y)) => x.checked_add(y), - _ => None - }; + let upper = match (a_upper, b_upper) { + (Some(x), Some(y)) => x.checked_add(y), + _ => None + }; - (lower, upper) + (lower, upper) + } + ChainState::Front => self.a.size_hint(), + ChainState::Back => self.b.size_hint(), + } } } diff --git a/src/libcore/iter/adapters/mod.rs b/src/libcore/iter/adapters/mod.rs index a63434abd6c..f50781890ab 100644 --- a/src/libcore/iter/adapters/mod.rs +++ b/src/libcore/iter/adapters/mod.rs @@ -1309,7 +1309,7 @@ impl<I> DoubleEndedIterator for Peekable<I> where I: DoubleEndedIterator { Self: Sized, F: FnMut(B, Self::Item) -> R, R: Try<Ok=B> { match self.peeked.take() { - Some(None) => return Try::from_ok(init), + Some(None) => Try::from_ok(init), Some(Some(v)) => match self.iter.try_rfold(init, &mut f).into_result() { Ok(acc) => f(acc, v), Err(e) => { @@ -1326,7 +1326,7 @@ impl<I> DoubleEndedIterator for Peekable<I> where I: DoubleEndedIterator { where Fold: FnMut(Acc, Self::Item) -> Acc, { match self.peeked { - Some(None) => return init, + Some(None) => init, Some(Some(v)) => { let acc = self.iter.rfold(init, &mut fold); fold(acc, v) diff --git a/src/libcore/macros.rs b/src/libcore/macros.rs index 6c88a766a2f..ffaca029a8a 100644 --- a/src/libcore/macros.rs +++ b/src/libcore/macros.rs @@ -734,7 +734,6 @@ pub(crate) mod builtin { #[allow_internal_unstable(fmt_internals)] #[rustc_builtin_macro] #[macro_export] - #[rustc_macro_transparency = "opaque"] macro_rules! format_args { ($fmt:expr) => ({ /* compiler built-in */ }); ($fmt:expr, $($args:tt)*) => ({ /* compiler built-in */ }) @@ -747,7 +746,6 @@ pub(crate) mod builtin { #[allow_internal_unstable(fmt_internals)] #[rustc_builtin_macro] #[macro_export] - #[rustc_macro_transparency = "opaque"] macro_rules! format_args_nl { ($fmt:expr) => ({ /* compiler built-in */ }); ($fmt:expr, $($args:tt)*) => ({ /* compiler built-in */ }) @@ -1235,7 +1233,6 @@ pub(crate) mod builtin { #[stable(feature = "rust1", since = "1.0.0")] #[allow_internal_unstable(test, rustc_attrs)] #[rustc_builtin_macro] - #[rustc_macro_transparency = "semitransparent"] pub macro test($item:item) { /* compiler built-in */ } /// Attribute macro applied to a function to turn it into a benchmark test. @@ -1243,7 +1240,6 @@ pub(crate) mod builtin { reason = "`bench` is a part of custom test frameworks which are unstable")] #[allow_internal_unstable(test, rustc_attrs)] #[rustc_builtin_macro] - #[rustc_macro_transparency = "semitransparent"] pub macro bench($item:item) { /* compiler built-in */ } /// An implementation detail of the `#[test]` and `#[bench]` macros. @@ -1251,26 +1247,22 @@ pub(crate) mod builtin { reason = "custom test frameworks are an unstable feature")] #[allow_internal_unstable(test, rustc_attrs)] #[rustc_builtin_macro] - #[rustc_macro_transparency = "semitransparent"] pub macro test_case($item:item) { /* compiler built-in */ } /// Attribute macro applied to a static to register it as a global allocator. #[stable(feature = "global_allocator", since = "1.28.0")] #[allow_internal_unstable(rustc_attrs)] #[rustc_builtin_macro] - #[rustc_macro_transparency = "semitransparent"] pub macro global_allocator($item:item) { /* compiler built-in */ } /// Unstable implementation detail of the `rustc` compiler, do not use. #[rustc_builtin_macro] - #[cfg_attr(boostrap_stdarch_ignore_this, rustc_macro_transparency = "semitransparent")] #[stable(feature = "rust1", since = "1.0.0")] #[allow_internal_unstable(core_intrinsics, libstd_sys_internals)] pub macro RustcDecodable($item:item) { /* compiler built-in */ } /// Unstable implementation detail of the `rustc` compiler, do not use. #[rustc_builtin_macro] - #[cfg_attr(boostrap_stdarch_ignore_this, rustc_macro_transparency = "semitransparent")] #[stable(feature = "rust1", since = "1.0.0")] #[allow_internal_unstable(core_intrinsics)] pub macro RustcEncodable($item:item) { /* compiler built-in */ } diff --git a/src/libcore/num/f32.rs b/src/libcore/num/f32.rs index 8ff78166a9f..22e7573eca6 100644 --- a/src/libcore/num/f32.rs +++ b/src/libcore/num/f32.rs @@ -315,7 +315,7 @@ impl f32 { /// use std::f32; /// /// let x = 2.0_f32; - /// let abs_difference = (x.recip() - (1.0/x)).abs(); + /// let abs_difference = (x.recip() - (1.0 / x)).abs(); /// /// assert!(abs_difference <= f32::EPSILON); /// ``` diff --git a/src/libcore/num/f64.rs b/src/libcore/num/f64.rs index d45c04f45af..bbe1d040780 100644 --- a/src/libcore/num/f64.rs +++ b/src/libcore/num/f64.rs @@ -327,7 +327,7 @@ impl f64 { /// /// ``` /// let x = 2.0_f64; - /// let abs_difference = (x.recip() - (1.0/x)).abs(); + /// let abs_difference = (x.recip() - (1.0 / x)).abs(); /// /// assert!(abs_difference < 1e-10); /// ``` diff --git a/src/libcore/slice/mod.rs b/src/libcore/slice/mod.rs index ce5af13d4ca..931768564ca 100644 --- a/src/libcore/slice/mod.rs +++ b/src/libcore/slice/mod.rs @@ -3026,8 +3026,7 @@ macro_rules! len { if size == 0 { // This _cannot_ use `unchecked_sub` because we depend on wrapping // to represent the length of long ZST slice iterators. - let diff = ($self.end as usize).wrapping_sub(start as usize); - diff + ($self.end as usize).wrapping_sub(start as usize) } else { // We know that `start <= end`, so can do better than `offset_from`, // which needs to deal in signed. By setting appropriate flags here @@ -4637,6 +4636,22 @@ impl<'a, T> DoubleEndedIterator for ChunksExactMut<'a, T> { Some(tail) } } + + #[inline] + fn nth_back(&mut self, n: usize) -> Option<Self::Item> { + let len = self.len(); + if n >= len { + self.v = &mut []; + None + } else { + let start = (len - 1 - n) * self.chunk_size; + let end = start + self.chunk_size; + let (temp, _tail) = mem::replace(&mut self.v, &mut []).split_at_mut(end); + let (head, nth_back) = temp.split_at_mut(start); + self.v = head; + Some(nth_back) + } + } } #[stable(feature = "chunks_exact", since = "1.31.0")] diff --git a/src/libcore/tests/iter.rs b/src/libcore/tests/iter.rs index a1a27e1d538..3a4f76852a0 100644 --- a/src/libcore/tests/iter.rs +++ b/src/libcore/tests/iter.rs @@ -153,6 +153,54 @@ fn test_iterator_chain_find() { } #[test] +fn test_iterator_chain_size_hint() { + struct Iter { + is_empty: bool, + } + + impl Iterator for Iter { + type Item = (); + + // alternates between `None` and `Some(())` + fn next(&mut self) -> Option<Self::Item> { + if self.is_empty { + self.is_empty = false; + None + } else { + self.is_empty = true; + Some(()) + } + } + + fn size_hint(&self) -> (usize, Option<usize>) { + if self.is_empty { + (0, Some(0)) + } else { + (1, Some(1)) + } + } + } + + impl DoubleEndedIterator for Iter { + fn next_back(&mut self) -> Option<Self::Item> { + self.next() + } + } + + // this chains an iterator of length 0 with an iterator of length 1, + // so after calling `.next()` once, the iterator is empty and the + // state is `ChainState::Back`. `.size_hint()` should now disregard + // the size hint of the left iterator + let mut iter = Iter { is_empty: true }.chain(once(())); + assert_eq!(iter.next(), Some(())); + assert_eq!(iter.size_hint(), (0, Some(0))); + + let mut iter = once(()).chain(Iter { is_empty: true }); + assert_eq!(iter.next_back(), Some(())); + assert_eq!(iter.size_hint(), (0, Some(0))); +} + +#[test] fn test_zip_nth() { let xs = [0, 1, 2, 4, 5]; let ys = [10, 11, 12]; diff --git a/src/libcore/tests/slice.rs b/src/libcore/tests/slice.rs index 4790152512a..6609bc3135a 100644 --- a/src/libcore/tests/slice.rs +++ b/src/libcore/tests/slice.rs @@ -375,6 +375,25 @@ fn test_chunks_exact_mut_nth() { } #[test] +fn test_chunks_exact_mut_nth_back() { + let v: &mut [i32] = &mut [0, 1, 2, 3, 4, 5]; + let mut c = v.chunks_exact_mut(2); + assert_eq!(c.nth_back(1).unwrap(), &[2, 3]); + assert_eq!(c.next().unwrap(), &[0, 1]); + assert_eq!(c.next(), None); + + let v2: &mut [i32] = &mut [0, 1, 2, 3, 4]; + let mut c2 = v2.chunks_exact_mut(3); + assert_eq!(c2.nth_back(0).unwrap(), &[0, 1, 2]); + assert_eq!(c2.next(), None); + assert_eq!(c2.next_back(), None); + + let v3: &mut [i32] = &mut [0, 1, 2, 3, 4]; + let mut c3 = v3.chunks_exact_mut(10); + assert_eq!(c3.nth_back(0), None); +} + +#[test] fn test_chunks_exact_mut_last() { let v: &mut [i32] = &mut [0, 1, 2, 3, 4, 5]; let c = v.chunks_exact_mut(2); diff --git a/src/libproc_macro/Cargo.toml b/src/libproc_macro/Cargo.toml index b3d0ee94f0e..187bdac8001 100644 --- a/src/libproc_macro/Cargo.toml +++ b/src/libproc_macro/Cargo.toml @@ -6,3 +6,6 @@ edition = "2018" [lib] path = "lib.rs" + +[dependencies] +std = { path = "../libstd" } diff --git a/src/librustc/error_codes.rs b/src/librustc/error_codes.rs index b3eee7c3464..a200a058f4f 100644 --- a/src/librustc/error_codes.rs +++ b/src/librustc/error_codes.rs @@ -2088,7 +2088,6 @@ generator can be constructed. Erroneous code example: ```edition2018,compile-fail,E0698 -#![feature(async_await)] async fn bar<T>() -> () {} async fn foo() { @@ -2101,7 +2100,6 @@ To fix this you must bind `T` to a concrete type such as `String` so that a generator can then be constructed: ```edition2018 -#![feature(async_await)] async fn bar<T>() -> () {} async fn foo() { diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs index 7292428ec37..f80e527dfd9 100644 --- a/src/librustc/hir/map/mod.rs +++ b/src/librustc/hir/map/mod.rs @@ -514,8 +514,7 @@ impl<'hir> Map<'hir> { &self.forest.krate.attrs } - pub fn get_module(&self, module: DefId) -> (&'hir Mod, Span, HirId) - { + pub fn get_module(&self, module: DefId) -> (&'hir Mod, Span, HirId) { let hir_id = self.as_local_hir_id(module).unwrap(); self.read(hir_id); match self.find_entry(hir_id).unwrap().node { @@ -525,7 +524,7 @@ impl<'hir> Map<'hir> { .. }) => (m, span, hir_id), Node::Crate => (&self.forest.krate.module, self.forest.krate.span, hir_id), - _ => panic!("not a module") + node => panic!("not a module: {:?}", node), } } @@ -679,6 +678,16 @@ impl<'hir> Map<'hir> { } } + /// Wether `hir_id` corresponds to a `mod` or a crate. + pub fn is_hir_id_module(&self, hir_id: HirId) -> bool { + match self.lookup(hir_id) { + Some(Entry { node: Node::Item(Item { node: ItemKind::Mod(_), .. }), .. }) | + Some(Entry { node: Node::Crate, .. }) => true, + _ => false, + } + } + + /// If there is some error when walking the parents (e.g., a node does not /// have a parent in the map or a node can't be found), then we return the /// last good `HirId` we found. Note that reaching the crate root (`id == 0`), diff --git a/src/librustc/ich/impls_syntax.rs b/src/librustc/ich/impls_syntax.rs index 7003f71c8ba..05e2c7854b4 100644 --- a/src/librustc/ich/impls_syntax.rs +++ b/src/librustc/ich/impls_syntax.rs @@ -402,7 +402,6 @@ impl_stable_hash_for!(struct ::syntax_pos::hygiene::ExpnData { parent -> _, call_site, def_site, - default_transparency, allow_internal_unstable, allow_internal_unsafe, local_inner_macros, diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs index 84687b8cab5..9be73cf3c6d 100644 --- a/src/librustc/infer/error_reporting/mod.rs +++ b/src/librustc/infer/error_reporting/mod.rs @@ -1650,7 +1650,7 @@ impl<'tcx> ObligationCause<'tcx> { hir::MatchSource::IfLetDesugar { .. } => "`if let` arms have compatible types", _ => "match arms have compatible types", }, - IfExpression { .. } => "if and else have compatible types", + IfExpression { .. } => "if and else have incompatible types", IfExpressionWithNoElse => "if missing an else returns ()", MainFunctionType => "`main` function has the correct type", StartFunctionType => "`start` function has the correct type", diff --git a/src/librustc/ty/error.rs b/src/librustc/ty/error.rs index d6d17a67e01..c70006b68d6 100644 --- a/src/librustc/ty/error.rs +++ b/src/librustc/ty/error.rs @@ -247,13 +247,15 @@ impl<'tcx> ty::TyS<'tcx> { } impl<'tcx> TyCtxt<'tcx> { - pub fn note_and_explain_type_err(self, - db: &mut DiagnosticBuilder<'_>, - err: &TypeError<'tcx>, - sp: Span) { + pub fn note_and_explain_type_err( + self, + db: &mut DiagnosticBuilder<'_>, + err: &TypeError<'tcx>, + sp: Span, + ) { use self::TypeError::*; - match err.clone() { + match err { Sorts(values) => { let expected_str = values.expected.sort_string(self); let found_str = values.found.sort_string(self); @@ -261,6 +263,16 @@ impl<'tcx> TyCtxt<'tcx> { db.note("no two closures, even if identical, have the same type"); db.help("consider boxing your closure and/or using it as a trait object"); } + if expected_str == found_str && expected_str == "opaque type" { // Issue #63167 + db.note("distinct uses of `impl Trait` result in different opaque types"); + let e_str = values.expected.to_string(); + let f_str = values.found.to_string(); + if &e_str == &f_str && &e_str == "impl std::future::Future" { + // FIXME: use non-string based check. + db.help("if both `Future`s have the same `Output` type, consider \ + `.await`ing on both of them"); + } + } if let (ty::Infer(ty::IntVar(_)), ty::Float(_)) = (&values.found.sty, &values.expected.sty) // Issue #53280 { diff --git a/src/librustc/ty/query/on_disk_cache.rs b/src/librustc/ty/query/on_disk_cache.rs index 8bf01970eb5..c21639d0dca 100644 --- a/src/librustc/ty/query/on_disk_cache.rs +++ b/src/librustc/ty/query/on_disk_cache.rs @@ -23,7 +23,7 @@ use std::mem; use syntax::ast::NodeId; use syntax::source_map::{SourceMap, StableSourceFileId}; use syntax_pos::{BytePos, Span, DUMMY_SP, SourceFile}; -use syntax_pos::hygiene::{ExpnId, SyntaxContext, ExpnData}; +use syntax_pos::hygiene::{ExpnId, SyntaxContext}; const TAG_FILE_FOOTER: u128 = 0xC0FFEE_C0FFEE_C0FFEE_C0FFEE_C0FFEE; @@ -593,8 +593,8 @@ impl<'a, 'tcx> SpecializedDecoder<Span> for CacheDecoder<'a, 'tcx> { // don't seem to be used after HIR lowering, so everything should be fine // as long as incremental compilation does not kick in before that. let location = || Span::with_root_ctxt(lo, hi); - let recover_from_expn_data = |this: &Self, expn_data, pos| { - let span = location().fresh_expansion(expn_data); + let recover_from_expn_data = |this: &Self, expn_data, transparency, pos| { + let span = location().fresh_expansion_with_transparency(expn_data, transparency); this.synthetic_syntax_contexts.borrow_mut().insert(pos, span.ctxt()); span }; @@ -603,9 +603,9 @@ impl<'a, 'tcx> SpecializedDecoder<Span> for CacheDecoder<'a, 'tcx> { location() } TAG_EXPN_DATA_INLINE => { - let expn_data = Decodable::decode(self)?; + let (expn_data, transparency) = Decodable::decode(self)?; recover_from_expn_data( - self, expn_data, AbsoluteBytePos::new(self.opaque.position()) + self, expn_data, transparency, AbsoluteBytePos::new(self.opaque.position()) ) } TAG_EXPN_DATA_SHORTHAND => { @@ -614,9 +614,9 @@ impl<'a, 'tcx> SpecializedDecoder<Span> for CacheDecoder<'a, 'tcx> { if let Some(ctxt) = cached_ctxt { Span::new(lo, hi, ctxt) } else { - let expn_data = - self.with_position(pos.to_usize(), |this| ExpnData::decode(this))?; - recover_from_expn_data(self, expn_data, pos) + let (expn_data, transparency) = + self.with_position(pos.to_usize(), |this| Decodable::decode(this))?; + recover_from_expn_data(self, expn_data, transparency, pos) } } _ => { @@ -819,7 +819,7 @@ where if span_data.ctxt == SyntaxContext::root() { TAG_NO_EXPN_DATA.encode(self) } else { - let (expn_id, expn_data) = span_data.ctxt.outer_expn_with_data(); + let (expn_id, transparency, expn_data) = span_data.ctxt.outer_mark_with_data(); if let Some(pos) = self.expn_data_shorthands.get(&expn_id).cloned() { TAG_EXPN_DATA_SHORTHAND.encode(self)?; pos.encode(self) @@ -827,7 +827,7 @@ where TAG_EXPN_DATA_INLINE.encode(self)?; let pos = AbsoluteBytePos::new(self.position()); self.expn_data_shorthands.insert(expn_id, pos); - expn_data.encode(self) + (expn_data, transparency).encode(self) } } } diff --git a/src/librustc/ty/relate.rs b/src/librustc/ty/relate.rs index 945e3e158ea..565447dd7e1 100644 --- a/src/librustc/ty/relate.rs +++ b/src/librustc/ty/relate.rs @@ -8,7 +8,7 @@ use crate::hir::def_id::DefId; use crate::ty::subst::{Kind, UnpackedKind, SubstsRef}; use crate::ty::{self, Ty, TyCtxt, TypeFoldable}; use crate::ty::error::{ExpectedFound, TypeError}; -use crate::mir::interpret::{ConstValue, Scalar, GlobalId}; +use crate::mir::interpret::{ConstValue, Scalar}; use std::rc::Rc; use std::iter; use rustc_target::spec::abi; @@ -551,26 +551,8 @@ pub fn super_relate_consts<R: TypeRelation<'tcx>>( let tcx = relation.tcx(); let eagerly_eval = |x: &'tcx ty::Const<'tcx>| { - if let ConstValue::Unevaluated(def_id, substs) = x.val { - // FIXME(eddyb) get the right param_env. - let param_env = ty::ParamEnv::empty(); - if !substs.has_local_value() { - let instance = ty::Instance::resolve( - tcx.global_tcx(), - param_env, - def_id, - substs, - ); - if let Some(instance) = instance { - let cid = GlobalId { - instance, - promoted: None, - }; - if let Ok(ct) = tcx.const_eval(param_env.and(cid)) { - return ct.val; - } - } - } + if !x.val.has_local_value() { + return x.eval(tcx, relation.param_env()).val; } x.val }; diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs index 2b173068b38..da66fdf5b1b 100644 --- a/src/librustc/ty/sty.rs +++ b/src/librustc/ty/sty.rs @@ -2299,23 +2299,33 @@ impl<'tcx> Const<'tcx> { assert_eq!(self.ty, ty); // if `ty` does not depend on generic parameters, use an empty param_env let size = tcx.layout_of(param_env.with_reveal_all().and(ty)).ok()?.size; + self.eval(tcx, param_env).val.try_to_bits(size) + } + + #[inline] + pub fn eval( + &self, + tcx: TyCtxt<'tcx>, + param_env: ParamEnv<'tcx>, + ) -> &Const<'tcx> { + // FIXME(const_generics): this doesn't work right now, + // because it tries to relate an `Infer` to a `Param`. match self.val { - // FIXME(const_generics): this doesn't work right now, - // because it tries to relate an `Infer` to a `Param`. ConstValue::Unevaluated(did, substs) => { // if `substs` has no unresolved components, use and empty param_env let (param_env, substs) = param_env.with_reveal_all().and(substs).into_parts(); // try to resolve e.g. associated constants to their definition on an impl - let instance = ty::Instance::resolve(tcx, param_env, did, substs)?; + let instance = match ty::Instance::resolve(tcx, param_env, did, substs) { + Some(instance) => instance, + None => return self, + }; let gid = GlobalId { instance, promoted: None, }; - let evaluated = tcx.const_eval(param_env.and(gid)).ok()?; - evaluated.val.try_to_bits(size) + tcx.const_eval(param_env.and(gid)).unwrap_or(self) }, - // otherwise just extract a `ConstValue`'s bits if possible - _ => self.val.try_to_bits(size), + _ => self, } } diff --git a/src/librustc_driver/Cargo.toml b/src/librustc_driver/Cargo.toml index f7a423092ac..b030517e28e 100644 --- a/src/librustc_driver/Cargo.toml +++ b/src/librustc_driver/Cargo.toml @@ -20,6 +20,7 @@ rustc_data_structures = { path = "../librustc_data_structures" } errors = { path = "../librustc_errors", package = "rustc_errors" } rustc_metadata = { path = "../librustc_metadata" } rustc_mir = { path = "../librustc_mir" } +rustc_plugin = { path = "../librustc_plugin/deprecated" } # To get this in the sysroot rustc_plugin_impl = { path = "../librustc_plugin" } rustc_save_analysis = { path = "../librustc_save_analysis" } rustc_codegen_utils = { path = "../librustc_codegen_utils" } diff --git a/src/librustc_driver/args.rs b/src/librustc_driver/args.rs new file mode 100644 index 00000000000..0906d358bad --- /dev/null +++ b/src/librustc_driver/args.rs @@ -0,0 +1,53 @@ +use std::error; +use std::fmt; +use std::fs; +use std::io; +use std::str; +use std::sync::atomic::{AtomicBool, Ordering}; + +static USED_ARGSFILE_FEATURE: AtomicBool = AtomicBool::new(false); + +pub fn used_unstable_argsfile() -> bool { + USED_ARGSFILE_FEATURE.load(Ordering::Relaxed) +} + +pub fn arg_expand(arg: String) -> Result<Vec<String>, Error> { + if arg.starts_with("@") { + let path = &arg[1..]; + let file = match fs::read_to_string(path) { + Ok(file) => { + USED_ARGSFILE_FEATURE.store(true, Ordering::Relaxed); + file + } + Err(ref err) if err.kind() == io::ErrorKind::InvalidData => { + return Err(Error::Utf8Error(Some(path.to_string()))); + } + Err(err) => return Err(Error::IOError(path.to_string(), err)), + }; + Ok(file.lines().map(ToString::to_string).collect()) + } else { + Ok(vec![arg]) + } +} + +#[derive(Debug)] +pub enum Error { + Utf8Error(Option<String>), + IOError(String, io::Error), +} + +impl fmt::Display for Error { + fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Error::Utf8Error(None) => write!(fmt, "Utf8 error"), + Error::Utf8Error(Some(path)) => write!(fmt, "Utf8 error in {}", path), + Error::IOError(path, err) => write!(fmt, "IO Error: {}: {}", path, err), + } + } +} + +impl error::Error for Error { + fn description(&self) -> &'static str { + "argument error" + } +} diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index b19ea513b75..e7712ae115f 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -68,6 +68,7 @@ use syntax::symbol::sym; use syntax_pos::{DUMMY_SP, MultiSpan, FileName}; pub mod pretty; +mod args; /// Exit status code used for successful compilation and help output. pub const EXIT_SUCCESS: i32 = 0; @@ -141,14 +142,22 @@ impl Callbacks for TimePassesCallbacks { // See comments on CompilerCalls below for details about the callbacks argument. // The FileLoader provides a way to load files from sources other than the file system. pub fn run_compiler( - args: &[String], + at_args: &[String], callbacks: &mut (dyn Callbacks + Send), file_loader: Option<Box<dyn FileLoader + Send + Sync>>, emitter: Option<Box<dyn Write + Send>> ) -> interface::Result<()> { + let mut args = Vec::new(); + for arg in at_args { + match args::arg_expand(arg.clone()) { + Ok(arg) => args.extend(arg), + Err(err) => early_error(ErrorOutputType::default(), + &format!("Failed to load argument file: {}", err)), + } + } let diagnostic_output = emitter.map(|emitter| DiagnosticOutput::Raw(emitter)) .unwrap_or(DiagnosticOutput::Default); - let matches = match handle_options(args) { + let matches = match handle_options(&args) { Some(matches) => matches, None => return Ok(()), }; @@ -779,13 +788,19 @@ fn usage(verbose: bool, include_unstable_options: bool) { } else { "\n --help -v Print the full set of options rustc accepts" }; - println!("{}\nAdditional help: + let at_path = if verbose && nightly_options::is_nightly_build() { + " @path Read newline separated options from `path`\n" + } else { + "" + }; + println!("{options}{at_path}\nAdditional help: -C help Print codegen options -W help \ - Print 'lint' options and default settings{}{}\n", - options.usage(message), - nightly_help, - verbose_help); + Print 'lint' options and default settings{nightly}{verbose}\n", + options = options.usage(message), + at_path = at_path, + nightly = nightly_help, + verbose = verbose_help); } fn print_wall_help() { @@ -1010,6 +1025,12 @@ pub fn handle_options(args: &[String]) -> Option<getopts::Matches> { // (unstable option being used on stable) nightly_options::check_nightly_options(&matches, &config::rustc_optgroups()); + // Late check to see if @file was used without unstable options enabled + if crate::args::used_unstable_argsfile() && !nightly_options::is_unstable_enabled(&matches) { + early_error(ErrorOutputType::default(), + "@path is unstable - use -Z unstable-options to enable its use"); + } + if matches.opt_present("h") || matches.opt_present("help") { // Only show unstable options in --help if we accept unstable options. usage(matches.opt_present("verbose"), nightly_options::is_unstable_enabled(&matches)); @@ -1190,7 +1211,7 @@ pub fn main() { let result = report_ices_to_stderr_if_any(|| { let args = env::args_os().enumerate() .map(|(i, arg)| arg.into_string().unwrap_or_else(|arg| { - early_error(ErrorOutputType::default(), + early_error(ErrorOutputType::default(), &format!("Argument {} is not valid Unicode: {:?}", i, arg)) })) .collect::<Vec<_>>(); diff --git a/src/librustc_metadata/cstore.rs b/src/librustc_metadata/cstore.rs index 792922a1837..efc77699313 100644 --- a/src/librustc_metadata/cstore.rs +++ b/src/librustc_metadata/cstore.rs @@ -68,9 +68,9 @@ pub struct CrateMetadata { pub alloc_decoding_state: AllocDecodingState, // NOTE(eddyb) we pass `'static` to a `'tcx` parameter because this - // lifetime is only used behind `Lazy` / `LazySeq`, and therefore - // acts like an universal (`for<'tcx>`), that is paired up with - // whichever `TyCtxt` is being used to decode those values. + // lifetime is only used behind `Lazy`, and therefore acts like an + // universal (`for<'tcx>`), that is paired up with whichever `TyCtxt` + // is being used to decode those values. pub root: schema::CrateRoot<'static>, /// For each definition in this crate, we encode a key. When the @@ -80,7 +80,7 @@ pub struct CrateMetadata { /// compilation support. pub def_path_table: Lrc<DefPathTable>, - pub trait_impls: FxHashMap<(u32, DefIndex), schema::LazySeq<DefIndex>>, + pub trait_impls: FxHashMap<(u32, DefIndex), schema::Lazy<[DefIndex]>>, pub dep_kind: Lock<DepKind>, pub source: CrateSource, diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs index d29592a5d68..da96728d2de 100644 --- a/src/librustc_metadata/decoder.rs +++ b/src/librustc_metadata/decoder.rs @@ -134,14 +134,14 @@ impl<'a, 'tcx, T: Decodable> Lazy<T> { } } -impl<'a: 'x, 'tcx: 'x, 'x, T: Decodable> LazySeq<T> { +impl<'a: 'x, 'tcx: 'x, 'x, T: Decodable> Lazy<[T]> { pub fn decode<M: Metadata<'a, 'tcx>>( self, meta: M, ) -> impl ExactSizeIterator<Item = T> + Captures<'a> + Captures<'tcx> + 'x { let mut dcx = meta.decoder(self.position); dcx.lazy_state = LazyState::NodeStart(self.position); - (0..self.len).map(move |_| T::decode(&mut dcx).unwrap()) + (0..self.meta).map(move |_| T::decode(&mut dcx).unwrap()) } } @@ -154,10 +154,14 @@ impl<'a, 'tcx> DecodeContext<'a, 'tcx> { self.cdata.expect("missing CrateMetadata in DecodeContext") } - fn read_lazy_distance(&mut self, min_size: usize) -> Result<usize, <Self as Decoder>::Error> { + fn read_lazy_with_meta<T: ?Sized + LazyMeta>( + &mut self, + meta: T::Meta, + ) -> Result<Lazy<T>, <Self as Decoder>::Error> { + let min_size = T::min_size(meta); let distance = self.read_usize()?; let position = match self.lazy_state { - LazyState::NoNode => bug!("read_lazy_distance: outside of a metadata node"), + LazyState::NoNode => bug!("read_lazy_with_meta: outside of a metadata node"), LazyState::NodeStart(start) => { assert!(distance + min_size <= start); start - distance - min_size @@ -165,7 +169,7 @@ impl<'a, 'tcx> DecodeContext<'a, 'tcx> { LazyState::Previous(last_min_end) => last_min_end + distance, }; self.lazy_state = LazyState::Previous(position + min_size); - Ok(position) + Ok(Lazy::from_position_and_meta(position, meta)) } } @@ -230,19 +234,18 @@ impl<'a, 'tcx> TyDecoder<'tcx> for DecodeContext<'a, 'tcx> { impl<'a, 'tcx, T> SpecializedDecoder<Lazy<T>> for DecodeContext<'a, 'tcx> { fn specialized_decode(&mut self) -> Result<Lazy<T>, Self::Error> { - Ok(Lazy::with_position(self.read_lazy_distance(Lazy::<T>::min_size())?)) + self.read_lazy_with_meta(()) } } -impl<'a, 'tcx, T> SpecializedDecoder<LazySeq<T>> for DecodeContext<'a, 'tcx> { - fn specialized_decode(&mut self) -> Result<LazySeq<T>, Self::Error> { +impl<'a, 'tcx, T> SpecializedDecoder<Lazy<[T]>> for DecodeContext<'a, 'tcx> { + fn specialized_decode(&mut self) -> Result<Lazy<[T]>, Self::Error> { let len = self.read_usize()?; - let position = if len == 0 { - 0 + if len == 0 { + Ok(Lazy::empty()) } else { - self.read_lazy_distance(LazySeq::<T>::min_size(len))? - }; - Ok(LazySeq::with_position_and_length(position, len)) + self.read_lazy_with_meta(len) + } } } @@ -378,7 +381,7 @@ impl<'tcx> MetadataBlob { } pub fn get_rustc_version(&self) -> String { - Lazy::with_position(METADATA_HEADER.len() + 4).decode(self) + Lazy::<String>::from_position(METADATA_HEADER.len() + 4).decode(self) } pub fn get_root(&self) -> CrateRoot<'tcx> { @@ -387,7 +390,7 @@ impl<'tcx> MetadataBlob { let pos = (((slice[offset + 0] as u32) << 24) | ((slice[offset + 1] as u32) << 16) | ((slice[offset + 2] as u32) << 8) | ((slice[offset + 3] as u32) << 0)) as usize; - Lazy::with_position(pos).decode(self) + Lazy::<CrateRoot<'tcx>>::from_position(pos).decode(self) } pub fn list_crate_metadata(&self, @@ -1140,7 +1143,7 @@ impl<'a, 'tcx> CrateMetadata { EntryKind::Fn(data) | EntryKind::ForeignFn(data) => data.decode(self).arg_names, EntryKind::Method(data) => data.decode(self).fn_data.arg_names, - _ => LazySeq::empty(), + _ => Lazy::empty(), }; arg_names.decode(self).collect() } diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs index 6058ae99cf4..df3320c64a9 100644 --- a/src/librustc_metadata/encoder.rs +++ b/src/librustc_metadata/encoder.rs @@ -98,17 +98,17 @@ impl<'tcx> Encoder for EncodeContext<'tcx> { impl<'tcx, T> SpecializedEncoder<Lazy<T>> for EncodeContext<'tcx> { fn specialized_encode(&mut self, lazy: &Lazy<T>) -> Result<(), Self::Error> { - self.emit_lazy_distance(lazy.position, Lazy::<T>::min_size()) + self.emit_lazy_distance(*lazy) } } -impl<'tcx, T> SpecializedEncoder<LazySeq<T>> for EncodeContext<'tcx> { - fn specialized_encode(&mut self, seq: &LazySeq<T>) -> Result<(), Self::Error> { - self.emit_usize(seq.len)?; - if seq.len == 0 { +impl<'tcx, T> SpecializedEncoder<Lazy<[T]>> for EncodeContext<'tcx> { + fn specialized_encode(&mut self, lazy: &Lazy<[T]>) -> Result<(), Self::Error> { + self.emit_usize(lazy.meta)?; + if lazy.meta == 0 { return Ok(()); } - self.emit_lazy_distance(seq.position, LazySeq::<T>::min_size(seq.len)) + self.emit_lazy_distance(*lazy) } } @@ -239,21 +239,38 @@ impl<'tcx> TyEncoder for EncodeContext<'tcx> { } } -impl<'tcx> EncodeContext<'tcx> { - fn emit_node<F: FnOnce(&mut Self, usize) -> R, R>(&mut self, f: F) -> R { - assert_eq!(self.lazy_state, LazyState::NoNode); - let pos = self.position(); - self.lazy_state = LazyState::NodeStart(pos); - let r = f(self, pos); - self.lazy_state = LazyState::NoNode; - r +/// Helper trait to allow overloading `EncodeContext::lazy` for iterators. +trait EncodeContentsForLazy<T: ?Sized + LazyMeta> { + fn encode_contents_for_lazy(self, ecx: &mut EncodeContext<'tcx>) -> T::Meta; +} + +impl<T: Encodable> EncodeContentsForLazy<T> for &T { + fn encode_contents_for_lazy(self, ecx: &mut EncodeContext<'tcx>) { + self.encode(ecx).unwrap() + } +} + +impl<T: Encodable> EncodeContentsForLazy<T> for T { + fn encode_contents_for_lazy(self, ecx: &mut EncodeContext<'tcx>) { + self.encode(ecx).unwrap() + } +} + +impl<I, T> EncodeContentsForLazy<[T]> for I + where I: IntoIterator, + I::Item: EncodeContentsForLazy<T>, +{ + fn encode_contents_for_lazy(self, ecx: &mut EncodeContext<'tcx>) -> usize { + self.into_iter().map(|value| value.encode_contents_for_lazy(ecx)).count() } +} - fn emit_lazy_distance(&mut self, - position: usize, - min_size: usize) - -> Result<(), <Self as Encoder>::Error> { - let min_end = position + min_size; +impl<'tcx> EncodeContext<'tcx> { + fn emit_lazy_distance<T: ?Sized + LazyMeta>( + &mut self, + lazy: Lazy<T>, + ) -> Result<(), <Self as Encoder>::Error> { + let min_end = lazy.position + T::min_size(lazy.meta); let distance = match self.lazy_state { LazyState::NoNode => bug!("emit_lazy_distance: outside of a metadata node"), LazyState::NodeStart(start) => { @@ -262,48 +279,31 @@ impl<'tcx> EncodeContext<'tcx> { } LazyState::Previous(last_min_end) => { assert!( - last_min_end <= position, + last_min_end <= lazy.position, "make sure that the calls to `lazy*` \ are in the same order as the metadata fields", ); - position - last_min_end + lazy.position - last_min_end } }; self.lazy_state = LazyState::Previous(min_end); self.emit_usize(distance) } - pub fn lazy<T: Encodable>(&mut self, value: &T) -> Lazy<T> { - self.emit_node(|ecx, pos| { - value.encode(ecx).unwrap(); - - assert!(pos + Lazy::<T>::min_size() <= ecx.position()); - Lazy::with_position(pos) - }) - } - - pub fn lazy_seq<I, T>(&mut self, iter: I) -> LazySeq<T> - where I: IntoIterator<Item = T>, - T: Encodable - { - self.emit_node(|ecx, pos| { - let len = iter.into_iter().map(|value| value.encode(ecx).unwrap()).count(); + fn lazy<T: ?Sized + LazyMeta>( + &mut self, + value: impl EncodeContentsForLazy<T>, + ) -> Lazy<T> { + let pos = self.position(); - assert!(pos + LazySeq::<T>::min_size(len) <= ecx.position()); - LazySeq::with_position_and_length(pos, len) - }) - } + assert_eq!(self.lazy_state, LazyState::NoNode); + self.lazy_state = LazyState::NodeStart(pos); + let meta = value.encode_contents_for_lazy(self); + self.lazy_state = LazyState::NoNode; - pub fn lazy_seq_ref<'b, I, T>(&mut self, iter: I) -> LazySeq<T> - where I: IntoIterator<Item = &'b T>, - T: 'b + Encodable - { - self.emit_node(|ecx, pos| { - let len = iter.into_iter().map(|value| value.encode(ecx).unwrap()).count(); + assert!(pos + <T>::min_size(meta) <= self.position()); - assert!(pos + LazySeq::<T>::min_size(len) <= ecx.position()); - LazySeq::with_position_and_length(pos, len) - }) + Lazy::from_position_and_meta(pos, meta) } /// Emit the data for a `DefId` to the metadata. The function to @@ -320,7 +320,7 @@ impl<'tcx> EncodeContext<'tcx> { assert!(id.is_local()); let entry = op(self, data); - let entry = self.lazy(&entry); + let entry = self.lazy(entry); self.entries_index.record(id, entry); } @@ -341,7 +341,7 @@ impl<'tcx> EncodeContext<'tcx> { self.lazy(definitions.def_path_table()) } - fn encode_source_map(&mut self) -> LazySeq<syntax_pos::SourceFile> { + fn encode_source_map(&mut self) -> Lazy<[syntax_pos::SourceFile]> { let source_map = self.tcx.sess.source_map(); let all_source_files = source_map.files(); @@ -380,7 +380,7 @@ impl<'tcx> EncodeContext<'tcx> { }) .collect::<Vec<_>>(); - self.lazy_seq_ref(adapted.iter().map(|rc| &**rc)) + self.lazy(adapted.iter().map(|rc| &**rc)) } fn encode_crate_root(&mut self) -> Lazy<CrateRoot<'tcx>> { @@ -463,7 +463,7 @@ impl<'tcx> EncodeContext<'tcx> { } n = new_n; } - self.lazy_seq(interpret_alloc_index) + self.lazy(interpret_alloc_index) }; @@ -482,8 +482,7 @@ impl<'tcx> EncodeContext<'tcx> { let has_global_allocator = *tcx.sess.has_global_allocator.get(); let has_panic_handler = *tcx.sess.has_panic_handler.try_get().unwrap_or(&false); - - let root = self.lazy(&CrateRoot { + let root = self.lazy(CrateRoot { name: tcx.crate_name(LOCAL_CRATE), extra_filename: tcx.sess.opts.cg.extra_filename.clone(), triple: tcx.sess.opts.target_triple.clone(), @@ -562,17 +561,17 @@ impl<'tcx> EncodeContext<'tcx> { } impl EncodeContext<'tcx> { - fn encode_variances_of(&mut self, def_id: DefId) -> LazySeq<ty::Variance> { + fn encode_variances_of(&mut self, def_id: DefId) -> Lazy<[ty::Variance]> { debug!("EncodeContext::encode_variances_of({:?})", def_id); let tcx = self.tcx; - self.lazy_seq_ref(&tcx.variances_of(def_id)[..]) + self.lazy(&tcx.variances_of(def_id)[..]) } fn encode_item_type(&mut self, def_id: DefId) -> Lazy<Ty<'tcx>> { let tcx = self.tcx; let ty = tcx.type_of(def_id); debug!("EncodeContext::encode_item_type({:?}) => {:?}", def_id, ty); - self.lazy(&ty) + self.lazy(ty) } fn encode_enum_variant_info( @@ -601,11 +600,11 @@ impl EncodeContext<'tcx> { let enum_vis = &tcx.hir().expect_item(enum_id).vis; Entry { - kind: EntryKind::Variant(self.lazy(&data)), - visibility: self.lazy(&ty::Visibility::from_hir(enum_vis, enum_id, tcx)), - span: self.lazy(&tcx.def_span(def_id)), + kind: EntryKind::Variant(self.lazy(data)), + visibility: self.lazy(ty::Visibility::from_hir(enum_vis, enum_id, tcx)), + span: self.lazy(tcx.def_span(def_id)), attributes: self.encode_attributes(&tcx.get_attrs(def_id)), - children: self.lazy_seq(variant.fields.iter().map(|f| { + children: self.lazy(variant.fields.iter().map(|f| { assert!(f.did.is_local()); f.did.index })), @@ -613,11 +612,11 @@ impl EncodeContext<'tcx> { deprecation: self.encode_deprecation(def_id), ty: Some(self.encode_item_type(def_id)), - inherent_impls: LazySeq::empty(), + inherent_impls: Lazy::empty(), variances: if variant.ctor_kind == CtorKind::Fn { self.encode_variances_of(def_id) } else { - LazySeq::empty() + Lazy::empty() }, generics: Some(self.encode_generics(def_id)), predicates: Some(self.encode_predicates(def_id)), @@ -642,7 +641,7 @@ impl EncodeContext<'tcx> { discr: variant.discr, ctor: Some(def_id.index), ctor_sig: if variant.ctor_kind == CtorKind::Fn { - Some(self.lazy(&tcx.fn_sig(def_id))) + Some(self.lazy(tcx.fn_sig(def_id))) } else { None } @@ -658,20 +657,20 @@ impl EncodeContext<'tcx> { } Entry { - kind: EntryKind::Variant(self.lazy(&data)), - visibility: self.lazy(&ctor_vis), - span: self.lazy(&tcx.def_span(def_id)), - attributes: LazySeq::empty(), - children: LazySeq::empty(), + kind: EntryKind::Variant(self.lazy(data)), + visibility: self.lazy(ctor_vis), + span: self.lazy(tcx.def_span(def_id)), + attributes: Lazy::empty(), + children: Lazy::empty(), stability: self.encode_stability(def_id), deprecation: self.encode_deprecation(def_id), ty: Some(self.encode_item_type(def_id)), - inherent_impls: LazySeq::empty(), + inherent_impls: Lazy::empty(), variances: if variant.ctor_kind == CtorKind::Fn { self.encode_variances_of(def_id) } else { - LazySeq::empty() + Lazy::empty() }, generics: Some(self.encode_generics(def_id)), predicates: Some(self.encode_predicates(def_id)), @@ -691,25 +690,25 @@ impl EncodeContext<'tcx> { let data = ModData { reexports: match tcx.module_exports(def_id) { - Some(exports) => self.lazy_seq_ref(exports), - _ => LazySeq::empty(), + Some(exports) => self.lazy(exports), + _ => Lazy::empty(), }, }; Entry { - kind: EntryKind::Mod(self.lazy(&data)), - visibility: self.lazy(&ty::Visibility::from_hir(vis, id, tcx)), - span: self.lazy(&tcx.def_span(def_id)), + kind: EntryKind::Mod(self.lazy(data)), + visibility: self.lazy(ty::Visibility::from_hir(vis, id, tcx)), + span: self.lazy(tcx.def_span(def_id)), attributes: self.encode_attributes(attrs), - children: self.lazy_seq(md.item_ids.iter().map(|item_id| { + children: self.lazy(md.item_ids.iter().map(|item_id| { tcx.hir().local_def_id(item_id.id).index })), stability: self.encode_stability(def_id), deprecation: self.encode_deprecation(def_id), ty: None, - inherent_impls: LazySeq::empty(), - variances: LazySeq::empty(), + inherent_impls: Lazy::empty(), + variances: Lazy::empty(), generics: None, predicates: None, predicates_defined_on: None, @@ -734,16 +733,16 @@ impl EncodeContext<'tcx> { Entry { kind: EntryKind::Field, - visibility: self.lazy(&field.vis), - span: self.lazy(&tcx.def_span(def_id)), + visibility: self.lazy(field.vis), + span: self.lazy(tcx.def_span(def_id)), attributes: self.encode_attributes(&variant_data.fields()[field_index].attrs), - children: LazySeq::empty(), + children: Lazy::empty(), stability: self.encode_stability(def_id), deprecation: self.encode_deprecation(def_id), ty: Some(self.encode_item_type(def_id)), - inherent_impls: LazySeq::empty(), - variances: LazySeq::empty(), + inherent_impls: Lazy::empty(), + variances: Lazy::empty(), generics: Some(self.encode_generics(def_id)), predicates: Some(self.encode_predicates(def_id)), predicates_defined_on: None, @@ -763,7 +762,7 @@ impl EncodeContext<'tcx> { discr: variant.discr, ctor: Some(def_id.index), ctor_sig: if variant.ctor_kind == CtorKind::Fn { - Some(self.lazy(&tcx.fn_sig(def_id))) + Some(self.lazy(tcx.fn_sig(def_id))) } else { None } @@ -789,20 +788,20 @@ impl EncodeContext<'tcx> { let repr_options = get_repr_options(tcx, adt_def_id); Entry { - kind: EntryKind::Struct(self.lazy(&data), repr_options), - visibility: self.lazy(&ctor_vis), - span: self.lazy(&tcx.def_span(def_id)), - attributes: LazySeq::empty(), - children: LazySeq::empty(), + kind: EntryKind::Struct(self.lazy(data), repr_options), + visibility: self.lazy(ctor_vis), + span: self.lazy(tcx.def_span(def_id)), + attributes: Lazy::empty(), + children: Lazy::empty(), stability: self.encode_stability(def_id), deprecation: self.encode_deprecation(def_id), ty: Some(self.encode_item_type(def_id)), - inherent_impls: LazySeq::empty(), + inherent_impls: Lazy::empty(), variances: if variant.ctor_kind == CtorKind::Fn { self.encode_variances_of(def_id) } else { - LazySeq::empty() + Lazy::empty() }, generics: Some(self.encode_generics(def_id)), predicates: Some(self.encode_predicates(def_id)), @@ -821,13 +820,13 @@ impl EncodeContext<'tcx> { fn encode_predicates(&mut self, def_id: DefId) -> Lazy<ty::GenericPredicates<'tcx>> { debug!("EncodeContext::encode_predicates({:?})", def_id); let tcx = self.tcx; - self.lazy(&tcx.predicates_of(def_id)) + self.lazy(&*tcx.predicates_of(def_id)) } fn encode_predicates_defined_on(&mut self, def_id: DefId) -> Lazy<ty::GenericPredicates<'tcx>> { debug!("EncodeContext::encode_predicates_defined_on({:?})", def_id); let tcx = self.tcx; - self.lazy(&tcx.predicates_defined_on(def_id)) + self.lazy(&*tcx.predicates_defined_on(def_id)) } fn encode_info_for_trait_item(&mut self, def_id: DefId) -> Entry<'tcx> { @@ -858,7 +857,7 @@ impl EncodeContext<'tcx> { let rendered = hir::print::to_string(self.tcx.hir(), |s| s.print_trait_item(ast_item)); - let rendered_const = self.lazy(&RenderedConst(rendered)); + let rendered_const = self.lazy(RenderedConst(rendered)); EntryKind::AssocConst(container, const_qualif, rendered_const) } @@ -875,12 +874,12 @@ impl EncodeContext<'tcx> { FnData { constness: hir::Constness::NotConst, arg_names, - sig: self.lazy(&tcx.fn_sig(def_id)), + sig: self.lazy(tcx.fn_sig(def_id)), } } else { bug!() }; - EntryKind::Method(self.lazy(&MethodData { + EntryKind::Method(self.lazy(MethodData { fn_data, container, has_self: trait_item.method_has_self_argument, @@ -892,10 +891,10 @@ impl EncodeContext<'tcx> { Entry { kind, - visibility: self.lazy(&trait_item.vis), - span: self.lazy(&ast_item.span), + visibility: self.lazy(trait_item.vis), + span: self.lazy(ast_item.span), attributes: self.encode_attributes(&ast_item.attrs), - children: LazySeq::empty(), + children: Lazy::empty(), stability: self.encode_stability(def_id), deprecation: self.encode_deprecation(def_id), @@ -913,11 +912,11 @@ impl EncodeContext<'tcx> { } ty::AssocKind::OpaqueTy => unreachable!(), }, - inherent_impls: LazySeq::empty(), + inherent_impls: Lazy::empty(), variances: if trait_item.kind == ty::AssocKind::Method { self.encode_variances_of(def_id) } else { - LazySeq::empty() + Lazy::empty() }, generics: Some(self.encode_generics(def_id)), predicates: Some(self.encode_predicates(def_id)), @@ -971,12 +970,12 @@ impl EncodeContext<'tcx> { FnData { constness: sig.header.constness, arg_names: self.encode_fn_arg_names_for_body(body), - sig: self.lazy(&tcx.fn_sig(def_id)), + sig: self.lazy(tcx.fn_sig(def_id)), } } else { bug!() }; - EntryKind::Method(self.lazy(&MethodData { + EntryKind::Method(self.lazy(MethodData { fn_data, container, has_self: impl_item.method_has_self_argument, @@ -1004,19 +1003,19 @@ impl EncodeContext<'tcx> { Entry { kind, - visibility: self.lazy(&impl_item.vis), - span: self.lazy(&ast_item.span), + visibility: self.lazy(impl_item.vis), + span: self.lazy(ast_item.span), attributes: self.encode_attributes(&ast_item.attrs), - children: LazySeq::empty(), + children: Lazy::empty(), stability: self.encode_stability(def_id), deprecation: self.encode_deprecation(def_id), ty: Some(self.encode_item_type(def_id)), - inherent_impls: LazySeq::empty(), + inherent_impls: Lazy::empty(), variances: if impl_item.kind == ty::AssocKind::Method { self.encode_variances_of(def_id) } else { - LazySeq::empty() + Lazy::empty() }, generics: Some(self.encode_generics(def_id)), predicates: Some(self.encode_predicates(def_id)), @@ -1027,10 +1026,10 @@ impl EncodeContext<'tcx> { } fn encode_fn_arg_names_for_body(&mut self, body_id: hir::BodyId) - -> LazySeq<ast::Name> { + -> Lazy<[ast::Name]> { self.tcx.dep_graph.with_ignore(|| { let body = self.tcx.hir().body(body_id); - self.lazy_seq(body.arguments.iter().map(|arg| { + self.lazy(body.arguments.iter().map(|arg| { match arg.pat.node { PatKind::Binding(_, _, ident, _) => ident.name, _ => kw::Invalid, @@ -1039,28 +1038,28 @@ impl EncodeContext<'tcx> { }) } - fn encode_fn_arg_names(&mut self, param_names: &[ast::Ident]) -> LazySeq<ast::Name> { - self.lazy_seq(param_names.iter().map(|ident| ident.name)) + fn encode_fn_arg_names(&mut self, param_names: &[ast::Ident]) -> Lazy<[ast::Name]> { + self.lazy(param_names.iter().map(|ident| ident.name)) } fn encode_optimized_mir(&mut self, def_id: DefId) -> Option<Lazy<mir::Body<'tcx>>> { debug!("EntryBuilder::encode_mir({:?})", def_id); if self.tcx.mir_keys(LOCAL_CRATE).contains(&def_id) { let mir = self.tcx.optimized_mir(def_id); - Some(self.lazy(&mir)) + Some(self.lazy(mir)) } else { None } } // Encodes the inherent implementations of a structure, enumeration, or trait. - fn encode_inherent_implementations(&mut self, def_id: DefId) -> LazySeq<DefIndex> { + fn encode_inherent_implementations(&mut self, def_id: DefId) -> Lazy<[DefIndex]> { debug!("EncodeContext::encode_inherent_implementations({:?})", def_id); let implementations = self.tcx.inherent_impls(def_id); if implementations.is_empty() { - LazySeq::empty() + Lazy::empty() } else { - self.lazy_seq(implementations.iter().map(|&def_id| { + self.lazy(implementations.iter().map(|&def_id| { assert!(def_id.is_local()); def_id.index })) @@ -1074,7 +1073,7 @@ impl EncodeContext<'tcx> { fn encode_deprecation(&mut self, def_id: DefId) -> Option<Lazy<attr::Deprecation>> { debug!("EncodeContext::encode_deprecation({:?})", def_id); - self.tcx.lookup_deprecation(def_id).map(|depr| self.lazy(&depr)) + self.tcx.lookup_deprecation(def_id).map(|depr| self.lazy(depr)) } fn encode_rendered_const_for_body(&mut self, body_id: hir::BodyId) -> Lazy<RenderedConst> { @@ -1103,10 +1102,10 @@ impl EncodeContext<'tcx> { let data = FnData { constness: header.constness, arg_names: self.encode_fn_arg_names_for_body(body), - sig: self.lazy(&tcx.fn_sig(def_id)), + sig: self.lazy(tcx.fn_sig(def_id)), }; - EntryKind::Fn(self.lazy(&data)) + EntryKind::Fn(self.lazy(data)) } hir::ItemKind::Mod(ref m) => { return self.encode_info_for_mod((item.hir_id, m, &item.attrs, &item.vis)); @@ -1127,7 +1126,7 @@ impl EncodeContext<'tcx> { let repr_options = get_repr_options(tcx, def_id); - EntryKind::Struct(self.lazy(&VariantData { + EntryKind::Struct(self.lazy(VariantData { ctor_kind: variant.ctor_kind, discr: variant.discr, ctor, @@ -1138,7 +1137,7 @@ impl EncodeContext<'tcx> { let variant = tcx.adt_def(def_id).non_enum_variant(); let repr_options = get_repr_options(tcx, def_id); - EntryKind::Union(self.lazy(&VariantData { + EntryKind::Union(self.lazy(VariantData { ctor_kind: variant.ctor_kind, discr: variant.discr, ctor: None, @@ -1175,10 +1174,10 @@ impl EncodeContext<'tcx> { defaultness, parent_impl: parent, coerce_unsized_info, - trait_ref: trait_ref.map(|trait_ref| self.lazy(&trait_ref)), + trait_ref: trait_ref.map(|trait_ref| self.lazy(trait_ref)), }; - EntryKind::Impl(self.lazy(&data)) + EntryKind::Impl(self.lazy(data)) } hir::ItemKind::Trait(..) => { let trait_def = tcx.trait_def(def_id); @@ -1187,17 +1186,17 @@ impl EncodeContext<'tcx> { paren_sugar: trait_def.paren_sugar, has_auto_impl: tcx.trait_is_auto(def_id), is_marker: trait_def.is_marker, - super_predicates: self.lazy(&tcx.super_predicates_of(def_id)), + super_predicates: self.lazy(&*tcx.super_predicates_of(def_id)), }; - EntryKind::Trait(self.lazy(&data)) + EntryKind::Trait(self.lazy(data)) } hir::ItemKind::TraitAlias(..) => { let data = TraitAliasData { - super_predicates: self.lazy(&tcx.super_predicates_of(def_id)), + super_predicates: self.lazy(&*tcx.super_predicates_of(def_id)), }; - EntryKind::TraitAlias(self.lazy(&data)) + EntryKind::TraitAlias(self.lazy(data)) } hir::ItemKind::ExternCrate(_) | hir::ItemKind::Use(..) => bug!("cannot encode info for item {:?}", item), @@ -1205,19 +1204,19 @@ impl EncodeContext<'tcx> { Entry { kind, - visibility: self.lazy(&ty::Visibility::from_hir(&item.vis, item.hir_id, tcx)), - span: self.lazy(&item.span), + visibility: self.lazy(ty::Visibility::from_hir(&item.vis, item.hir_id, tcx)), + span: self.lazy(item.span), attributes: self.encode_attributes(&item.attrs), children: match item.node { hir::ItemKind::ForeignMod(ref fm) => { - self.lazy_seq(fm.items + self.lazy(fm.items .iter() .map(|foreign_item| tcx.hir().local_def_id( foreign_item.hir_id).index)) } hir::ItemKind::Enum(..) => { let def = self.tcx.adt_def(def_id); - self.lazy_seq(def.variants.iter().map(|v| { + self.lazy(def.variants.iter().map(|v| { assert!(v.def_id.is_local()); v.def_id.index })) @@ -1225,19 +1224,19 @@ impl EncodeContext<'tcx> { hir::ItemKind::Struct(..) | hir::ItemKind::Union(..) => { let def = self.tcx.adt_def(def_id); - self.lazy_seq(def.non_enum_variant().fields.iter().map(|f| { + self.lazy(def.non_enum_variant().fields.iter().map(|f| { assert!(f.did.is_local()); f.did.index })) } hir::ItemKind::Impl(..) | hir::ItemKind::Trait(..) => { - self.lazy_seq(tcx.associated_item_def_ids(def_id).iter().map(|&def_id| { + self.lazy(tcx.associated_item_def_ids(def_id).iter().map(|&def_id| { assert!(def_id.is_local()); def_id.index })) } - _ => LazySeq::empty(), + _ => Lazy::empty(), }, stability: self.encode_stability(def_id), deprecation: self.encode_deprecation(def_id), @@ -1260,7 +1259,7 @@ impl EncodeContext<'tcx> { hir::ItemKind::Struct(..) | hir::ItemKind::Union(..) | hir::ItemKind::Fn(..) => self.encode_variances_of(def_id), - _ => LazySeq::empty(), + _ => Lazy::empty(), }, generics: match item.node { hir::ItemKind::Static(..) | @@ -1333,20 +1332,20 @@ impl EncodeContext<'tcx> { use syntax::print::pprust; let def_id = self.tcx.hir().local_def_id(macro_def.hir_id); Entry { - kind: EntryKind::MacroDef(self.lazy(&MacroDef { + kind: EntryKind::MacroDef(self.lazy(MacroDef { body: pprust::tokens_to_string(macro_def.body.clone()), legacy: macro_def.legacy, })), - visibility: self.lazy(&ty::Visibility::Public), - span: self.lazy(¯o_def.span), + visibility: self.lazy(ty::Visibility::Public), + span: self.lazy(macro_def.span), attributes: self.encode_attributes(¯o_def.attrs), stability: self.encode_stability(def_id), deprecation: self.encode_deprecation(def_id), - children: LazySeq::empty(), + children: Lazy::empty(), ty: None, - inherent_impls: LazySeq::empty(), - variances: LazySeq::empty(), + inherent_impls: Lazy::empty(), + variances: Lazy::empty(), generics: None, predicates: None, predicates_defined_on: None, @@ -1363,15 +1362,15 @@ impl EncodeContext<'tcx> { let tcx = self.tcx; Entry { kind: entry_kind, - visibility: self.lazy(&ty::Visibility::Public), - span: self.lazy(&tcx.def_span(def_id)), - attributes: LazySeq::empty(), - children: LazySeq::empty(), + visibility: self.lazy(ty::Visibility::Public), + span: self.lazy(tcx.def_span(def_id)), + attributes: Lazy::empty(), + children: Lazy::empty(), stability: None, deprecation: None, ty: if encode_type { Some(self.encode_item_type(def_id)) } else { None }, - inherent_impls: LazySeq::empty(), - variances: LazySeq::empty(), + inherent_impls: Lazy::empty(), + variances: Lazy::empty(), generics: None, predicates: None, predicates_defined_on: None, @@ -1408,13 +1407,13 @@ impl EncodeContext<'tcx> { let data = GeneratorData { layout: layout.clone(), }; - EntryKind::Generator(self.lazy(&data)) + EntryKind::Generator(self.lazy(data)) } ty::Closure(def_id, substs) => { let sig = substs.closure_sig(def_id, self.tcx); - let data = ClosureData { sig: self.lazy(&sig) }; - EntryKind::Closure(self.lazy(&data)) + let data = ClosureData { sig: self.lazy(sig) }; + EntryKind::Closure(self.lazy(data)) } _ => bug!("closure that is neither generator nor closure") @@ -1422,16 +1421,16 @@ impl EncodeContext<'tcx> { Entry { kind, - visibility: self.lazy(&ty::Visibility::Public), - span: self.lazy(&tcx.def_span(def_id)), + visibility: self.lazy(ty::Visibility::Public), + span: self.lazy(tcx.def_span(def_id)), attributes: self.encode_attributes(&tcx.get_attrs(def_id)), - children: LazySeq::empty(), + children: Lazy::empty(), stability: None, deprecation: None, ty: Some(self.encode_item_type(def_id)), - inherent_impls: LazySeq::empty(), - variances: LazySeq::empty(), + inherent_impls: Lazy::empty(), + variances: Lazy::empty(), generics: Some(self.encode_generics(def_id)), predicates: None, predicates_defined_on: None, @@ -1450,16 +1449,16 @@ impl EncodeContext<'tcx> { Entry { kind: EntryKind::Const(self.const_qualif(mir, body_id), const_data), - visibility: self.lazy(&ty::Visibility::Public), - span: self.lazy(&tcx.def_span(def_id)), - attributes: LazySeq::empty(), - children: LazySeq::empty(), + visibility: self.lazy(ty::Visibility::Public), + span: self.lazy(tcx.def_span(def_id)), + attributes: Lazy::empty(), + children: Lazy::empty(), stability: None, deprecation: None, ty: Some(self.encode_item_type(def_id)), - inherent_impls: LazySeq::empty(), - variances: LazySeq::empty(), + inherent_impls: Lazy::empty(), + variances: Lazy::empty(), generics: Some(self.encode_generics(def_id)), predicates: Some(self.encode_predicates(def_id)), predicates_defined_on: None, @@ -1468,37 +1467,37 @@ impl EncodeContext<'tcx> { } } - fn encode_attributes(&mut self, attrs: &[ast::Attribute]) -> LazySeq<ast::Attribute> { - self.lazy_seq_ref(attrs) + fn encode_attributes(&mut self, attrs: &[ast::Attribute]) -> Lazy<[ast::Attribute]> { + self.lazy(attrs) } - fn encode_native_libraries(&mut self) -> LazySeq<NativeLibrary> { + fn encode_native_libraries(&mut self) -> Lazy<[NativeLibrary]> { let used_libraries = self.tcx.native_libraries(LOCAL_CRATE); - self.lazy_seq(used_libraries.iter().cloned()) + self.lazy(used_libraries.iter().cloned()) } - fn encode_foreign_modules(&mut self) -> LazySeq<ForeignModule> { + fn encode_foreign_modules(&mut self) -> Lazy<[ForeignModule]> { let foreign_modules = self.tcx.foreign_modules(LOCAL_CRATE); - self.lazy_seq(foreign_modules.iter().cloned()) + self.lazy(foreign_modules.iter().cloned()) } - fn encode_proc_macros(&mut self) -> Option<LazySeq<DefIndex>> { + fn encode_proc_macros(&mut self) -> Option<Lazy<[DefIndex]>> { let is_proc_macro = self.tcx.sess.crate_types.borrow().contains(&CrateType::ProcMacro); if is_proc_macro { - let proc_macros: Vec<_> = self.tcx.hir().krate().items.values().filter_map(|item| { + let tcx = self.tcx; + Some(self.lazy(tcx.hir().krate().items.values().filter_map(|item| { if item.attrs.iter().any(|attr| is_proc_macro_attr(attr)) { Some(item.hir_id.owner) } else { None } - }).collect(); - Some(self.lazy_seq(proc_macros)) + }))) } else { None } } - fn encode_crate_deps(&mut self) -> LazySeq<CrateDep> { + fn encode_crate_deps(&mut self) -> Lazy<[CrateDep]> { let crates = self.tcx.crates(); let mut deps = crates @@ -1529,20 +1528,20 @@ impl EncodeContext<'tcx> { // the assumption that they are numbered 1 to n. // FIXME (#2166): This is not nearly enough to support correct versioning // but is enough to get transitive crate dependencies working. - self.lazy_seq_ref(deps.iter().map(|&(_, ref dep)| dep)) + self.lazy(deps.iter().map(|&(_, ref dep)| dep)) } - fn encode_lib_features(&mut self) -> LazySeq<(ast::Name, Option<ast::Name>)> { + fn encode_lib_features(&mut self) -> Lazy<[(ast::Name, Option<ast::Name>)]> { let tcx = self.tcx; let lib_features = tcx.lib_features(); - self.lazy_seq(lib_features.to_vec()) + self.lazy(lib_features.to_vec()) } - fn encode_lang_items(&mut self) -> LazySeq<(DefIndex, usize)> { + fn encode_lang_items(&mut self) -> Lazy<[(DefIndex, usize)]> { let tcx = self.tcx; let lang_items = tcx.lang_items(); let lang_items = lang_items.items().iter(); - self.lazy_seq(lang_items.enumerate().filter_map(|(i, &opt_def_id)| { + self.lazy(lang_items.enumerate().filter_map(|(i, &opt_def_id)| { if let Some(def_id) = opt_def_id { if def_id.is_local() { return Some((def_id.index, i)); @@ -1552,13 +1551,13 @@ impl EncodeContext<'tcx> { })) } - fn encode_lang_items_missing(&mut self) -> LazySeq<lang_items::LangItem> { + fn encode_lang_items_missing(&mut self) -> Lazy<[lang_items::LangItem]> { let tcx = self.tcx; - self.lazy_seq_ref(&tcx.lang_items().missing) + self.lazy(&tcx.lang_items().missing) } /// Encodes an index, mapping each trait to its (local) implementations. - fn encode_impls(&mut self) -> LazySeq<TraitImpls> { + fn encode_impls(&mut self) -> Lazy<[TraitImpls]> { debug!("EncodeContext::encode_impls()"); let tcx = self.tcx; let mut visitor = ImplVisitor { @@ -1584,12 +1583,12 @@ impl EncodeContext<'tcx> { TraitImpls { trait_id: (trait_def_id.krate.as_u32(), trait_def_id.index), - impls: self.lazy_seq_ref(&impls), + impls: self.lazy(&impls), } }) .collect(); - self.lazy_seq_ref(&all_impls) + self.lazy(&all_impls) } // Encodes all symbols exported from this crate into the metadata. @@ -1600,12 +1599,12 @@ impl EncodeContext<'tcx> { // definition (as that's not defined in this crate). fn encode_exported_symbols(&mut self, exported_symbols: &[(ExportedSymbol<'tcx>, SymbolExportLevel)]) - -> LazySeq<(ExportedSymbol<'tcx>, SymbolExportLevel)> { + -> Lazy<[(ExportedSymbol<'tcx>, SymbolExportLevel)]> { // The metadata symbol name is special. It should not show up in // downstream crates. let metadata_symbol_name = SymbolName::new(&metadata_symbol_name(self.tcx)); - self.lazy_seq(exported_symbols + self.lazy(exported_symbols .iter() .filter(|&&(ref exported_symbol, _)| { match *exported_symbol { @@ -1618,10 +1617,10 @@ impl EncodeContext<'tcx> { .cloned()) } - fn encode_dylib_dependency_formats(&mut self) -> LazySeq<Option<LinkagePreference>> { + fn encode_dylib_dependency_formats(&mut self) -> Lazy<[Option<LinkagePreference>]> { match self.tcx.sess.dependency_formats.borrow().get(&config::CrateType::Dylib) { Some(arr) => { - self.lazy_seq(arr.iter().map(|slot| { + self.lazy(arr.iter().map(|slot| { match *slot { Linkage::NotLinked | Linkage::IncludedFromDylib => None, @@ -1631,7 +1630,7 @@ impl EncodeContext<'tcx> { } })) } - None => LazySeq::empty(), + None => Lazy::empty(), } } @@ -1647,9 +1646,9 @@ impl EncodeContext<'tcx> { let data = FnData { constness: hir::Constness::NotConst, arg_names: self.encode_fn_arg_names(names), - sig: self.lazy(&tcx.fn_sig(def_id)), + sig: self.lazy(tcx.fn_sig(def_id)), }; - EntryKind::ForeignFn(self.lazy(&data)) + EntryKind::ForeignFn(self.lazy(data)) } hir::ForeignItemKind::Static(_, hir::MutMutable) => EntryKind::ForeignMutStatic, hir::ForeignItemKind::Static(_, hir::MutImmutable) => EntryKind::ForeignImmStatic, @@ -1658,18 +1657,18 @@ impl EncodeContext<'tcx> { Entry { kind, - visibility: self.lazy(&ty::Visibility::from_hir(&nitem.vis, nitem.hir_id, tcx)), - span: self.lazy(&nitem.span), + visibility: self.lazy(ty::Visibility::from_hir(&nitem.vis, nitem.hir_id, tcx)), + span: self.lazy(nitem.span), attributes: self.encode_attributes(&nitem.attrs), - children: LazySeq::empty(), + children: Lazy::empty(), stability: self.encode_stability(def_id), deprecation: self.encode_deprecation(def_id), ty: Some(self.encode_item_type(def_id)), - inherent_impls: LazySeq::empty(), + inherent_impls: Lazy::empty(), variances: match nitem.node { hir::ForeignItemKind::Fn(..) => self.encode_variances_of(def_id), - _ => LazySeq::empty(), + _ => Lazy::empty(), }, generics: Some(self.encode_generics(def_id)), predicates: Some(self.encode_predicates(def_id)), diff --git a/src/librustc_metadata/index.rs b/src/librustc_metadata/index.rs index dd2f59922ef..6f248f22cf2 100644 --- a/src/librustc_metadata/index.rs +++ b/src/librustc_metadata/index.rs @@ -108,18 +108,18 @@ impl Index<'tcx> { position.write_to_bytes_at(positions, array_index) } - pub fn write_index(&self, buf: &mut Encoder) -> LazySeq<Self> { + pub fn write_index(&self, buf: &mut Encoder) -> Lazy<[Self]> { let pos = buf.position(); // First we write the length of the lower range ... buf.emit_raw_bytes(&(self.positions.len() as u32 / 4).to_le_bytes()); // ... then the values. buf.emit_raw_bytes(&self.positions); - LazySeq::with_position_and_length(pos as usize, self.positions.len() / 4 + 1) + Lazy::from_position_and_meta(pos as usize, self.positions.len() / 4 + 1) } } -impl LazySeq<Index<'tcx>> { +impl Lazy<[Index<'tcx>]> { /// Given the metadata, extract out the offset of a particular /// DefIndex (if any). #[inline(never)] @@ -127,7 +127,7 @@ impl LazySeq<Index<'tcx>> { let bytes = &bytes[self.position..]; debug!("Index::lookup: index={:?} len={:?}", def_index, - self.len); + self.meta); let position = u32::read_from_bytes_at(bytes, 1 + def_index.index()); if position == u32::MAX { @@ -135,7 +135,7 @@ impl LazySeq<Index<'tcx>> { None } else { debug!("Index::lookup: position={:?}", position); - Some(Lazy::with_position(position as usize)) + Some(Lazy::from_position(position as usize)) } } } diff --git a/src/librustc_metadata/schema.rs b/src/librustc_metadata/schema.rs index 13c599cf997..f37877b437e 100644 --- a/src/librustc_metadata/schema.rs +++ b/src/librustc_metadata/schema.rs @@ -41,6 +41,33 @@ pub const METADATA_VERSION: u8 = 4; pub const METADATA_HEADER: &[u8; 12] = &[0, 0, 0, 0, b'r', b'u', b's', b't', 0, 0, 0, METADATA_VERSION]; +/// Additional metadata for a `Lazy<T>` where `T` may not be `Sized`, +/// e.g. for `Lazy<[T]>`, this is the length (count of `T` values). +pub trait LazyMeta { + type Meta: Copy + 'static; + + /// Returns the minimum encoded size. + // FIXME(eddyb) Give better estimates for certain types. + fn min_size(meta: Self::Meta) -> usize; +} + +impl<T> LazyMeta for T { + type Meta = (); + + fn min_size(_: ()) -> usize { + assert_ne!(std::mem::size_of::<T>(), 0); + 1 + } +} + +impl<T> LazyMeta for [T] { + type Meta = usize; + + fn min_size(len: usize) -> usize { + len * T::min_size(()) + } +} + /// A value of type T referred to by its absolute position /// in the metadata, and which can be decoded lazily. /// @@ -56,40 +83,8 @@ pub const METADATA_HEADER: &[u8; 12] = /// Distances start at 1, as 0-byte nodes are invalid. /// Also invalid are nodes being referred in a different /// order than they were encoded in. -#[must_use] -pub struct Lazy<T> { - pub position: usize, - _marker: PhantomData<T>, -} - -impl<T> Lazy<T> { - pub fn with_position(position: usize) -> Lazy<T> { - Lazy { - position, - _marker: PhantomData, - } - } - - /// Returns the minimum encoded size of a value of type `T`. - // FIXME(eddyb) Give better estimates for certain types. - pub fn min_size() -> usize { - 1 - } -} - -impl<T> Copy for Lazy<T> {} -impl<T> Clone for Lazy<T> { - fn clone(&self) -> Self { - *self - } -} - -impl<T> rustc_serialize::UseSpecializedEncodable for Lazy<T> {} -impl<T> rustc_serialize::UseSpecializedDecodable for Lazy<T> {} - -/// A sequence of type T referred to by its absolute position -/// in the metadata and length, and which can be decoded lazily. -/// The sequence is a single node for the purposes of `Lazy`. +/// +/// # Sequences (`Lazy<[T]>`) /// /// Unlike `Lazy<Vec<T>>`, the length is encoded next to the /// position, not at the position, which means that the length @@ -100,54 +95,62 @@ impl<T> rustc_serialize::UseSpecializedDecodable for Lazy<T> {} /// the minimal distance the length of the sequence, i.e. /// it's assumed there's no 0-byte element in the sequence. #[must_use] -pub struct LazySeq<T> { - pub len: usize, +// FIXME(#59875) the `Meta` parameter only exists to dodge +// invariance wrt `T` (coming from the `meta: T::Meta` field). +pub struct Lazy<T, Meta = <T as LazyMeta>::Meta> + where T: ?Sized + LazyMeta<Meta = Meta>, + Meta: 'static + Copy, +{ pub position: usize, + pub meta: Meta, _marker: PhantomData<T>, } -impl<T> LazySeq<T> { - pub fn empty() -> LazySeq<T> { - LazySeq::with_position_and_length(0, 0) - } - - pub fn with_position_and_length(position: usize, len: usize) -> LazySeq<T> { - LazySeq { - len, +impl<T: ?Sized + LazyMeta> Lazy<T> { + pub fn from_position_and_meta(position: usize, meta: T::Meta) -> Lazy<T> { + Lazy { position, + meta, _marker: PhantomData, } } +} + +impl<T> Lazy<T> { + pub fn from_position(position: usize) -> Lazy<T> { + Lazy::from_position_and_meta(position, ()) + } +} - /// Returns the minimum encoded size of `length` values of type `T`. - pub fn min_size(length: usize) -> usize { - length +impl<T> Lazy<[T]> { + pub fn empty() -> Lazy<[T]> { + Lazy::from_position_and_meta(0, 0) } } -impl<T> Copy for LazySeq<T> {} -impl<T> Clone for LazySeq<T> { +impl<T: ?Sized + LazyMeta> Copy for Lazy<T> {} +impl<T: ?Sized + LazyMeta> Clone for Lazy<T> { fn clone(&self) -> Self { *self } } -impl<T> rustc_serialize::UseSpecializedEncodable for LazySeq<T> {} -impl<T> rustc_serialize::UseSpecializedDecodable for LazySeq<T> {} +impl<T: ?Sized + LazyMeta> rustc_serialize::UseSpecializedEncodable for Lazy<T> {} +impl<T: ?Sized + LazyMeta> rustc_serialize::UseSpecializedDecodable for Lazy<T> {} -/// Encoding / decoding state for `Lazy` and `LazySeq`. +/// Encoding / decoding state for `Lazy`. #[derive(Copy, Clone, PartialEq, Eq, Debug)] pub enum LazyState { /// Outside of a metadata node. NoNode, - /// Inside a metadata node, and before any `Lazy` or `LazySeq`. + /// Inside a metadata node, and before any `Lazy`. /// The position is that of the node itself. NodeStart(usize), - /// Inside a metadata node, with a previous `Lazy` or `LazySeq`. + /// Inside a metadata node, with a previous `Lazy`. /// The position is a conservative estimate of where that - /// previous `Lazy` / `LazySeq` would end (see their comments). + /// previous `Lazy` would end (see their comments). Previous(usize), } @@ -167,24 +170,24 @@ pub struct CrateRoot<'tcx> { pub proc_macro_decls_static: Option<DefIndex>, pub proc_macro_stability: Option<attr::Stability>, - pub crate_deps: LazySeq<CrateDep>, - pub dylib_dependency_formats: LazySeq<Option<LinkagePreference>>, - pub lib_features: LazySeq<(Symbol, Option<Symbol>)>, - pub lang_items: LazySeq<(DefIndex, usize)>, - pub lang_items_missing: LazySeq<lang_items::LangItem>, - pub native_libraries: LazySeq<NativeLibrary>, - pub foreign_modules: LazySeq<ForeignModule>, - pub source_map: LazySeq<syntax_pos::SourceFile>, + pub crate_deps: Lazy<[CrateDep]>, + pub dylib_dependency_formats: Lazy<[Option<LinkagePreference>]>, + pub lib_features: Lazy<[(Symbol, Option<Symbol>)]>, + pub lang_items: Lazy<[(DefIndex, usize)]>, + pub lang_items_missing: Lazy<[lang_items::LangItem]>, + pub native_libraries: Lazy<[NativeLibrary]>, + pub foreign_modules: Lazy<[ForeignModule]>, + pub source_map: Lazy<[syntax_pos::SourceFile]>, pub def_path_table: Lazy<hir::map::definitions::DefPathTable>, - pub impls: LazySeq<TraitImpls>, - pub exported_symbols: LazySeq<(ExportedSymbol<'tcx>, SymbolExportLevel)>, - pub interpret_alloc_index: LazySeq<u32>, + pub impls: Lazy<[TraitImpls]>, + pub exported_symbols: Lazy<[(ExportedSymbol<'tcx>, SymbolExportLevel)]>, + pub interpret_alloc_index: Lazy<[u32]>, - pub entries_index: LazySeq<index::Index<'tcx>>, + pub entries_index: Lazy<[index::Index<'tcx>]>, /// The DefIndex's of any proc macros delcared by /// this crate - pub proc_macro_data: Option<LazySeq<DefIndex>>, + pub proc_macro_data: Option<Lazy<[DefIndex]>>, pub compiler_builtins: bool, pub needs_allocator: bool, @@ -207,7 +210,7 @@ pub struct CrateDep { #[derive(RustcEncodable, RustcDecodable)] pub struct TraitImpls { pub trait_id: (u32, DefIndex), - pub impls: LazySeq<DefIndex>, + pub impls: Lazy<[DefIndex]>, } #[derive(RustcEncodable, RustcDecodable)] @@ -215,14 +218,14 @@ pub struct Entry<'tcx> { pub kind: EntryKind<'tcx>, pub visibility: Lazy<ty::Visibility>, pub span: Lazy<Span>, - pub attributes: LazySeq<ast::Attribute>, - pub children: LazySeq<DefIndex>, + pub attributes: Lazy<[ast::Attribute]>, + pub children: Lazy<[DefIndex]>, pub stability: Option<Lazy<attr::Stability>>, pub deprecation: Option<Lazy<attr::Deprecation>>, pub ty: Option<Lazy<Ty<'tcx>>>, - pub inherent_impls: LazySeq<DefIndex>, - pub variances: LazySeq<ty::Variance>, + pub inherent_impls: Lazy<[DefIndex]>, + pub variances: Lazy<[ty::Variance]>, pub generics: Option<Lazy<ty::Generics>>, pub predicates: Option<Lazy<ty::GenericPredicates<'tcx>>>, pub predicates_defined_on: Option<Lazy<ty::GenericPredicates<'tcx>>>, @@ -278,7 +281,7 @@ pub struct RenderedConst(pub String); #[derive(RustcEncodable, RustcDecodable)] pub struct ModData { - pub reexports: LazySeq<def::Export<hir::HirId>>, + pub reexports: Lazy<[def::Export<hir::HirId>]>, } #[derive(RustcEncodable, RustcDecodable)] @@ -290,7 +293,7 @@ pub struct MacroDef { #[derive(RustcEncodable, RustcDecodable)] pub struct FnData<'tcx> { pub constness: hir::Constness, - pub arg_names: LazySeq<ast::Name>, + pub arg_names: Lazy<[ast::Name]>, pub sig: Lazy<ty::PolyFnSig<'tcx>>, } diff --git a/src/librustc_passes/error_codes.rs b/src/librustc_passes/error_codes.rs index cd33943e77e..a30cd8a627f 100644 --- a/src/librustc_passes/error_codes.rs +++ b/src/librustc_passes/error_codes.rs @@ -131,7 +131,7 @@ be taken. Erroneous code example: ```compile_fail,E0268 fn some_func() { - break; // error: `break` outside of loop + break; // error: `break` outside of a loop } ``` diff --git a/src/librustc_passes/loops.rs b/src/librustc_passes/loops.rs index 1547e607b9c..dbfbec32a6f 100644 --- a/src/librustc_passes/loops.rs +++ b/src/librustc_passes/loops.rs @@ -16,8 +16,8 @@ use errors::Applicability; enum Context { Normal, Loop(hir::LoopSource), - Closure, - AsyncClosure, + Closure(Span), + AsyncClosure(Span), LabeledBlock, AnonConst, } @@ -58,11 +58,11 @@ impl<'a, 'hir> Visitor<'hir> for CheckLoopVisitor<'a, 'hir> { hir::ExprKind::Loop(ref b, _, source) => { self.with_context(Loop(source), |v| v.visit_block(&b)); } - hir::ExprKind::Closure(_, ref function_decl, b, _, movability) => { + hir::ExprKind::Closure(_, ref function_decl, b, span, movability) => { let cx = if let Some(GeneratorMovability::Static) = movability { - AsyncClosure + AsyncClosure(span) } else { - Closure + Closure(span) }; self.visit_fn_decl(&function_decl); self.with_context(cx, |v| v.visit_nested_body(b)); @@ -170,23 +170,22 @@ impl<'a, 'hir> CheckLoopVisitor<'a, 'hir> { } fn require_break_cx(&self, name: &str, span: Span) { - match self.cx { - LabeledBlock | Loop(_) => {} - Closure => { - struct_span_err!(self.sess, span, E0267, "`{}` inside of a closure", name) - .span_label(span, "cannot break inside of a closure") + let err_inside_of = |article, ty, closure_span| { + struct_span_err!(self.sess, span, E0267, "`{}` inside of {} {}", name, article, ty) + .span_label(span, format!("cannot `{}` inside of {} {}", name, article, ty)) + .span_label(closure_span, &format!("enclosing {}", ty)) .emit(); - } - AsyncClosure => { - struct_span_err!(self.sess, span, E0267, "`{}` inside of an async block", name) - .span_label(span, "cannot break inside of an async block") - .emit(); - } + }; + + match self.cx { + LabeledBlock | Loop(_) => {}, + Closure(closure_span) => err_inside_of("a", "closure", closure_span), + AsyncClosure(closure_span) => err_inside_of("an", "`async` block", closure_span), Normal | AnonConst => { - struct_span_err!(self.sess, span, E0268, "`{}` outside of loop", name) - .span_label(span, "cannot break outside of a loop") + struct_span_err!(self.sess, span, E0268, "`{}` outside of a loop", name) + .span_label(span, format!("cannot `{}` outside of a loop", name)) .emit(); - } + }, } } diff --git a/src/librustc_plugin/deprecated/lib.rs b/src/librustc_plugin/deprecated/lib.rs index 5fb18066759..1d0afe84c25 100644 --- a/src/librustc_plugin/deprecated/lib.rs +++ b/src/librustc_plugin/deprecated/lib.rs @@ -1,6 +1,6 @@ #![doc(html_root_url = "https://doc.rust-lang.org/nightly/")] #![feature(staged_api)] -#![unstable(feature = "rustc_plugin", issue = "29597")] +#![unstable(feature = "rustc_private", issue = "27812")] #![rustc_deprecated(since = "1.38.0", reason = "\ import this through `rustc_driver::plugin` instead to make TLS work correctly. \ See https://github.com/rust-lang/rust/issues/62717")] diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs index bca77621e55..146058963b6 100644 --- a/src/librustc_privacy/lib.rs +++ b/src/librustc_privacy/lib.rs @@ -508,11 +508,7 @@ impl EmbargoVisitor<'tcx> { } } - fn update_macro_reachable_mod( - &mut self, - reachable_mod: hir::HirId, - defining_mod: DefId, - ) { + fn update_macro_reachable_mod(&mut self, reachable_mod: hir::HirId, defining_mod: DefId) { let module_def_id = self.tcx.hir().local_def_id(reachable_mod); let module = self.tcx.hir().get_module(module_def_id).0; for item_id in &module.item_ids { @@ -524,19 +520,13 @@ impl EmbargoVisitor<'tcx> { self.update_macro_reachable_def(hir_id, def_kind, vis, defining_mod); } } - if let Some(exports) = self.tcx.module_exports(module_def_id) { for export in exports { if export.vis.is_accessible_from(defining_mod, self.tcx) { if let Res::Def(def_kind, def_id) = export.res { let vis = def_id_visibility(self.tcx, def_id).0; if let Some(hir_id) = self.tcx.hir().as_local_hir_id(def_id) { - self.update_macro_reachable_def( - hir_id, - def_kind, - vis, - defining_mod, - ); + self.update_macro_reachable_def(hir_id, def_kind, vis, defining_mod); } } } @@ -892,10 +882,14 @@ impl Visitor<'tcx> for EmbargoVisitor<'tcx> { self.tcx.hir().local_def_id(md.hir_id) ).unwrap(); let mut module_id = self.tcx.hir().as_local_hir_id(macro_module_def_id).unwrap(); + if !self.tcx.hir().is_hir_id_module(module_id) { + // `module_id` doesn't correspond to a `mod`, return early (#63164). + return; + } let level = if md.vis.node.is_pub() { self.get(module_id) } else { None }; let new_level = self.update(md.hir_id, level); if new_level.is_none() { - return + return; } loop { diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index 42428456b6e..9a794ade729 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -145,7 +145,7 @@ impl<'a> Resolver<'a> { } } - fn get_macro_by_def_id(&mut self, def_id: DefId) -> Option<Lrc<SyntaxExtension>> { + crate fn get_macro_by_def_id(&mut self, def_id: DefId) -> Option<Lrc<SyntaxExtension>> { if let Some(ext) = self.macro_map.get(&def_id) { return Some(ext.clone()); } diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 2dd0ad13c52..875ae449d94 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -1647,10 +1647,14 @@ impl<'a> Resolver<'a> { if module.expansion != parent.expansion && module.expansion.is_descendant_of(parent.expansion) { // The macro is a proc macro derive - if module.expansion.looks_like_proc_macro_derive() { - if parent.expansion.outer_expn_is_descendant_of(span.ctxt()) { - *poisoned = Some(node_id); - return module.parent; + if let Some(&def_id) = self.macro_defs.get(&module.expansion) { + if let Some(ext) = self.get_macro_by_def_id(def_id) { + if !ext.is_builtin && ext.macro_kind() == MacroKind::Derive { + if parent.expansion.outer_expn_is_descendant_of(span.ctxt()) { + *poisoned = Some(node_id); + return module.parent; + } + } } } } diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs index 01ad67252a3..719167eb057 100644 --- a/src/librustc_resolve/macros.rs +++ b/src/librustc_resolve/macros.rs @@ -140,9 +140,23 @@ impl<'a> base::Resolver for Resolver<'a> { ImportResolver { r: self }.resolve_imports() } - fn resolve_macro_invocation(&mut self, invoc: &Invocation, invoc_id: ExpnId, force: bool) - -> Result<Option<Lrc<SyntaxExtension>>, Indeterminate> { - let parent_scope = self.invocation_parent_scopes[&invoc_id]; + fn resolve_macro_invocation( + &mut self, invoc: &Invocation, eager_expansion_root: ExpnId, force: bool + ) -> Result<Option<Lrc<SyntaxExtension>>, Indeterminate> { + let invoc_id = invoc.expansion_data.id; + let parent_scope = match self.invocation_parent_scopes.get(&invoc_id) { + Some(parent_scope) => *parent_scope, + None => { + // If there's no entry in the table, then we are resolving an eagerly expanded + // macro, which should inherit its parent scope from its eager expansion root - + // the macro that requested this eager expansion. + let parent_scope = *self.invocation_parent_scopes.get(&eager_expansion_root) + .expect("non-eager expansion without a parent scope"); + self.invocation_parent_scopes.insert(invoc_id, parent_scope); + parent_scope + } + }; + let (path, kind, derives, after_derive) = match invoc.kind { InvocationKind::Attr { ref attr, ref derives, after_derive, .. } => (&attr.path, MacroKind::Attr, self.arenas.alloc_ast_paths(derives), after_derive), @@ -161,7 +175,7 @@ impl<'a> base::Resolver for Resolver<'a> { match self.resolve_macro_path(path, Some(MacroKind::Derive), &parent_scope, true, force) { Ok((Some(ref ext), _)) if ext.is_derive_copy => { - self.add_derives(invoc.expansion_data.id, SpecialDerives::COPY); + self.add_derives(invoc_id, SpecialDerives::COPY); return Ok(None); } Err(Determinacy::Undetermined) => result = Err(Indeterminate), @@ -178,19 +192,15 @@ impl<'a> base::Resolver for Resolver<'a> { let (ext, res) = self.smart_resolve_macro_path(path, kind, parent_scope, force)?; let span = invoc.span(); - invoc.expansion_data.id.set_expn_data( - ext.expn_data(parent_scope.expansion, span, fast_print_path(path)) - ); + invoc_id.set_expn_data(ext.expn_data(parent_scope.expansion, span, fast_print_path(path))); if let Res::Def(_, def_id) = res { if after_derive { self.session.span_err(span, "macro attributes must be placed before `#[derive]`"); } - self.macro_defs.insert(invoc.expansion_data.id, def_id); - let normal_module_def_id = - self.macro_def_scope(invoc.expansion_data.id).normal_ancestor_id; - self.definitions.add_parent_module_of_macro_def(invoc.expansion_data.id, - normal_module_def_id); + self.macro_defs.insert(invoc_id, def_id); + let normal_module_def_id = self.macro_def_scope(invoc_id).normal_ancestor_id; + self.definitions.add_parent_module_of_macro_def(invoc_id, normal_module_def_id); } Ok(Some(ext)) diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index fc1ee649e28..9c7ac83e82e 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -4197,8 +4197,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { /// A possible error is to forget to add `.await` when using futures: /// /// ``` - /// #![feature(async_await)] - /// /// async fn make_u32() -> u32 { /// 22 /// } diff --git a/src/librustc_typeck/error_codes.rs b/src/librustc_typeck/error_codes.rs index ca9ce3d22b5..b52183d4b1b 100644 --- a/src/librustc_typeck/error_codes.rs +++ b/src/librustc_typeck/error_codes.rs @@ -4751,7 +4751,6 @@ E0733: r##" Recursion in an `async fn` requires boxing. For example, this will not compile: ```edition2018,compile_fail,E0733 -#![feature(async_await)] async fn foo(n: usize) { if n > 0 { foo(n - 1).await; @@ -4763,12 +4762,11 @@ To achieve async recursion, the `async fn` needs to be desugared such that the `Future` is explicit in the return type: ```edition2018,compile_fail,E0720 -# #![feature(async_await)] use std::future::Future; -fn foo_desugered(n: usize) -> impl Future<Output = ()> { +fn foo_desugared(n: usize) -> impl Future<Output = ()> { async move { if n > 0 { - foo_desugered(n - 1).await; + foo_desugared(n - 1).await; } } } @@ -4777,7 +4775,6 @@ fn foo_desugered(n: usize) -> impl Future<Output = ()> { Finally, the future is wrapped in a pinned box: ```edition2018 -# #![feature(async_await)] use std::future::Future; use std::pin::Pin; fn foo_recursive(n: usize) -> Pin<Box<dyn Future<Output = ()>>> { diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index ea97cea9428..b64e74468e6 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -876,22 +876,22 @@ r#"var themes = document.getElementById("theme-choices"); var themePicker = document.getElementById("theme-picker"); function showThemeButtonState() {{ - themes.style.display = "none"; - themePicker.style.borderBottomRightRadius = "3px"; - themePicker.style.borderBottomLeftRadius = "3px"; -}} - -function hideThemeButtonState() {{ themes.style.display = "block"; themePicker.style.borderBottomRightRadius = "0"; themePicker.style.borderBottomLeftRadius = "0"; }} +function hideThemeButtonState() {{ + themes.style.display = "none"; + themePicker.style.borderBottomRightRadius = "3px"; + themePicker.style.borderBottomLeftRadius = "3px"; +}} + function switchThemeButtonState() {{ if (themes.style.display === "block") {{ - showThemeButtonState(); - }} else {{ hideThemeButtonState(); + }} else {{ + showThemeButtonState(); }} }}; @@ -914,7 +914,7 @@ themePicker.onblur = handleThemeButtonsBlur; var but = document.createElement('button'); but.innerHTML = item; but.onclick = function(el) {{ - switchTheme(currentTheme, mainTheme, item); + switchTheme(currentTheme, mainTheme, item, true); }}; but.onblur = handleThemeButtonsBlur; themes.appendChild(but); diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js index 82d2c11b249..3d0f00095ac 100644 --- a/src/librustdoc/html/static/main.js +++ b/src/librustdoc/html/static/main.js @@ -105,9 +105,9 @@ if (!DOMTokenList.prototype.remove) { sidebar.appendChild(div); } } - var themePicker = document.getElementsByClassName("theme-picker"); - if (themePicker && themePicker.length > 0) { - themePicker[0].style.display = "none"; + var themePickers = document.getElementsByClassName("theme-picker"); + if (themePickers && themePickers.length > 0) { + themePickers[0].style.display = "none"; } } @@ -123,9 +123,9 @@ if (!DOMTokenList.prototype.remove) { filler.remove(); } document.getElementsByTagName("body")[0].style.marginTop = ""; - var themePicker = document.getElementsByClassName("theme-picker"); - if (themePicker && themePicker.length > 0) { - themePicker[0].style.display = null; + var themePickers = document.getElementsByClassName("theme-picker"); + if (themePickers && themePickers.length > 0) { + themePickers[0].style.display = null; } } diff --git a/src/librustdoc/html/static/rustdoc.css b/src/librustdoc/html/static/rustdoc.css index 59d10668f11..244b24af43f 100644 --- a/src/librustdoc/html/static/rustdoc.css +++ b/src/librustdoc/html/static/rustdoc.css @@ -54,6 +54,21 @@ box-sizing: border-box; } +/* This part handles the "default" theme being used depending on the system one. */ +html { + content: ""; +} +@media (prefers-color-scheme: light) { + html { + content: "light"; + } +} +@media (prefers-color-scheme: dark) { + html { + content: "dark"; + } +} + /* General structure and fonts */ body { diff --git a/src/librustdoc/html/static/storage.js b/src/librustdoc/html/static/storage.js index e3927350d11..c55b1e41443 100644 --- a/src/librustdoc/html/static/storage.js +++ b/src/librustdoc/html/static/storage.js @@ -86,7 +86,7 @@ function getCurrentValue(name) { return null; } -function switchTheme(styleElem, mainStyleElem, newTheme) { +function switchTheme(styleElem, mainStyleElem, newTheme, saveTheme) { var fullBasicCss = "rustdoc" + resourcesSuffix + ".css"; var fullNewTheme = newTheme + resourcesSuffix + ".css"; var newHref = mainStyleElem.href.replace(fullBasicCss, fullNewTheme); @@ -109,8 +109,18 @@ function switchTheme(styleElem, mainStyleElem, newTheme) { }); if (found === true) { styleElem.href = newHref; - updateLocalStorage("rustdoc-theme", newTheme); + // If this new value comes from a system setting or from the previously saved theme, no + // need to save it. + if (saveTheme === true) { + updateLocalStorage("rustdoc-theme", newTheme); + } } } -switchTheme(currentTheme, mainTheme, getCurrentValue("rustdoc-theme") || "light"); +function getSystemValue() { + return getComputedStyle(document.documentElement).getPropertyValue('content'); +} + +switchTheme(currentTheme, mainTheme, + getCurrentValue("rustdoc-theme") || getSystemValue() || "light", + false); diff --git a/src/libstd/f32.rs b/src/libstd/f32.rs index f649170c403..e55afc2344f 100644 --- a/src/libstd/f32.rs +++ b/src/libstd/f32.rs @@ -236,7 +236,7 @@ impl f32 { /// let b = 60.0_f32; /// /// // 100.0 - /// let abs_difference = (m.mul_add(x, b) - (m*x + b)).abs(); + /// let abs_difference = (m.mul_add(x, b) - ((m * x) + b)).abs(); /// /// assert!(abs_difference <= f32::EPSILON); /// ``` @@ -318,7 +318,7 @@ impl f32 { /// use std::f32; /// /// let x = 2.0_f32; - /// let abs_difference = (x.powi(2) - x*x).abs(); + /// let abs_difference = (x.powi(2) - (x * x)).abs(); /// /// assert!(abs_difference <= f32::EPSILON); /// ``` @@ -336,7 +336,7 @@ impl f32 { /// use std::f32; /// /// let x = 2.0_f32; - /// let abs_difference = (x.powf(2.0) - x*x).abs(); + /// let abs_difference = (x.powf(2.0) - (x * x)).abs(); /// /// assert!(abs_difference <= f32::EPSILON); /// ``` @@ -600,7 +600,7 @@ impl f32 { /// ``` /// use std::f32; /// - /// let x = f32::consts::PI/2.0; + /// let x = f32::consts::FRAC_PI_2; /// /// let abs_difference = (x.sin() - 1.0).abs(); /// @@ -623,7 +623,7 @@ impl f32 { /// ``` /// use std::f32; /// - /// let x = 2.0*f32::consts::PI; + /// let x = 2.0 * f32::consts::PI; /// /// let abs_difference = (x.cos() - 1.0).abs(); /// @@ -646,7 +646,7 @@ impl f32 { /// ``` /// use std::f32; /// - /// let x = f32::consts::PI / 4.0; + /// let x = f32::consts::FRAC_PI_4; /// let abs_difference = (x.tan() - 1.0).abs(); /// /// assert!(abs_difference <= f32::EPSILON); @@ -666,10 +666,10 @@ impl f32 { /// ``` /// use std::f32; /// - /// let f = f32::consts::PI / 2.0; + /// let f = f32::consts::FRAC_PI_2; /// /// // asin(sin(pi/2)) - /// let abs_difference = (f.sin().asin() - f32::consts::PI / 2.0).abs(); + /// let abs_difference = (f.sin().asin() - f32::consts::FRAC_PI_2).abs(); /// /// assert!(abs_difference <= f32::EPSILON); /// ``` @@ -688,10 +688,10 @@ impl f32 { /// ``` /// use std::f32; /// - /// let f = f32::consts::PI / 4.0; + /// let f = f32::consts::FRAC_PI_4; /// /// // acos(cos(pi/4)) - /// let abs_difference = (f.cos().acos() - f32::consts::PI / 4.0).abs(); + /// let abs_difference = (f.cos().acos() - f32::consts::FRAC_PI_4).abs(); /// /// assert!(abs_difference <= f32::EPSILON); /// ``` @@ -734,7 +734,6 @@ impl f32 { /// ``` /// use std::f32; /// - /// let pi = f32::consts::PI; /// // Positive angles measured counter-clockwise /// // from positive x axis /// // -pi/4 radians (45 deg clockwise) @@ -745,8 +744,8 @@ impl f32 { /// let x2 = -3.0f32; /// let y2 = 3.0f32; /// - /// let abs_difference_1 = (y1.atan2(x1) - (-pi/4.0)).abs(); - /// let abs_difference_2 = (y2.atan2(x2) - 3.0*pi/4.0).abs(); + /// let abs_difference_1 = (y1.atan2(x1) - (-f32::consts::FRAC_PI_4)).abs(); + /// let abs_difference_2 = (y2.atan2(x2) - (3.0 * f32::consts::FRAC_PI_4)).abs(); /// /// assert!(abs_difference_1 <= f32::EPSILON); /// assert!(abs_difference_2 <= f32::EPSILON); @@ -765,7 +764,7 @@ impl f32 { /// ``` /// use std::f32; /// - /// let x = f32::consts::PI/4.0; + /// let x = f32::consts::FRAC_PI_4; /// let f = x.sin_cos(); /// /// let abs_difference_0 = (f.0 - x.sin()).abs(); @@ -834,7 +833,7 @@ impl f32 { /// /// let f = x.sinh(); /// // Solving sinh() at 1 gives `(e^2-1)/(2e)` - /// let g = (e*e - 1.0)/(2.0*e); + /// let g = ((e * e) - 1.0) / (2.0 * e); /// let abs_difference = (f - g).abs(); /// /// assert!(abs_difference <= f32::EPSILON); @@ -856,7 +855,7 @@ impl f32 { /// let x = 1.0f32; /// let f = x.cosh(); /// // Solving cosh() at 1 gives this result - /// let g = (e*e + 1.0)/(2.0*e); + /// let g = ((e * e) + 1.0) / (2.0 * e); /// let abs_difference = (f - g).abs(); /// /// // Same result @@ -880,7 +879,7 @@ impl f32 { /// /// let f = x.tanh(); /// // Solving tanh() at 1 gives `(1 - e^(-2))/(1 + e^(-2))` - /// let g = (1.0 - e.powi(-2))/(1.0 + e.powi(-2)); + /// let g = (1.0 - e.powi(-2)) / (1.0 + e.powi(-2)); /// let abs_difference = (f - g).abs(); /// /// assert!(abs_difference <= f32::EPSILON); diff --git a/src/libstd/f64.rs b/src/libstd/f64.rs index f61630997dc..b3571026300 100644 --- a/src/libstd/f64.rs +++ b/src/libstd/f64.rs @@ -212,7 +212,7 @@ impl f64 { /// let b = 60.0_f64; /// /// // 100.0 - /// let abs_difference = (m.mul_add(x, b) - (m*x + b)).abs(); + /// let abs_difference = (m.mul_add(x, b) - ((m * x) + b)).abs(); /// /// assert!(abs_difference < 1e-10); /// ``` @@ -291,7 +291,7 @@ impl f64 { /// /// ``` /// let x = 2.0_f64; - /// let abs_difference = (x.powi(2) - x*x).abs(); + /// let abs_difference = (x.powi(2) - (x * x)).abs(); /// /// assert!(abs_difference < 1e-10); /// ``` @@ -307,7 +307,7 @@ impl f64 { /// /// ``` /// let x = 2.0_f64; - /// let abs_difference = (x.powf(2.0) - x*x).abs(); + /// let abs_difference = (x.powf(2.0) - (x * x)).abs(); /// /// assert!(abs_difference < 1e-10); /// ``` @@ -537,7 +537,7 @@ impl f64 { /// ``` /// use std::f64; /// - /// let x = f64::consts::PI/2.0; + /// let x = f64::consts::FRAC_PI_2; /// /// let abs_difference = (x.sin() - 1.0).abs(); /// @@ -556,7 +556,7 @@ impl f64 { /// ``` /// use std::f64; /// - /// let x = 2.0*f64::consts::PI; + /// let x = 2.0 * f64::consts::PI; /// /// let abs_difference = (x.cos() - 1.0).abs(); /// @@ -575,7 +575,7 @@ impl f64 { /// ``` /// use std::f64; /// - /// let x = f64::consts::PI/4.0; + /// let x = f64::consts::FRAC_PI_4; /// let abs_difference = (x.tan() - 1.0).abs(); /// /// assert!(abs_difference < 1e-14); @@ -595,10 +595,10 @@ impl f64 { /// ``` /// use std::f64; /// - /// let f = f64::consts::PI / 2.0; + /// let f = f64::consts::FRAC_PI_2; /// /// // asin(sin(pi/2)) - /// let abs_difference = (f.sin().asin() - f64::consts::PI / 2.0).abs(); + /// let abs_difference = (f.sin().asin() - f64::consts::FRAC_PI_2).abs(); /// /// assert!(abs_difference < 1e-10); /// ``` @@ -617,10 +617,10 @@ impl f64 { /// ``` /// use std::f64; /// - /// let f = f64::consts::PI / 4.0; + /// let f = f64::consts::FRAC_PI_4; /// /// // acos(cos(pi/4)) - /// let abs_difference = (f.cos().acos() - f64::consts::PI / 4.0).abs(); + /// let abs_difference = (f.cos().acos() - f64::consts::FRAC_PI_4).abs(); /// /// assert!(abs_difference < 1e-10); /// ``` @@ -661,7 +661,6 @@ impl f64 { /// ``` /// use std::f64; /// - /// let pi = f64::consts::PI; /// // Positive angles measured counter-clockwise /// // from positive x axis /// // -pi/4 radians (45 deg clockwise) @@ -672,8 +671,8 @@ impl f64 { /// let x2 = -3.0_f64; /// let y2 = 3.0_f64; /// - /// let abs_difference_1 = (y1.atan2(x1) - (-pi/4.0)).abs(); - /// let abs_difference_2 = (y2.atan2(x2) - 3.0*pi/4.0).abs(); + /// let abs_difference_1 = (y1.atan2(x1) - (-f64::consts::FRAC_PI_4)).abs(); + /// let abs_difference_2 = (y2.atan2(x2) - (3.0 * f64::consts::FRAC_PI_4)).abs(); /// /// assert!(abs_difference_1 < 1e-10); /// assert!(abs_difference_2 < 1e-10); @@ -692,7 +691,7 @@ impl f64 { /// ``` /// use std::f64; /// - /// let x = f64::consts::PI/4.0; + /// let x = f64::consts::FRAC_PI_4; /// let f = x.sin_cos(); /// /// let abs_difference_0 = (f.0 - x.sin()).abs(); @@ -759,7 +758,7 @@ impl f64 { /// /// let f = x.sinh(); /// // Solving sinh() at 1 gives `(e^2-1)/(2e)` - /// let g = (e*e - 1.0)/(2.0*e); + /// let g = ((e * e) - 1.0) / (2.0 * e); /// let abs_difference = (f - g).abs(); /// /// assert!(abs_difference < 1e-10); @@ -781,7 +780,7 @@ impl f64 { /// let x = 1.0_f64; /// let f = x.cosh(); /// // Solving cosh() at 1 gives this result - /// let g = (e*e + 1.0)/(2.0*e); + /// let g = ((e * e) + 1.0) / (2.0 * e); /// let abs_difference = (f - g).abs(); /// /// // Same result @@ -805,7 +804,7 @@ impl f64 { /// /// let f = x.tanh(); /// // Solving tanh() at 1 gives `(1 - e^(-2))/(1 + e^(-2))` - /// let g = (1.0 - e.powi(-2))/(1.0 + e.powi(-2)); + /// let g = (1.0 - e.powi(-2)) / (1.0 + e.powi(-2)); /// let abs_difference = (f - g).abs(); /// /// assert!(abs_difference < 1.0e-10); diff --git a/src/libstd/ffi/c_str.rs b/src/libstd/ffi/c_str.rs index 512839a12c0..65f4e0cafe0 100644 --- a/src/libstd/ffi/c_str.rs +++ b/src/libstd/ffi/c_str.rs @@ -572,8 +572,8 @@ impl CString { /// use std::ffi::{CString, CStr}; /// /// let c_string = CString::new(b"foo".to_vec()).expect("CString::new failed"); - /// let c_str = c_string.as_c_str(); - /// assert_eq!(c_str, + /// let cstr = c_string.as_c_str(); + /// assert_eq!(cstr, /// CStr::from_bytes_with_nul(b"foo\0").expect("CStr::from_bytes_with_nul failed")); /// ``` #[inline] @@ -994,8 +994,8 @@ impl CStr { /// ``` /// use std::ffi::CStr; /// - /// let c_str = CStr::from_bytes_with_nul(b"hello"); - /// assert!(c_str.is_err()); + /// let cstr = CStr::from_bytes_with_nul(b"hello"); + /// assert!(cstr.is_err()); /// ``` /// /// Creating a `CStr` with an interior nul byte is an error: @@ -1003,8 +1003,8 @@ impl CStr { /// ``` /// use std::ffi::CStr; /// - /// let c_str = CStr::from_bytes_with_nul(b"he\0llo\0"); - /// assert!(c_str.is_err()); + /// let cstr = CStr::from_bytes_with_nul(b"he\0llo\0"); + /// assert!(cstr.is_err()); /// ``` #[stable(feature = "cstr_from_bytes", since = "1.10.0")] pub fn from_bytes_with_nul(bytes: &[u8]) @@ -1111,8 +1111,8 @@ impl CStr { /// ``` /// use std::ffi::CStr; /// - /// let c_str = CStr::from_bytes_with_nul(b"foo\0").expect("CStr::from_bytes_with_nul failed"); - /// assert_eq!(c_str.to_bytes(), b"foo"); + /// let cstr = CStr::from_bytes_with_nul(b"foo\0").expect("CStr::from_bytes_with_nul failed"); + /// assert_eq!(cstr.to_bytes(), b"foo"); /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] @@ -1137,8 +1137,8 @@ impl CStr { /// ``` /// use std::ffi::CStr; /// - /// let c_str = CStr::from_bytes_with_nul(b"foo\0").expect("CStr::from_bytes_with_nul failed"); - /// assert_eq!(c_str.to_bytes_with_nul(), b"foo\0"); + /// let cstr = CStr::from_bytes_with_nul(b"foo\0").expect("CStr::from_bytes_with_nul failed"); + /// assert_eq!(cstr.to_bytes_with_nul(), b"foo\0"); /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] @@ -1164,8 +1164,8 @@ impl CStr { /// ``` /// use std::ffi::CStr; /// - /// let c_str = CStr::from_bytes_with_nul(b"foo\0").expect("CStr::from_bytes_with_nul failed"); - /// assert_eq!(c_str.to_str(), Ok("foo")); + /// let cstr = CStr::from_bytes_with_nul(b"foo\0").expect("CStr::from_bytes_with_nul failed"); + /// assert_eq!(cstr.to_str(), Ok("foo")); /// ``` #[stable(feature = "cstr_to_str", since = "1.4.0")] pub fn to_str(&self) -> Result<&str, str::Utf8Error> { @@ -1205,9 +1205,9 @@ impl CStr { /// use std::borrow::Cow; /// use std::ffi::CStr; /// - /// let c_str = CStr::from_bytes_with_nul(b"Hello World\0") + /// let cstr = CStr::from_bytes_with_nul(b"Hello World\0") /// .expect("CStr::from_bytes_with_nul failed"); - /// assert_eq!(c_str.to_string_lossy(), Cow::Borrowed("Hello World")); + /// assert_eq!(cstr.to_string_lossy(), Cow::Borrowed("Hello World")); /// ``` /// /// Calling `to_string_lossy` on a `CStr` containing invalid UTF-8: @@ -1216,10 +1216,10 @@ impl CStr { /// use std::borrow::Cow; /// use std::ffi::CStr; /// - /// let c_str = CStr::from_bytes_with_nul(b"Hello \xF0\x90\x80World\0") + /// let cstr = CStr::from_bytes_with_nul(b"Hello \xF0\x90\x80World\0") /// .expect("CStr::from_bytes_with_nul failed"); /// assert_eq!( - /// c_str.to_string_lossy(), + /// cstr.to_string_lossy(), /// Cow::Owned(String::from("Hello �World")) as Cow<'_, str> /// ); /// ``` diff --git a/src/libstd/ffi/os_str.rs b/src/libstd/ffi/os_str.rs index 1f384cbada3..6cf062d4f30 100644 --- a/src/libstd/ffi/os_str.rs +++ b/src/libstd/ffi/os_str.rs @@ -233,7 +233,7 @@ impl OsString { /// ``` /// use std::ffi::OsString; /// - /// let mut os_string = OsString::with_capacity(10); + /// let os_string = OsString::with_capacity(10); /// assert!(os_string.capacity() >= 10); /// ``` #[stable(feature = "osstring_simple_functions", since = "1.9.0")] @@ -616,7 +616,7 @@ impl OsStr { /// Note that this does **not** return the number of bytes in the string in /// OS string form. /// - /// The length returned is that of the underlying storage used by `OsStr`; + /// The length returned is that of the underlying storage used by `OsStr`. /// As discussed in the [`OsString`] introduction, [`OsString`] and `OsStr` /// store strings in a form best suited for cheap inter-conversion between /// native-platform and Rust string forms, which may differ significantly diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs index f2b6ce6feb2..5060f368229 100644 --- a/src/libstd/io/mod.rs +++ b/src/libstd/io/mod.rs @@ -353,12 +353,17 @@ fn append_to_string<F>(buf: &mut String, f: F) -> Result<usize> // Because we're extending the buffer with uninitialized data for trusted // readers, we need to make sure to truncate that if any of this panics. fn read_to_end<R: Read + ?Sized>(r: &mut R, buf: &mut Vec<u8>) -> Result<usize> { - read_to_end_with_reservation(r, buf, 32) + read_to_end_with_reservation(r, buf, |_| 32) } -fn read_to_end_with_reservation<R: Read + ?Sized>(r: &mut R, - buf: &mut Vec<u8>, - reservation_size: usize) -> Result<usize> +fn read_to_end_with_reservation<R, F>( + r: &mut R, + buf: &mut Vec<u8>, + mut reservation_size: F, +) -> Result<usize> +where + R: Read + ?Sized, + F: FnMut(&R) -> usize, { let start_len = buf.len(); let mut g = Guard { len: buf.len(), buf: buf }; @@ -366,7 +371,7 @@ fn read_to_end_with_reservation<R: Read + ?Sized>(r: &mut R, loop { if g.len == g.buf.len() { unsafe { - g.buf.reserve(reservation_size); + g.buf.reserve(reservation_size(r)); let capacity = g.buf.capacity(); g.buf.set_len(capacity); r.initializer().initialize(&mut g.buf[g.len..]); @@ -2253,9 +2258,10 @@ impl<T: Read> Read for Take<T> { } fn read_to_end(&mut self, buf: &mut Vec<u8>) -> Result<usize> { - let reservation_size = cmp::min(self.limit, 32) as usize; - - read_to_end_with_reservation(self, buf, reservation_size) + // Pass in a reservation_size closure that respects the current value + // of limit for each read. If we hit the read limit, this prevents the + // final zero-byte read from allocating again. + read_to_end_with_reservation(self, buf, |self_| cmp::min(self_.limit, 32) as usize) } } @@ -2378,6 +2384,7 @@ impl<B: BufRead> Iterator for Lines<B> { #[cfg(test)] mod tests { + use crate::cmp; use crate::io::prelude::*; use super::{Cursor, SeekFrom, repeat}; use crate::io::{self, IoSlice, IoSliceMut}; @@ -2651,6 +2658,49 @@ mod tests { Ok(()) } + // A simple example reader which uses the default implementation of + // read_to_end. + struct ExampleSliceReader<'a> { + slice: &'a [u8], + } + + impl<'a> Read for ExampleSliceReader<'a> { + fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> { + let len = cmp::min(self.slice.len(), buf.len()); + buf[..len].copy_from_slice(&self.slice[..len]); + self.slice = &self.slice[len..]; + Ok(len) + } + } + + #[test] + fn test_read_to_end_capacity() -> io::Result<()> { + let input = &b"foo"[..]; + + // read_to_end() generally needs to over-allocate, both for efficiency + // and so that it can distinguish EOF. Assert that this is the case + // with this simple ExampleSliceReader struct, which uses the default + // implementation of read_to_end. Even though vec1 is allocated with + // exactly enough capacity for the read, read_to_end will allocate more + // space here. + let mut vec1 = Vec::with_capacity(input.len()); + ExampleSliceReader { slice: input }.read_to_end(&mut vec1)?; + assert_eq!(vec1.len(), input.len()); + assert!(vec1.capacity() > input.len(), "allocated more"); + + // However, std::io::Take includes an implementation of read_to_end + // that will not allocate when the limit has already been reached. In + // this case, vec2 never grows. + let mut vec2 = Vec::with_capacity(input.len()); + ExampleSliceReader { slice: input } + .take(input.len() as u64) + .read_to_end(&mut vec2)?; + assert_eq!(vec2.len(), input.len()); + assert_eq!(vec2.capacity(), input.len(), "did not allocate more"); + + Ok(()) + } + #[test] fn io_slice_mut_advance() { let mut buf1 = [1; 8]; diff --git a/src/libstd/keyword_docs.rs b/src/libstd/keyword_docs.rs index f5018485ef7..85a9dea09ed 100644 --- a/src/libstd/keyword_docs.rs +++ b/src/libstd/keyword_docs.rs @@ -984,7 +984,6 @@ mod where_keyword { } // 2018 Edition keywords -#[unstable(feature = "async_await", issue = "50547")] #[doc(keyword = "async")] // /// Return a [`Future`] instead of blocking the current thread. @@ -995,7 +994,6 @@ mod where_keyword { } /// [not yet complete]: https://github.com/rust-lang/rust/issues/34601 mod async_keyword { } -#[unstable(feature = "async_await", issue = "50547")] #[doc(keyword = "await")] // /// Suspend execution until the result of a [`Future`] is ready. diff --git a/src/libstd/primitive_docs.rs b/src/libstd/primitive_docs.rs index d9a3da66a67..45816ffd229 100644 --- a/src/libstd/primitive_docs.rs +++ b/src/libstd/primitive_docs.rs @@ -655,7 +655,7 @@ mod prim_slice { } /// [`len`]: #method.len /// /// Note: This example shows the internals of `&str`. `unsafe` should not be -/// used to get a string slice under normal circumstances. Use `as_slice` +/// used to get a string slice under normal circumstances. Use `as_str` /// instead. #[stable(feature = "rust1", since = "1.0.0")] mod prim_str { } diff --git a/src/libstd/sys/unix/process/process_common.rs b/src/libstd/sys/unix/process/process_common.rs index 6bb20bbe087..21fca23a8fe 100644 --- a/src/libstd/sys/unix/process/process_common.rs +++ b/src/libstd/sys/unix/process/process_common.rs @@ -20,6 +20,30 @@ cfg_if::cfg_if! { } } +// Android with api less than 21 define sig* functions inline, so it is not +// available for dynamic link. Implementing sigemptyset and sigaddset allow us +// to support older Android version (independent of libc version). +// The following implementations are based on https://git.io/vSkNf +cfg_if::cfg_if! { + if #[cfg(target_os = "android")] { + pub unsafe fn sigemptyset(set: *mut libc::sigset_t) -> libc::c_int { + set.write_bytes(0u8, 1); + return 0; + } + #[allow(dead_code)] + pub unsafe fn sigaddset(set: *mut libc::sigset_t, signum: libc::c_int) -> libc::c_int { + use crate::{slice, mem}; + + let raw = slice::from_raw_parts_mut(set as *mut u8, mem::size_of::<libc::sigset_t>()); + let bit = (signum - 1) as usize; + raw[bit / 8] |= 1 << (bit % 8); + return 0; + } + } else { + pub use libc::{sigemptyset, sigaddset}; + } +} + //////////////////////////////////////////////////////////////////////////////// // Command //////////////////////////////////////////////////////////////////////////////// @@ -429,36 +453,6 @@ mod tests { } } - // Android with api less than 21 define sig* functions inline, so it is not - // available for dynamic link. Implementing sigemptyset and sigaddset allow us - // to support older Android version (independent of libc version). - // The following implementations are based on https://git.io/vSkNf - - #[cfg(not(target_os = "android"))] - extern { - #[cfg_attr(target_os = "netbsd", link_name = "__sigemptyset14")] - fn sigemptyset(set: *mut libc::sigset_t) -> libc::c_int; - - #[cfg_attr(target_os = "netbsd", link_name = "__sigaddset14")] - fn sigaddset(set: *mut libc::sigset_t, signum: libc::c_int) -> libc::c_int; - } - - #[cfg(target_os = "android")] - unsafe fn sigemptyset(set: *mut libc::sigset_t) -> libc::c_int { - set.write_bytes(0u8, 1); - return 0; - } - - #[cfg(target_os = "android")] - unsafe fn sigaddset(set: *mut libc::sigset_t, signum: libc::c_int) -> libc::c_int { - use crate::slice; - - let raw = slice::from_raw_parts_mut(set as *mut u8, mem::size_of::<libc::sigset_t>()); - let bit = (signum - 1) as usize; - raw[bit / 8] |= 1 << (bit % 8); - return 0; - } - // See #14232 for more information, but it appears that signal delivery to a // newly spawned process may just be raced in the macOS, so to prevent this // test from being flaky we ignore it on macOS. diff --git a/src/libstd/sys/unix/process/process_unix.rs b/src/libstd/sys/unix/process/process_unix.rs index 327d82e60cf..e6a742bd45d 100644 --- a/src/libstd/sys/unix/process/process_unix.rs +++ b/src/libstd/sys/unix/process/process_unix.rs @@ -178,23 +178,22 @@ impl Command { cvt_r(|| libc::dup2(fd, libc::STDERR_FILENO))?; } - if cfg!(not(any(target_os = "l4re"))) { + #[cfg(not(target_os = "l4re"))] + { if let Some(u) = self.get_gid() { cvt(libc::setgid(u as gid_t))?; } if let Some(u) = self.get_uid() { + // When dropping privileges from root, the `setgroups` call + // will remove any extraneous groups. If we don't call this, + // then even though our uid has dropped, we may still have + // groups that enable us to do super-user things. This will + // fail if we aren't root, so don't bother checking the + // return value, this is just done as an optimistic + // privilege dropping function. //FIXME: Redox kernel does not support setgroups yet - if cfg!(not(target_os = "redox")) { - // When dropping privileges from root, the `setgroups` call - // will remove any extraneous groups. If we don't call this, - // then even though our uid has dropped, we may still have - // groups that enable us to do super-user things. This will - // fail if we aren't root, so don't bother checking the - // return value, this is just done as an optimistic - // privilege dropping function. - let _ = libc::setgroups(0, ptr::null()); - } - + #[cfg(not(target_os = "redox"))] + let _ = libc::setgroups(0, ptr::null()); cvt(libc::setuid(u as uid_t))?; } } @@ -203,7 +202,7 @@ impl Command { } // emscripten has no signal support. - #[cfg(not(any(target_os = "emscripten")))] + #[cfg(not(target_os = "emscripten"))] { use crate::mem::MaybeUninit; // Reset signal handling so the child process starts in a @@ -214,14 +213,7 @@ impl Command { // need to clean things up now to avoid confusing the program // we're about to run. let mut set = MaybeUninit::<libc::sigset_t>::uninit(); - if cfg!(target_os = "android") { - // Implementing sigemptyset allow us to support older Android - // versions. See the comment about Android and sig* functions in - // process_common.rs - set.as_mut_ptr().write_bytes(0u8, 1); - } else { - cvt(libc::sigemptyset(set.as_mut_ptr()))?; - } + cvt(sigemptyset(set.as_mut_ptr()))?; cvt(libc::pthread_sigmask(libc::SIG_SETMASK, set.as_ptr(), ptr::null_mut()))?; let ret = sys::signal(libc::SIGPIPE, libc::SIG_DFL); @@ -363,10 +355,10 @@ impl Command { } let mut set = MaybeUninit::<libc::sigset_t>::uninit(); - cvt(libc::sigemptyset(set.as_mut_ptr()))?; + cvt(sigemptyset(set.as_mut_ptr()))?; cvt(libc::posix_spawnattr_setsigmask(attrs.0.as_mut_ptr(), set.as_ptr()))?; - cvt(libc::sigaddset(set.as_mut_ptr(), libc::SIGPIPE))?; + cvt(sigaddset(set.as_mut_ptr(), libc::SIGPIPE))?; cvt(libc::posix_spawnattr_setsigdefault(attrs.0.as_mut_ptr(), set.as_ptr()))?; diff --git a/src/libstd/sys/wasi/mod.rs b/src/libstd/sys/wasi/mod.rs index f87e4d16fcd..4007b7ac0ec 100644 --- a/src/libstd/sys/wasi/mod.rs +++ b/src/libstd/sys/wasi/mod.rs @@ -67,8 +67,25 @@ pub fn unsupported_err() -> std_io::Error { ) } -pub fn decode_error_kind(_code: i32) -> std_io::ErrorKind { - std_io::ErrorKind::Other +pub fn decode_error_kind(errno: i32) -> std_io::ErrorKind { + use std_io::ErrorKind::*; + match errno as libc::c_int { + wasi::ECONNREFUSED => ConnectionRefused, + wasi::ECONNRESET => ConnectionReset, + wasi::EPERM | libc::EACCES => PermissionDenied, + wasi::EPIPE => BrokenPipe, + wasi::ENOTCONN => NotConnected, + wasi::ECONNABORTED => ConnectionAborted, + wasi::EADDRNOTAVAIL => AddrNotAvailable, + wasi::EADDRINUSE => AddrInUse, + wasi::ENOENT => NotFound, + wasi::EINTR => Interrupted, + wasi::EINVAL => InvalidInput, + wasi::ETIMEDOUT => TimedOut, + wasi::EEXIST => AlreadyExists, + wasi::EAGAIN => WouldBlock, + _ => ErrorKind::Other, + } } // This enum is used as the storage for a bunch of types which can't actually diff --git a/src/libsyntax/diagnostics/metadata.rs b/src/libsyntax/diagnostics/metadata.rs deleted file mode 100644 index 53f37bb10bd..00000000000 --- a/src/libsyntax/diagnostics/metadata.rs +++ /dev/null @@ -1,93 +0,0 @@ -//! This module contains utilities for outputting metadata for diagnostic errors. -//! -//! Each set of errors is mapped to a metadata file by a name, which is -//! currently always a crate name. - -use std::collections::BTreeMap; -use std::env; -use std::fs::{remove_file, create_dir_all, File}; -use std::io::Write; -use std::path::PathBuf; -use std::error::Error; -use rustc_serialize::json::as_json; - -use syntax_pos::{Span, FileName}; - -use crate::ext::base::ExtCtxt; -use crate::diagnostics::plugin::{ErrorMap, ErrorInfo}; - -/// JSON encodable/decodable version of `ErrorInfo`. -#[derive(PartialEq, RustcDecodable, RustcEncodable)] -pub struct ErrorMetadata { - pub description: Option<String>, - pub use_site: Option<ErrorLocation> -} - -/// Mapping from error codes to metadata that can be (de)serialized. -pub type ErrorMetadataMap = BTreeMap<String, ErrorMetadata>; - -/// JSON encodable error location type with filename and line number. -#[derive(PartialEq, RustcDecodable, RustcEncodable)] -pub struct ErrorLocation { - pub filename: FileName, - pub line: usize -} - -impl ErrorLocation { - /// Creates an error location from a span. - pub fn from_span(ecx: &ExtCtxt<'_>, sp: Span) -> ErrorLocation { - let loc = ecx.source_map().lookup_char_pos(sp.lo()); - ErrorLocation { - filename: loc.file.name.clone(), - line: loc.line - } - } -} - -/// Gets the directory where metadata for a given `prefix` should be stored. -/// -/// See `output_metadata`. -pub fn get_metadata_dir(prefix: &str) -> PathBuf { - env::var_os("RUSTC_ERROR_METADATA_DST") - .map(PathBuf::from) - .expect("env var `RUSTC_ERROR_METADATA_DST` isn't set") - .join(prefix) -} - -/// Map `name` to a path in the given directory: <directory>/<name>.json -fn get_metadata_path(directory: PathBuf, name: &str) -> PathBuf { - directory.join(format!("{}.json", name)) -} - -/// Write metadata for the errors in `err_map` to disk, to a file corresponding to `prefix/name`. -/// -/// For our current purposes the prefix is the target architecture and the name is a crate name. -/// If an error occurs steps will be taken to ensure that no file is created. -pub fn output_metadata(ecx: &ExtCtxt<'_>, prefix: &str, name: &str, err_map: &ErrorMap) - -> Result<(), Box<dyn Error>> -{ - // Create the directory to place the file in. - let metadata_dir = get_metadata_dir(prefix); - create_dir_all(&metadata_dir)?; - - // Open the metadata file. - let metadata_path = get_metadata_path(metadata_dir, name); - let mut metadata_file = File::create(&metadata_path)?; - - // Construct a serializable map. - let json_map = err_map.iter().map(|(k, &ErrorInfo { description, use_site })| { - let key = k.as_str().to_string(); - let value = ErrorMetadata { - description: description.map(|n| n.as_str().to_string()), - use_site: use_site.map(|sp| ErrorLocation::from_span(ecx, sp)) - }; - (key, value) - }).collect::<ErrorMetadataMap>(); - - // Write the data to the file, deleting it if the write fails. - let result = write!(&mut metadata_file, "{}", as_json(&json_map)); - if result.is_err() { - remove_file(&metadata_path)?; - } - Ok(result?) -} diff --git a/src/libsyntax/diagnostics/plugin.rs b/src/libsyntax/diagnostics/plugin.rs index 9618b5acfb0..e9a55af52e8 100644 --- a/src/libsyntax/diagnostics/plugin.rs +++ b/src/libsyntax/diagnostics/plugin.rs @@ -1,5 +1,4 @@ use std::collections::BTreeMap; -use std::env; use crate::ast::{self, Ident, Name}; use crate::source_map; @@ -12,8 +11,6 @@ use crate::tokenstream::{TokenTree}; use smallvec::smallvec; use syntax_pos::Span; -use crate::diagnostics::metadata::output_metadata; - pub use errors::*; // Maximum width of any line in an extended error description (inclusive). @@ -127,36 +124,13 @@ pub fn expand_build_diagnostic_array<'cx>(ecx: &'cx mut ExtCtxt<'_>, token_tree: &[TokenTree]) -> Box<dyn MacResult+'cx> { assert_eq!(token_tree.len(), 3); - let (crate_name, ident) = match (&token_tree[0], &token_tree[2]) { - ( - // Crate name. - &TokenTree::Token(Token { kind: token::Ident(crate_name, _), .. }), - // DIAGNOSTICS ident. - &TokenTree::Token(Token { kind: token::Ident(name, _), span }) - ) => (crate_name, Ident::new(name, span)), + let ident = match &token_tree[2] { + // DIAGNOSTICS ident. + &TokenTree::Token(Token { kind: token::Ident(name, _), span }) + => Ident::new(name, span), _ => unreachable!() }; - // Output error metadata to `tmp/extended-errors/<target arch>/<crate name>.json` - if let Ok(target_triple) = env::var("CFG_COMPILER_HOST_TRIPLE") { - ecx.parse_sess.registered_diagnostics.with_lock(|diagnostics| { - if let Err(e) = output_metadata(ecx, - &target_triple, - &crate_name.as_str(), - diagnostics) { - ecx.span_bug(span, &format!( - "error writing metadata for triple `{}` and crate `{}`, error: {}, \ - cause: {:?}", - target_triple, crate_name, e.description(), e.source() - )); - } - }); - } else { - ecx.span_err(span, &format!( - "failed to write metadata for crate `{}` because $CFG_COMPILER_HOST_TRIPLE is not set", - crate_name)); - } - // Construct the output expression. let (count, expr) = ecx.parse_sess.registered_diagnostics.with_lock(|diagnostics| { diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index b0a4a6af983..a63c4181d5e 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -3,7 +3,7 @@ use crate::attr::{HasAttrs, Stability, Deprecation}; use crate::source_map::SourceMap; use crate::edition::Edition; use crate::ext::expand::{self, AstFragment, Invocation}; -use crate::ext::hygiene::{ExpnId, SyntaxContext, Transparency}; +use crate::ext::hygiene::{ExpnId, Transparency}; use crate::mut_visit::{self, MutVisitor}; use crate::parse::{self, parser, DirectoryOwnership}; use crate::parse::token; @@ -549,8 +549,6 @@ pub struct SyntaxExtension { pub kind: SyntaxExtensionKind, /// Span of the macro definition. pub span: Span, - /// Hygienic properties of spans produced by this macro by default. - pub default_transparency: Transparency, /// Whitelist of unstable features that are treated as stable inside this macro. pub allow_internal_unstable: Option<Lrc<[Symbol]>>, /// Suppresses the `unsafe_code` lint for code produced by this macro. @@ -572,22 +570,6 @@ pub struct SyntaxExtension { pub is_derive_copy: bool, } -impl SyntaxExtensionKind { - /// When a syntax extension is constructed, - /// its transparency can often be inferred from its kind. - fn default_transparency(&self) -> Transparency { - match self { - SyntaxExtensionKind::Bang(..) | - SyntaxExtensionKind::Attr(..) | - SyntaxExtensionKind::Derive(..) | - SyntaxExtensionKind::NonMacroAttr { .. } => Transparency::Opaque, - SyntaxExtensionKind::LegacyBang(..) | - SyntaxExtensionKind::LegacyAttr(..) | - SyntaxExtensionKind::LegacyDerive(..) => Transparency::SemiTransparent, - } - } -} - impl SyntaxExtension { /// Returns which kind of macro calls this syntax extension. pub fn macro_kind(&self) -> MacroKind { @@ -606,7 +588,6 @@ impl SyntaxExtension { pub fn default(kind: SyntaxExtensionKind, edition: Edition) -> SyntaxExtension { SyntaxExtension { span: DUMMY_SP, - default_transparency: kind.default_transparency(), allow_internal_unstable: None, allow_internal_unsafe: false, local_inner_macros: false, @@ -646,7 +627,6 @@ impl SyntaxExtension { parent, call_site, def_site: self.span, - default_transparency: self.default_transparency, allow_internal_unstable: self.allow_internal_unstable.clone(), allow_internal_unsafe: self.allow_internal_unsafe, local_inner_macros: self.local_inner_macros, @@ -682,8 +662,9 @@ pub trait Resolver { fn resolve_imports(&mut self); - fn resolve_macro_invocation(&mut self, invoc: &Invocation, invoc_id: ExpnId, force: bool) - -> Result<Option<Lrc<SyntaxExtension>>, Indeterminate>; + fn resolve_macro_invocation( + &mut self, invoc: &Invocation, eager_expansion_root: ExpnId, force: bool + ) -> Result<Option<Lrc<SyntaxExtension>>, Indeterminate>; fn check_unused_macros(&self); @@ -759,23 +740,39 @@ impl<'a> ExtCtxt<'a> { pub fn call_site(&self) -> Span { self.current_expansion.id.expn_data().call_site } - pub fn backtrace(&self) -> SyntaxContext { - SyntaxContext::root().apply_mark(self.current_expansion.id) + + /// Equivalent of `Span::def_site` from the proc macro API, + /// except that the location is taken from the span passed as an argument. + pub fn with_def_site_ctxt(&self, span: Span) -> Span { + span.with_ctxt_from_mark(self.current_expansion.id, Transparency::Opaque) + } + + /// Equivalent of `Span::call_site` from the proc macro API, + /// except that the location is taken from the span passed as an argument. + pub fn with_call_site_ctxt(&self, span: Span) -> Span { + span.with_ctxt_from_mark(self.current_expansion.id, Transparency::Transparent) + } + + /// Span with a context reproducing `macro_rules` hygiene (hygienic locals, unhygienic items). + /// FIXME: This should be eventually replaced either with `with_def_site_ctxt` (preferably), + /// or with `with_call_site_ctxt` (where necessary). + pub fn with_legacy_ctxt(&self, span: Span) -> Span { + span.with_ctxt_from_mark(self.current_expansion.id, Transparency::SemiTransparent) } /// Returns span for the macro which originally caused the current expansion to happen. /// /// Stops backtracing at include! boundary. pub fn expansion_cause(&self) -> Option<Span> { - let mut ctxt = self.backtrace(); + let mut expn_id = self.current_expansion.id; let mut last_macro = None; loop { - let expn_data = ctxt.outer_expn_data(); + let expn_data = expn_id.expn_data(); // Stop going up the backtrace once include! is encountered if expn_data.is_root() || expn_data.kind.descr() == sym::include { break; } - ctxt = expn_data.call_site.ctxt(); + expn_id = expn_data.call_site.ctxt().outer_expn(); last_macro = Some(expn_data.call_site); } last_macro @@ -864,7 +861,7 @@ impl<'a> ExtCtxt<'a> { ast::Ident::from_str(st) } pub fn std_path(&self, components: &[Symbol]) -> Vec<ast::Ident> { - let def_site = DUMMY_SP.apply_mark(self.current_expansion.id); + let def_site = self.with_def_site_ctxt(DUMMY_SP); iter::once(Ident::new(kw::DollarCrate, def_site)) .chain(components.iter().map(|&s| Ident::with_dummy_span(s))) .collect() @@ -908,12 +905,9 @@ impl<'a> ExtCtxt<'a> { /// compilation on error, merely emits a non-fatal error and returns `None`. pub fn expr_to_spanned_string<'a>( cx: &'a mut ExtCtxt<'_>, - mut expr: P<ast::Expr>, + expr: P<ast::Expr>, err_msg: &str, ) -> Result<(Symbol, ast::StrStyle, Span), Option<DiagnosticBuilder<'a>>> { - // Update `expr.span`'s ctxt now in case expr is an `include!` macro invocation. - expr.span = expr.span.apply_mark(cx.current_expansion.id); - // Perform eager expansion on the expression. // We want to be able to handle e.g., `concat!("foo", "bar")`. let expr = cx.expander().fully_expand_fragment(AstFragment::Expr(expr)).make_expr(); diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index c1d52c97455..c8c0f4ce36e 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -305,9 +305,11 @@ impl<'a, 'b> MacroExpander<'a, 'b> { continue }; - let scope = + let eager_expansion_root = if self.monotonic { invoc.expansion_data.id } else { orig_expansion_data.id }; - let ext = match self.cx.resolver.resolve_macro_invocation(&invoc, scope, force) { + let ext = match self.cx.resolver.resolve_macro_invocation( + &invoc, eager_expansion_root, force + ) { Ok(ext) => ext, Err(Indeterminate) => { undetermined_invocations.push(invoc); @@ -318,7 +320,6 @@ impl<'a, 'b> MacroExpander<'a, 'b> { progress = true; let ExpansionData { depth, id: expn_id, .. } = invoc.expansion_data; self.cx.current_expansion = invoc.expansion_data.clone(); - self.cx.current_expansion.id = scope; // FIXME(jseyfried): Refactor out the following logic let (expanded_fragment, new_invocations) = if let Some(ext) = ext { @@ -564,7 +565,6 @@ impl<'a, 'b> MacroExpander<'a, 'b> { return fragment_kind.dummy(span); } let meta = ast::MetaItem { node: ast::MetaItemKind::Word, span, path }; - let span = span.with_ctxt(self.cx.backtrace()); let items = expander.expand(self.cx, span, &meta, item); fragment_kind.expect_from_annotatables(items) } @@ -1388,17 +1388,3 @@ impl<'feat> ExpansionConfig<'feat> { self.features.map_or(false, |features| features.custom_inner_attributes) } } - -// A Marker adds the given mark to the syntax context. -#[derive(Debug)] -pub struct Marker(pub ExpnId); - -impl MutVisitor for Marker { - fn visit_span(&mut self, span: &mut Span) { - *span = span.apply_mark(self.0) - } - - fn visit_mac(&mut self, mac: &mut ast::Mac) { - noop_visit_mac(mac, self) - } -} diff --git a/src/libsyntax/ext/proc_macro_server.rs b/src/libsyntax/ext/proc_macro_server.rs index 1619fa69941..b1bbd2aaac9 100644 --- a/src/libsyntax/ext/proc_macro_server.rs +++ b/src/libsyntax/ext/proc_macro_server.rs @@ -7,7 +7,6 @@ use crate::tokenstream::{self, DelimSpan, IsJoint::*, TokenStream, TreeAndJoint} use errors::{Diagnostic, DiagnosticBuilder}; use rustc_data_structures::sync::Lrc; use syntax_pos::{BytePos, FileName, MultiSpan, Pos, SourceFile, Span}; -use syntax_pos::hygiene::{SyntaxContext, Transparency}; use syntax_pos::symbol::{kw, sym, Symbol}; use proc_macro::{Delimiter, Level, LineColumn, Spacing}; @@ -363,16 +362,10 @@ impl<'a> Rustc<'a> { pub fn new(cx: &'a ExtCtxt<'_>) -> Self { // No way to determine def location for a proc macro right now, so use call location. let location = cx.current_expansion.id.expn_data().call_site; - let to_span = |transparency| { - location.with_ctxt( - SyntaxContext::root() - .apply_mark_with_transparency(cx.current_expansion.id, transparency), - ) - }; Rustc { sess: cx.parse_sess, - def_site: to_span(Transparency::Opaque), - call_site: to_span(Transparency::Transparent), + def_site: cx.with_def_site_ctxt(location), + call_site: cx.with_call_site_ctxt(location), } } diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs index b057a9ad44d..37cb8467ff5 100644 --- a/src/libsyntax/ext/tt/macro_rules.rs +++ b/src/libsyntax/ext/tt/macro_rules.rs @@ -19,6 +19,7 @@ use crate::{ast, attr, attr::TransparencyError}; use errors::{DiagnosticBuilder, FatalError}; use log::debug; +use syntax_pos::hygiene::Transparency; use syntax_pos::Span; use rustc_data_structures::fx::FxHashMap; @@ -128,6 +129,7 @@ impl<'a> ParserAnyMacro<'a> { struct MacroRulesMacroExpander { name: ast::Ident, span: Span, + transparency: Transparency, lhses: Vec<quoted::TokenTree>, rhses: Vec<quoted::TokenTree>, valid: bool, @@ -143,7 +145,9 @@ impl TTMacroExpander for MacroRulesMacroExpander { if !self.valid { return DummyResult::any(sp); } - generic_extension(cx, sp, self.span, self.name, input, &self.lhses, &self.rhses) + generic_extension( + cx, sp, self.span, self.name, self.transparency, input, &self.lhses, &self.rhses + ) } } @@ -158,6 +162,7 @@ fn generic_extension<'cx>( sp: Span, def_span: Span, name: ast::Ident, + transparency: Transparency, arg: TokenStream, lhses: &[quoted::TokenTree], rhses: &[quoted::TokenTree], @@ -187,7 +192,7 @@ fn generic_extension<'cx>( let rhs_spans = rhs.iter().map(|t| t.span()).collect::<Vec<_>>(); // rhs has holes ( `$id` and `$(...)` that need filled) - let mut tts = transcribe(cx, &named_matches, rhs); + let mut tts = transcribe(cx, &named_matches, rhs, transparency); // Replace all the tokens for the corresponding positions in the macro, to maintain // proper positions in error reporting, while maintaining the macro_backtrace. @@ -415,11 +420,7 @@ pub fn compile( // that is not lint-checked and trigger the "failed to process buffered lint here" bug. valid &= macro_check::check_meta_variables(sess, ast::CRATE_NODE_ID, def.span, &lhses, &rhses); - let expander: Box<_> = - Box::new(MacroRulesMacroExpander { name: def.ident, span: def.span, lhses, rhses, valid }); - - let (default_transparency, transparency_error) = - attr::find_transparency(&def.attrs, body.legacy); + let (transparency, transparency_error) = attr::find_transparency(&def.attrs, body.legacy); match transparency_error { Some(TransparencyError::UnknownTransparency(value, span)) => sess.span_diagnostic.span_err( @@ -432,6 +433,10 @@ pub fn compile( None => {} } + let expander: Box<_> = Box::new(MacroRulesMacroExpander { + name: def.ident, span: def.span, transparency, lhses, rhses, valid + }); + let allow_internal_unstable = attr::find_by_name(&def.attrs, sym::allow_internal_unstable).map(|attr| { attr.meta_item_list() @@ -473,7 +478,6 @@ pub fn compile( SyntaxExtension { kind: SyntaxExtensionKind::LegacyBang(expander), span: def.span, - default_transparency, allow_internal_unstable, allow_internal_unsafe: attr::contains_name(&def.attrs, sym::allow_internal_unsafe), local_inner_macros, diff --git a/src/libsyntax/ext/tt/transcribe.rs b/src/libsyntax/ext/tt/transcribe.rs index 214e721fd15..30d5df13dce 100644 --- a/src/libsyntax/ext/tt/transcribe.rs +++ b/src/libsyntax/ext/tt/transcribe.rs @@ -1,9 +1,8 @@ -use crate::ast::Ident; +use crate::ast::{Ident, Mac}; use crate::ext::base::ExtCtxt; -use crate::ext::expand::Marker; use crate::ext::tt::macro_parser::{MatchedNonterminal, MatchedSeq, NamedMatch}; use crate::ext::tt::quoted; -use crate::mut_visit::noop_visit_tt; +use crate::mut_visit::{self, MutVisitor}; use crate::parse::token::{self, NtTT, Token}; use crate::tokenstream::{DelimSpan, TokenStream, TokenTree, TreeAndJoint}; @@ -11,8 +10,31 @@ use smallvec::{smallvec, SmallVec}; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::sync::Lrc; +use syntax_pos::hygiene::{ExpnId, Transparency}; +use syntax_pos::Span; + use std::mem; +// A Marker adds the given mark to the syntax context. +struct Marker(ExpnId, Transparency); + +impl MutVisitor for Marker { + fn visit_span(&mut self, span: &mut Span) { + *span = span.apply_mark(self.0, self.1) + } + + fn visit_mac(&mut self, mac: &mut Mac) { + mut_visit::noop_visit_mac(mac, self) + } +} + +impl Marker { + fn visit_delim_span(&mut self, dspan: &mut DelimSpan) { + self.visit_span(&mut dspan.open); + self.visit_span(&mut dspan.close); + } +} + /// An iterator over the token trees in a delimited token tree (`{ ... }`) or a sequence (`$(...)`). enum Frame { Delimited { forest: Lrc<quoted::Delimited>, idx: usize, span: DelimSpan }, @@ -68,6 +90,7 @@ pub(super) fn transcribe( cx: &ExtCtxt<'_>, interp: &FxHashMap<Ident, NamedMatch>, src: Vec<quoted::TokenTree>, + transparency: Transparency, ) -> TokenStream { // Nothing for us to transcribe... if src.is_empty() { @@ -96,6 +119,7 @@ pub(super) fn transcribe( // again, and we are done transcribing. let mut result: Vec<TreeAndJoint> = Vec::new(); let mut result_stack = Vec::new(); + let mut marker = Marker(cx.current_expansion.id, transparency); loop { // Look at the last frame on the stack. @@ -207,7 +231,7 @@ pub(super) fn transcribe( } // Replace the meta-var with the matched token tree from the invocation. - quoted::TokenTree::MetaVar(mut sp, ident) => { + quoted::TokenTree::MetaVar(mut sp, mut ident) => { // Find the matched nonterminal from the macro invocation, and use it to replace // the meta-var. if let Some(cur_matched) = lookup_cur_matched(ident, interp, &repeats) { @@ -218,7 +242,7 @@ pub(super) fn transcribe( if let NtTT(ref tt) = **nt { result.push(tt.clone().into()); } else { - sp = sp.apply_mark(cx.current_expansion.id); + marker.visit_span(&mut sp); let token = TokenTree::token(token::Interpolated(nt.clone()), sp); result.push(token.into()); } @@ -232,9 +256,8 @@ pub(super) fn transcribe( } else { // If we aren't able to match the meta-var, we push it back into the result but // with modified syntax context. (I believe this supports nested macros). - let ident = - Ident::new(ident.name, ident.span.apply_mark(cx.current_expansion.id)); - sp = sp.apply_mark(cx.current_expansion.id); + marker.visit_span(&mut sp); + marker.visit_ident(&mut ident); result.push(TokenTree::token(token::Dollar, sp).into()); result.push(TokenTree::Token(Token::from_ast_ident(ident)).into()); } @@ -246,7 +269,7 @@ pub(super) fn transcribe( // jump back out of the Delimited, pop the result_stack and add the new results back to // the previous results (from outside the Delimited). quoted::TokenTree::Delimited(mut span, delimited) => { - span = span.apply_mark(cx.current_expansion.id); + marker.visit_delim_span(&mut span); stack.push(Frame::Delimited { forest: delimited, idx: 0, span }); result_stack.push(mem::take(&mut result)); } @@ -254,9 +277,8 @@ pub(super) fn transcribe( // Nothing much to do here. Just push the token to the result, being careful to // preserve syntax context. quoted::TokenTree::Token(token) => { - let mut marker = Marker(cx.current_expansion.id); let mut tt = TokenTree::Token(token); - noop_visit_tt(&mut tt, &mut marker); + marker.visit_tt(&mut tt); result.push(tt.into()); } diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs deleted file mode 100644 index bbc3ae28225..00000000000 --- a/src/libsyntax/feature_gate.rs +++ /dev/null @@ -1,2510 +0,0 @@ -//! # Feature gating -//! -//! This module implements the gating necessary for preventing certain compiler -//! features from being used by default. This module will crawl a pre-expanded -//! AST to ensure that there are no features which are used that are not -//! enabled. -//! -//! Features are enabled in programs via the crate-level attributes of -//! `#![feature(...)]` with a comma-separated list of features. -//! -//! For the purpose of future feature-tracking, once code for detection of feature -//! gate usage is added, *do not remove it again* even once the feature -//! becomes stable. - -use AttributeType::*; -use AttributeGate::*; - -use crate::ast::{ - self, AssocTyConstraint, AssocTyConstraintKind, NodeId, GenericParam, GenericParamKind, - PatKind, RangeEnd, -}; -use crate::attr::{self, check_builtin_attribute, AttributeTemplate}; -use crate::source_map::Spanned; -use crate::edition::{ALL_EDITIONS, Edition}; -use crate::visit::{self, FnKind, Visitor}; -use crate::parse::{token, ParseSess}; -use crate::parse::parser::Parser; -use crate::symbol::{Symbol, sym}; -use crate::tokenstream::TokenTree; - -use errors::{Applicability, DiagnosticBuilder, Handler}; -use rustc_data_structures::fx::FxHashMap; -use rustc_target::spec::abi::Abi; -use syntax_pos::{Span, DUMMY_SP, MultiSpan}; -use log::debug; -use lazy_static::lazy_static; - -use std::env; - -macro_rules! set { - ($field: ident) => {{ - fn f(features: &mut Features, _: Span) { - features.$field = true; - } - f as fn(&mut Features, Span) - }} -} - -macro_rules! declare_features { - ($((active, $feature: ident, $ver: expr, $issue: expr, $edition: expr),)+) => { - /// Represents active features that are currently being implemented or - /// currently being considered for addition/removal. - const ACTIVE_FEATURES: - &[(Symbol, &str, Option<u32>, Option<Edition>, fn(&mut Features, Span))] = - &[$((sym::$feature, $ver, $issue, $edition, set!($feature))),+]; - - /// A set of features to be used by later passes. - #[derive(Clone)] - pub struct Features { - /// `#![feature]` attrs for language features, for error reporting - pub declared_lang_features: Vec<(Symbol, Span, Option<Symbol>)>, - /// `#![feature]` attrs for non-language (library) features - pub declared_lib_features: Vec<(Symbol, Span)>, - $(pub $feature: bool),+ - } - - impl Features { - pub fn new() -> Features { - Features { - declared_lang_features: Vec::new(), - declared_lib_features: Vec::new(), - $($feature: false),+ - } - } - - pub fn walk_feature_fields<F>(&self, mut f: F) - where F: FnMut(&str, bool) - { - $(f(stringify!($feature), self.$feature);)+ - } - } - }; - - ($((removed, $feature: ident, $ver: expr, $issue: expr, None, $reason: expr),)+) => { - /// Represents unstable features which have since been removed (it was once Active) - const REMOVED_FEATURES: &[(Symbol, &str, Option<u32>, Option<&str>)] = &[ - $((sym::$feature, $ver, $issue, $reason)),+ - ]; - }; - - ($((stable_removed, $feature: ident, $ver: expr, $issue: expr, None),)+) => { - /// Represents stable features which have since been removed (it was once Accepted) - const STABLE_REMOVED_FEATURES: &[(Symbol, &str, Option<u32>, Option<&str>)] = &[ - $((sym::$feature, $ver, $issue, None)),+ - ]; - }; - - ($((accepted, $feature: ident, $ver: expr, $issue: expr, None),)+) => { - /// Those language feature has since been Accepted (it was once Active) - const ACCEPTED_FEATURES: &[(Symbol, &str, Option<u32>, Option<&str>)] = &[ - $((sym::$feature, $ver, $issue, None)),+ - ]; - } -} - -// If you change this, please modify `src/doc/unstable-book` as well. -// -// Don't ever remove anything from this list; set them to 'Removed'. -// -// The version numbers here correspond to the version in which the current status -// was set. This is most important for knowing when a particular feature became -// stable (active). -// -// Note that the features are grouped into internal/user-facing and then -// sorted by version inside those groups. This is inforced with tidy. -// -// N.B., `tools/tidy/src/features.rs` parses this information directly out of the -// source, so take care when modifying it. - -declare_features! ( - // ------------------------------------------------------------------------- - // feature-group-start: internal feature gates - // ------------------------------------------------------------------------- - - // no-tracking-issue-start - - // Allows using compiler's own crates. - (active, rustc_private, "1.0.0", Some(27812), None), - - // Allows using the `rust-intrinsic`'s "ABI". - (active, intrinsics, "1.0.0", None, None), - - // Allows using `#[lang = ".."]` attribute for linking items to special compiler logic. - (active, lang_items, "1.0.0", None, None), - - // Allows using the `#[stable]` and `#[unstable]` attributes. - (active, staged_api, "1.0.0", None, None), - - // Allows using `#[allow_internal_unstable]`. This is an - // attribute on `macro_rules!` and can't use the attribute handling - // below (it has to be checked before expansion possibly makes - // macros disappear). - (active, allow_internal_unstable, "1.0.0", None, None), - - // Allows using `#[allow_internal_unsafe]`. This is an - // attribute on `macro_rules!` and can't use the attribute handling - // below (it has to be checked before expansion possibly makes - // macros disappear). - (active, allow_internal_unsafe, "1.0.0", None, None), - - // Allows using the macros: - // + `__diagnostic_used` - // + `__register_diagnostic` - // +`__build_diagnostic_array` - (active, rustc_diagnostic_macros, "1.0.0", None, None), - - // Allows using `#[rustc_const_unstable(feature = "foo", ..)]` which - // lets a function to be `const` when opted into with `#![feature(foo)]`. - (active, rustc_const_unstable, "1.0.0", None, None), - - // no-tracking-issue-end - - // Allows using `#[link_name="llvm.*"]`. - (active, link_llvm_intrinsics, "1.0.0", Some(29602), None), - - // Allows using `rustc_*` attributes (RFC 572). - (active, rustc_attrs, "1.0.0", Some(29642), None), - - // Allows using `#[on_unimplemented(..)]` on traits. - (active, on_unimplemented, "1.0.0", Some(29628), None), - - // Allows using the `box $expr` syntax. - (active, box_syntax, "1.0.0", Some(49733), None), - - // Allows using `#[main]` to replace the entrypoint `#[lang = "start"]` calls. - (active, main, "1.0.0", Some(29634), None), - - // Allows using `#[start]` on a function indicating that it is the program entrypoint. - (active, start, "1.0.0", Some(29633), None), - - // Allows using the `#[fundamental]` attribute. - (active, fundamental, "1.0.0", Some(29635), None), - - // Allows using the `rust-call` ABI. - (active, unboxed_closures, "1.0.0", Some(29625), None), - - // Allows using the `#[linkage = ".."]` attribute. - (active, linkage, "1.0.0", Some(29603), None), - - // Allows features specific to OIBIT (auto traits). - (active, optin_builtin_traits, "1.0.0", Some(13231), None), - - // Allows using `box` in patterns (RFC 469). - (active, box_patterns, "1.0.0", Some(29641), None), - - // no-tracking-issue-start - - // Allows using `#[prelude_import]` on glob `use` items. - (active, prelude_import, "1.2.0", None, None), - - // no-tracking-issue-end - - // no-tracking-issue-start - - // Allows using `#[omit_gdb_pretty_printer_section]`. - (active, omit_gdb_pretty_printer_section, "1.5.0", None, None), - - // Allows using the `vectorcall` ABI. - (active, abi_vectorcall, "1.7.0", None, None), - - // no-tracking-issue-end - - // Allows using `#[structural_match]` which indicates that a type is structurally matchable. - (active, structural_match, "1.8.0", Some(31434), None), - - // Allows using the `may_dangle` attribute (RFC 1327). - (active, dropck_eyepatch, "1.10.0", Some(34761), None), - - // Allows using the `#![panic_runtime]` attribute. - (active, panic_runtime, "1.10.0", Some(32837), None), - - // Allows declaring with `#![needs_panic_runtime]` that a panic runtime is needed. - (active, needs_panic_runtime, "1.10.0", Some(32837), None), - - // no-tracking-issue-start - - // Allows identifying the `compiler_builtins` crate. - (active, compiler_builtins, "1.13.0", None, None), - - // Allows using the `unadjusted` ABI; perma-unstable. - (active, abi_unadjusted, "1.16.0", None, None), - - // Allows identifying crates that contain sanitizer runtimes. - (active, sanitizer_runtime, "1.17.0", None, None), - - // Used to identify crates that contain the profiler runtime. - (active, profiler_runtime, "1.18.0", None, None), - - // Allows using the `thiscall` ABI. - (active, abi_thiscall, "1.19.0", None, None), - - // Allows using `#![needs_allocator]`, an implementation detail of `#[global_allocator]`. - (active, allocator_internals, "1.20.0", None, None), - - // no-tracking-issue-end - - // Added for testing E0705; perma-unstable. - (active, test_2018_feature, "1.31.0", Some(0), Some(Edition::Edition2018)), - - // ------------------------------------------------------------------------- - // feature-group-end: internal feature gates - // ------------------------------------------------------------------------- - - // ------------------------------------------------------------------------- - // feature-group-start: actual feature gates (target features) - // ------------------------------------------------------------------------- - - // FIXME: Document these and merge with the list below. - - // Unstable `#[target_feature]` directives. - (active, arm_target_feature, "1.27.0", Some(44839), None), - (active, aarch64_target_feature, "1.27.0", Some(44839), None), - (active, hexagon_target_feature, "1.27.0", Some(44839), None), - (active, powerpc_target_feature, "1.27.0", Some(44839), None), - (active, mips_target_feature, "1.27.0", Some(44839), None), - (active, avx512_target_feature, "1.27.0", Some(44839), None), - (active, mmx_target_feature, "1.27.0", Some(44839), None), - (active, sse4a_target_feature, "1.27.0", Some(44839), None), - (active, tbm_target_feature, "1.27.0", Some(44839), None), - (active, wasm_target_feature, "1.30.0", Some(44839), None), - (active, adx_target_feature, "1.32.0", Some(44839), None), - (active, cmpxchg16b_target_feature, "1.32.0", Some(44839), None), - (active, movbe_target_feature, "1.34.0", Some(44839), None), - (active, rtm_target_feature, "1.35.0", Some(44839), None), - (active, f16c_target_feature, "1.36.0", Some(44839), None), - - // ------------------------------------------------------------------------- - // feature-group-end: actual feature gates (target features) - // ------------------------------------------------------------------------- - - // ------------------------------------------------------------------------- - // feature-group-start: actual feature gates - // ------------------------------------------------------------------------- - - // Allows using the `#[link_args]` attribute. - (active, link_args, "1.0.0", Some(29596), None), - - // Allows defining identifiers beyond ASCII. - (active, non_ascii_idents, "1.0.0", Some(55467), None), - - // Allows using `#[plugin_registrar]` on functions. - (active, plugin_registrar, "1.0.0", Some(29597), None), - - // Allows using `#![plugin(myplugin)]`. - (active, plugin, "1.0.0", Some(29597), None), - - // Allows using `#[thread_local]` on `static` items. - (active, thread_local, "1.0.0", Some(29594), None), - - // Allows the use of SIMD types in functions declared in `extern` blocks. - (active, simd_ffi, "1.0.0", Some(27731), None), - - // Allows using custom attributes (RFC 572). - (active, custom_attribute, "1.0.0", Some(29642), None), - - // Allows using non lexical lifetimes (RFC 2094). - (active, nll, "1.0.0", Some(43234), None), - - // Allows using slice patterns. - (active, slice_patterns, "1.0.0", Some(62254), None), - - // Allows the definition of `const` functions with some advanced features. - (active, const_fn, "1.2.0", Some(57563), None), - - // Allows associated type defaults. - (active, associated_type_defaults, "1.2.0", Some(29661), None), - - // Allows `#![no_core]`. - (active, no_core, "1.3.0", Some(29639), None), - - // Allows default type parameters to influence type inference. - (active, default_type_parameter_fallback, "1.3.0", Some(27336), None), - - // Allows `repr(simd)` and importing the various simd intrinsics. - (active, repr_simd, "1.4.0", Some(27731), None), - - // Allows `extern "platform-intrinsic" { ... }`. - (active, platform_intrinsics, "1.4.0", Some(27731), None), - - // Allows `#[unwind(..)]`. - // - // Permits specifying whether a function should permit unwinding or abort on unwind. - (active, unwind_attributes, "1.4.0", Some(58760), None), - - // Allows `#[no_debug]`. - (active, no_debug, "1.5.0", Some(29721), None), - - // Allows attributes on expressions and non-item statements. - (active, stmt_expr_attributes, "1.6.0", Some(15701), None), - - // Allows the use of type ascription in expressions. - (active, type_ascription, "1.6.0", Some(23416), None), - - // Allows `cfg(target_thread_local)`. - (active, cfg_target_thread_local, "1.7.0", Some(29594), None), - - // Allows specialization of implementations (RFC 1210). - (active, specialization, "1.7.0", Some(31844), None), - - // Allows using `#[naked]` on functions. - (active, naked_functions, "1.9.0", Some(32408), None), - - // Allows `cfg(target_has_atomic = "...")`. - (active, cfg_target_has_atomic, "1.9.0", Some(32976), None), - - // Allows `X..Y` patterns. - (active, exclusive_range_pattern, "1.11.0", Some(37854), None), - - // Allows the `!` type. Does not imply 'exhaustive_patterns' (below) any more. - (active, never_type, "1.13.0", Some(35121), None), - - // Allows exhaustive pattern matching on types that contain uninhabited types. - (active, exhaustive_patterns, "1.13.0", Some(51085), None), - - // Allows untagged unions `union U { ... }`. - (active, untagged_unions, "1.13.0", Some(32836), None), - - // Allows `#[link(..., cfg(..))]`. - (active, link_cfg, "1.14.0", Some(37406), None), - - // Allows `extern "ptx-*" fn()`. - (active, abi_ptx, "1.15.0", Some(38788), None), - - // Allows the `#[repr(i128)]` attribute for enums. - (active, repr128, "1.16.0", Some(35118), None), - - // Allows `#[link(kind="static-nobundle"...)]`. - (active, static_nobundle, "1.16.0", Some(37403), None), - - // Allows `extern "msp430-interrupt" fn()`. - (active, abi_msp430_interrupt, "1.16.0", Some(38487), None), - - // Allows declarative macros 2.0 (`macro`). - (active, decl_macro, "1.17.0", Some(39412), None), - - // Allows `extern "x86-interrupt" fn()`. - (active, abi_x86_interrupt, "1.17.0", Some(40180), None), - - // Allows overlapping impls of marker traits. - (active, overlapping_marker_traits, "1.18.0", Some(29864), None), - - // Allows a test to fail without failing the whole suite. - (active, allow_fail, "1.19.0", Some(46488), None), - - // Allows unsized tuple coercion. - (active, unsized_tuple_coercion, "1.20.0", Some(42877), None), - - // Allows defining generators. - (active, generators, "1.21.0", Some(43122), None), - - // Allows `#[doc(cfg(...))]`. - (active, doc_cfg, "1.21.0", Some(43781), None), - - // Allows `#[doc(masked)]`. - (active, doc_masked, "1.21.0", Some(44027), None), - - // Allows `#[doc(spotlight)]`. - (active, doc_spotlight, "1.22.0", Some(45040), None), - - // Allows `#[doc(include = "some-file")]`. - (active, external_doc, "1.22.0", Some(44732), None), - - // Allows future-proofing enums/structs with the `#[non_exhaustive]` attribute (RFC 2008). - (active, non_exhaustive, "1.22.0", Some(44109), None), - - // Allows using `crate` as visibility modifier, synonymous with `pub(crate)`. - (active, crate_visibility_modifier, "1.23.0", Some(53120), None), - - // Allows defining `extern type`s. - (active, extern_types, "1.23.0", Some(43467), None), - - // Allows trait methods with arbitrary self types. - (active, arbitrary_self_types, "1.23.0", Some(44874), None), - - // Allows in-band quantification of lifetime bindings (e.g., `fn foo(x: &'a u8) -> &'a u8`). - (active, in_band_lifetimes, "1.23.0", Some(44524), None), - - // Allows associated types to be generic, e.g., `type Foo<T>;` (RFC 1598). - (active, generic_associated_types, "1.23.0", Some(44265), None), - - // Allows defining `trait X = A + B;` alias items. - (active, trait_alias, "1.24.0", Some(41517), None), - - // Allows infering `'static` outlives requirements (RFC 2093). - (active, infer_static_outlives_requirements, "1.26.0", Some(54185), None), - - // Allows macro invocations in `extern {}` blocks. - (active, macros_in_extern, "1.27.0", Some(49476), None), - - // Allows accessing fields of unions inside `const` functions. - (active, const_fn_union, "1.27.0", Some(51909), None), - - // Allows casting raw pointers to `usize` during const eval. - (active, const_raw_ptr_to_usize_cast, "1.27.0", Some(51910), None), - - // Allows dereferencing raw pointers during const eval. - (active, const_raw_ptr_deref, "1.27.0", Some(51911), None), - - // Allows comparing raw pointers during const eval. - (active, const_compare_raw_pointers, "1.27.0", Some(53020), None), - - // Allows `#[doc(alias = "...")]`. - (active, doc_alias, "1.27.0", Some(50146), None), - - // Allows inconsistent bounds in where clauses. - (active, trivial_bounds, "1.28.0", Some(48214), None), - - // Allows `'a: { break 'a; }`. - (active, label_break_value, "1.28.0", Some(48594), None), - - // Allows using `#[doc(keyword = "...")]`. - (active, doc_keyword, "1.28.0", Some(51315), None), - - // Allows async and await syntax. - (active, async_await, "1.28.0", Some(50547), None), - - // Allows reinterpretation of the bits of a value of one type as another type during const eval. - (active, const_transmute, "1.29.0", Some(53605), None), - - // Allows using `try {...}` expressions. - (active, try_blocks, "1.29.0", Some(31436), None), - - // Allows defining an `#[alloc_error_handler]`. - (active, alloc_error_handler, "1.29.0", Some(51540), None), - - // Allows using the `amdgpu-kernel` ABI. - (active, abi_amdgpu_kernel, "1.29.0", Some(51575), None), - - // Allows panicking during const eval (producing compile-time errors). - (active, const_panic, "1.30.0", Some(51999), None), - - // Allows `#[marker]` on certain traits allowing overlapping implementations. - (active, marker_trait_attr, "1.30.0", Some(29864), None), - - // Allows macro invocations on modules expressions and statements and - // procedural macros to expand to non-items. - (active, proc_macro_hygiene, "1.30.0", Some(54727), None), - - // Allows unsized rvalues at arguments and parameters. - (active, unsized_locals, "1.30.0", Some(48055), None), - - // Allows custom test frameworks with `#![test_runner]` and `#[test_case]`. - (active, custom_test_frameworks, "1.30.0", Some(50297), None), - - // Allows non-builtin attributes in inner attribute position. - (active, custom_inner_attributes, "1.30.0", Some(54726), None), - - // Allows mixing bind-by-move in patterns and references to those identifiers in guards. - (active, bind_by_move_pattern_guards, "1.30.0", Some(15287), None), - - // Allows `impl Trait` in bindings (`let`, `const`, `static`). - (active, impl_trait_in_bindings, "1.30.0", Some(63065), None), - - // Allows using `reason` in lint attributes and the `#[expect(lint)]` lint check. - (active, lint_reasons, "1.31.0", Some(54503), None), - - // Allows exhaustive integer pattern matching on `usize` and `isize`. - (active, precise_pointer_size_matching, "1.32.0", Some(56354), None), - - // Allows relaxing the coherence rules such that - // `impl<T> ForeignTrait<LocalType> for ForeignType<T> is permitted. - (active, re_rebalance_coherence, "1.32.0", Some(55437), None), - - // Allows using `#[ffi_returns_twice]` on foreign functions. - (active, ffi_returns_twice, "1.34.0", Some(58314), None), - - // Allows const generic types (e.g. `struct Foo<const N: usize>(...);`). - (active, const_generics, "1.34.0", Some(44580), None), - - // Allows using `#[optimize(X)]`. - (active, optimize_attribute, "1.34.0", Some(54882), None), - - // Allows using C-variadics. - (active, c_variadic, "1.34.0", Some(44930), None), - - // Allows the user of associated type bounds. - (active, associated_type_bounds, "1.34.0", Some(52662), None), - - // Attributes on formal function params. - (active, param_attrs, "1.36.0", Some(60406), None), - - // Allows calling constructor functions in `const fn`. - (active, const_constructor, "1.37.0", Some(61456), None), - - // Allows `if/while p && let q = r && ...` chains. - (active, let_chains, "1.37.0", Some(53667), None), - - // Allows #[repr(transparent)] on enums (RFC 2645). - (active, transparent_enums, "1.37.0", Some(60405), None), - - // Allows #[repr(transparent)] on unions (RFC 2645). - (active, transparent_unions, "1.37.0", Some(60405), None), - - // Allows explicit discriminants on non-unit enum variants. - (active, arbitrary_enum_discriminant, "1.37.0", Some(60553), None), - - // Allows `impl Trait` with multiple unrelated lifetimes. - (active, member_constraints, "1.37.0", Some(61977), None), - - // Allows `async || body` closures. - (active, async_closure, "1.37.0", Some(62290), None), - - // Allows the use of `#[cfg(doctest)]`, set when rustdoc is collecting doctests - (active, cfg_doctest, "1.37.0", Some(62210), None), - - // Allows `[x; N]` where `x` is a constant (RFC 2203). - (active, const_in_array_repeat_expressions, "1.37.0", Some(49147), None), - - // Allows `impl Trait` to be used inside type aliases (RFC 2515). - (active, type_alias_impl_trait, "1.38.0", Some(63063), None), - - // Allows the use of or-patterns, e.g. `0 | 1`. - (active, or_patterns, "1.38.0", Some(54883), None), - - // ------------------------------------------------------------------------- - // feature-group-end: actual feature gates - // ------------------------------------------------------------------------- -); - -/// Some features are known to be incomplete and using them is likely to have -/// unanticipated results, such as compiler crashes. We warn the user about these -/// to alert them. -pub const INCOMPLETE_FEATURES: &[Symbol] = &[ - sym::impl_trait_in_bindings, - sym::generic_associated_types, - sym::const_generics, - sym::or_patterns, - sym::let_chains, -]; - -declare_features! ( - // ------------------------------------------------------------------------- - // feature-group-start: removed features - // ------------------------------------------------------------------------- - - (removed, import_shadowing, "1.0.0", None, None, None), - (removed, managed_boxes, "1.0.0", None, None, None), - // Allows use of unary negate on unsigned integers, e.g., -e for e: u8 - (removed, negate_unsigned, "1.0.0", Some(29645), None, None), - (removed, reflect, "1.0.0", Some(27749), None, None), - // A way to temporarily opt out of opt in copy. This will *never* be accepted. - (removed, opt_out_copy, "1.0.0", None, None, None), - (removed, quad_precision_float, "1.0.0", None, None, None), - (removed, struct_inherit, "1.0.0", None, None, None), - (removed, test_removed_feature, "1.0.0", None, None, None), - (removed, visible_private_types, "1.0.0", None, None, None), - (removed, unsafe_no_drop_flag, "1.0.0", None, None, None), - // Allows using items which are missing stability attributes - (removed, unmarked_api, "1.0.0", None, None, None), - (removed, allocator, "1.0.0", None, None, None), - (removed, simd, "1.0.0", Some(27731), None, - Some("removed in favor of `#[repr(simd)]`")), - (removed, advanced_slice_patterns, "1.0.0", Some(62254), None, - Some("merged into `#![feature(slice_patterns)]`")), - (removed, macro_reexport, "1.0.0", Some(29638), None, - Some("subsumed by `pub use`")), - (removed, pushpop_unsafe, "1.2.0", None, None, None), - (removed, needs_allocator, "1.4.0", Some(27389), None, - Some("subsumed by `#![feature(allocator_internals)]`")), - (removed, proc_macro_mod, "1.27.0", Some(54727), None, - Some("subsumed by `#![feature(proc_macro_hygiene)]`")), - (removed, proc_macro_expr, "1.27.0", Some(54727), None, - Some("subsumed by `#![feature(proc_macro_hygiene)]`")), - (removed, proc_macro_non_items, "1.27.0", Some(54727), None, - Some("subsumed by `#![feature(proc_macro_hygiene)]`")), - (removed, proc_macro_gen, "1.27.0", Some(54727), None, - Some("subsumed by `#![feature(proc_macro_hygiene)]`")), - (removed, panic_implementation, "1.28.0", Some(44489), None, - Some("subsumed by `#[panic_handler]`")), - // Allows the use of `#[derive(Anything)]` as sugar for `#[derive_Anything]`. - (removed, custom_derive, "1.32.0", Some(29644), None, - Some("subsumed by `#[proc_macro_derive]`")), - // Paths of the form: `extern::foo::bar` - (removed, extern_in_paths, "1.33.0", Some(55600), None, - Some("subsumed by `::foo::bar` paths")), - (removed, quote, "1.33.0", Some(29601), None, None), - // Allows using `#[unsafe_destructor_blind_to_params]` (RFC 1238). - (removed, dropck_parametricity, "1.38.0", Some(28498), None, None), - (removed, await_macro, "1.38.0", Some(50547), None, - Some("subsumed by `.await` syntax")), - // Allows defining `existential type`s. - (removed, existential_type, "1.38.0", Some(63063), None, - Some("removed in favor of `#![feature(type_alias_impl_trait)]`")), - - // ------------------------------------------------------------------------- - // feature-group-end: removed features - // ------------------------------------------------------------------------- -); - -declare_features! ( - (stable_removed, no_stack_check, "1.0.0", None, None), -); - -declare_features! ( - // ------------------------------------------------------------------------- - // feature-group-start: for testing purposes - // ------------------------------------------------------------------------- - - // A temporary feature gate used to enable parser extensions needed - // to bootstrap fix for #5723. - (accepted, issue_5723_bootstrap, "1.0.0", None, None), - // These are used to test this portion of the compiler, - // they don't actually mean anything. - (accepted, test_accepted_feature, "1.0.0", None, None), - - // ------------------------------------------------------------------------- - // feature-group-end: for testing purposes - // ------------------------------------------------------------------------- - - // ------------------------------------------------------------------------- - // feature-group-start: accepted features - // ------------------------------------------------------------------------- - - // Allows using associated `type`s in `trait`s. - (accepted, associated_types, "1.0.0", None, None), - // Allows using assigning a default type to type parameters in algebraic data type definitions. - (accepted, default_type_params, "1.0.0", None, None), - // FIXME: explain `globs`. - (accepted, globs, "1.0.0", None, None), - // Allows `macro_rules!` items. - (accepted, macro_rules, "1.0.0", None, None), - // Allows use of `&foo[a..b]` as a slicing syntax. - (accepted, slicing_syntax, "1.0.0", None, None), - // Allows struct variants `Foo { baz: u8, .. }` in enums (RFC 418). - (accepted, struct_variant, "1.0.0", None, None), - // Allows indexing tuples. - (accepted, tuple_indexing, "1.0.0", None, None), - // Allows the use of `if let` expressions. - (accepted, if_let, "1.0.0", None, None), - // Allows the use of `while let` expressions. - (accepted, while_let, "1.0.0", None, None), - // Allows using `#![no_std]`. - (accepted, no_std, "1.6.0", None, None), - // Allows overloading augmented assignment operations like `a += b`. - (accepted, augmented_assignments, "1.8.0", Some(28235), None), - // Allows empty structs and enum variants with braces. - (accepted, braced_empty_structs, "1.8.0", Some(29720), None), - // Allows `#[deprecated]` attribute. - (accepted, deprecated, "1.9.0", Some(29935), None), - // Allows macros to appear in the type position. - (accepted, type_macros, "1.13.0", Some(27245), None), - // Allows use of the postfix `?` operator in expressions. - (accepted, question_mark, "1.13.0", Some(31436), None), - // Allows `..` in tuple (struct) patterns. - (accepted, dotdot_in_tuple_patterns, "1.14.0", Some(33627), None), - // Allows some increased flexibility in the name resolution rules, - // especially around globs and shadowing (RFC 1560). - (accepted, item_like_imports, "1.15.0", Some(35120), None), - // Allows using `Self` and associated types in struct expressions and patterns. - (accepted, more_struct_aliases, "1.16.0", Some(37544), None), - // Allows elision of `'static` lifetimes in `static`s and `const`s. - (accepted, static_in_const, "1.17.0", Some(35897), None), - // Allows field shorthands (`x` meaning `x: x`) in struct literal expressions. - (accepted, field_init_shorthand, "1.17.0", Some(37340), None), - // Allows the definition recursive static items. - (accepted, static_recursion, "1.17.0", Some(29719), None), - // Allows `pub(restricted)` visibilities (RFC 1422). - (accepted, pub_restricted, "1.18.0", Some(32409), None), - // Allows `#![windows_subsystem]`. - (accepted, windows_subsystem, "1.18.0", Some(37499), None), - // Allows `break {expr}` with a value inside `loop`s. - (accepted, loop_break_value, "1.19.0", Some(37339), None), - // Allows numeric fields in struct expressions and patterns. - (accepted, relaxed_adts, "1.19.0", Some(35626), None), - // Allows coercing non capturing closures to function pointers. - (accepted, closure_to_fn_coercion, "1.19.0", Some(39817), None), - // Allows attributes on struct literal fields. - (accepted, struct_field_attributes, "1.20.0", Some(38814), None), - // Allows the definition of associated constants in `trait` or `impl` blocks. - (accepted, associated_consts, "1.20.0", Some(29646), None), - // Allows usage of the `compile_error!` macro. - (accepted, compile_error, "1.20.0", Some(40872), None), - // Allows code like `let x: &'static u32 = &42` to work (RFC 1414). - (accepted, rvalue_static_promotion, "1.21.0", Some(38865), None), - // Allows `Drop` types in constants (RFC 1440). - (accepted, drop_types_in_const, "1.22.0", Some(33156), None), - // Allows the sysV64 ABI to be specified on all platforms - // instead of just the platforms on which it is the C ABI. - (accepted, abi_sysv64, "1.24.0", Some(36167), None), - // Allows `repr(align(16))` struct attribute (RFC 1358). - (accepted, repr_align, "1.25.0", Some(33626), None), - // Allows '|' at beginning of match arms (RFC 1925). - (accepted, match_beginning_vert, "1.25.0", Some(44101), None), - // Allows nested groups in `use` items (RFC 2128). - (accepted, use_nested_groups, "1.25.0", Some(44494), None), - // Allows indexing into constant arrays. - (accepted, const_indexing, "1.26.0", Some(29947), None), - // Allows using `a..=b` and `..=b` as inclusive range syntaxes. - (accepted, inclusive_range_syntax, "1.26.0", Some(28237), None), - // Allows `..=` in patterns (RFC 1192). - (accepted, dotdoteq_in_patterns, "1.26.0", Some(28237), None), - // Allows `fn main()` with return types which implements `Termination` (RFC 1937). - (accepted, termination_trait, "1.26.0", Some(43301), None), - // Allows implementing `Clone` for closures where possible (RFC 2132). - (accepted, clone_closures, "1.26.0", Some(44490), None), - // Allows implementing `Copy` for closures where possible (RFC 2132). - (accepted, copy_closures, "1.26.0", Some(44490), None), - // Allows `impl Trait` in function arguments. - (accepted, universal_impl_trait, "1.26.0", Some(34511), None), - // Allows `impl Trait` in function return types. - (accepted, conservative_impl_trait, "1.26.0", Some(34511), None), - // Allows using the `u128` and `i128` types. - (accepted, i128_type, "1.26.0", Some(35118), None), - // Allows default match binding modes (RFC 2005). - (accepted, match_default_bindings, "1.26.0", Some(42640), None), - // Allows `'_` placeholder lifetimes. - (accepted, underscore_lifetimes, "1.26.0", Some(44524), None), - // Allows attributes on lifetime/type formal parameters in generics (RFC 1327). - (accepted, generic_param_attrs, "1.27.0", Some(48848), None), - // Allows `cfg(target_feature = "...")`. - (accepted, cfg_target_feature, "1.27.0", Some(29717), None), - // Allows `#[target_feature(...)]`. - (accepted, target_feature, "1.27.0", None, None), - // Allows using `dyn Trait` as a syntax for trait objects. - (accepted, dyn_trait, "1.27.0", Some(44662), None), - // Allows `#[must_use]` on functions, and introduces must-use operators (RFC 1940). - (accepted, fn_must_use, "1.27.0", Some(43302), None), - // Allows use of the `:lifetime` macro fragment specifier. - (accepted, macro_lifetime_matcher, "1.27.0", Some(34303), None), - // Allows `#[test]` functions where the return type implements `Termination` (RFC 1937). - (accepted, termination_trait_test, "1.27.0", Some(48854), None), - // Allows the `#[global_allocator]` attribute. - (accepted, global_allocator, "1.28.0", Some(27389), None), - // Allows `#[repr(transparent)]` attribute on newtype structs. - (accepted, repr_transparent, "1.28.0", Some(43036), None), - // Allows procedural macros in `proc-macro` crates. - (accepted, proc_macro, "1.29.0", Some(38356), None), - // Allows `foo.rs` as an alternative to `foo/mod.rs`. - (accepted, non_modrs_mods, "1.30.0", Some(44660), None), - // Allows use of the `:vis` macro fragment specifier - (accepted, macro_vis_matcher, "1.30.0", Some(41022), None), - // Allows importing and reexporting macros with `use`, - // enables macro modularization in general. - (accepted, use_extern_macros, "1.30.0", Some(35896), None), - // Allows keywords to be escaped for use as identifiers. - (accepted, raw_identifiers, "1.30.0", Some(48589), None), - // Allows attributes scoped to tools. - (accepted, tool_attributes, "1.30.0", Some(44690), None), - // Allows multi-segment paths in attributes and derives. - (accepted, proc_macro_path_invoc, "1.30.0", Some(38356), None), - // Allows all literals in attribute lists and values of key-value pairs. - (accepted, attr_literals, "1.30.0", Some(34981), None), - // Allows inferring outlives requirements (RFC 2093). - (accepted, infer_outlives_requirements, "1.30.0", Some(44493), None), - // Allows annotating functions conforming to `fn(&PanicInfo) -> !` with `#[panic_handler]`. - // This defines the behavior of panics. - (accepted, panic_handler, "1.30.0", Some(44489), None), - // Allows `#[used]` to preserve symbols (see llvm.used). - (accepted, used, "1.30.0", Some(40289), None), - // Allows `crate` in paths. - (accepted, crate_in_paths, "1.30.0", Some(45477), None), - // Allows resolving absolute paths as paths from other crates. - (accepted, extern_absolute_paths, "1.30.0", Some(44660), None), - // Allows access to crate names passed via `--extern` through prelude. - (accepted, extern_prelude, "1.30.0", Some(44660), None), - // Allows parentheses in patterns. - (accepted, pattern_parentheses, "1.31.0", Some(51087), None), - // Allows the definition of `const fn` functions. - (accepted, min_const_fn, "1.31.0", Some(53555), None), - // Allows scoped lints. - (accepted, tool_lints, "1.31.0", Some(44690), None), - // Allows lifetime elision in `impl` headers. For example: - // + `impl<I:Iterator> Iterator for &mut Iterator` - // + `impl Debug for Foo<'_>` - (accepted, impl_header_lifetime_elision, "1.31.0", Some(15872), None), - // Allows `extern crate foo as bar;`. This puts `bar` into extern prelude. - (accepted, extern_crate_item_prelude, "1.31.0", Some(55599), None), - // Allows use of the `:literal` macro fragment specifier (RFC 1576). - (accepted, macro_literal_matcher, "1.32.0", Some(35625), None), - // Allows use of `?` as the Kleene "at most one" operator in macros. - (accepted, macro_at_most_once_rep, "1.32.0", Some(48075), None), - // Allows `Self` struct constructor (RFC 2302). - (accepted, self_struct_ctor, "1.32.0", Some(51994), None), - // Allows `Self` in type definitions (RFC 2300). - (accepted, self_in_typedefs, "1.32.0", Some(49303), None), - // Allows `use x::y;` to search `x` in the current scope. - (accepted, uniform_paths, "1.32.0", Some(53130), None), - // Allows integer match exhaustiveness checking (RFC 2591). - (accepted, exhaustive_integer_patterns, "1.33.0", Some(50907), None), - // Allows `use path as _;` and `extern crate c as _;`. - (accepted, underscore_imports, "1.33.0", Some(48216), None), - // Allows `#[repr(packed(N))]` attribute on structs. - (accepted, repr_packed, "1.33.0", Some(33158), None), - // Allows irrefutable patterns in `if let` and `while let` statements (RFC 2086). - (accepted, irrefutable_let_patterns, "1.33.0", Some(44495), None), - // Allows calling `const unsafe fn` inside `unsafe` blocks in `const fn` functions. - (accepted, min_const_unsafe_fn, "1.33.0", Some(55607), None), - // Allows let bindings, assignments and destructuring in `const` functions and constants. - // As long as control flow is not implemented in const eval, `&&` and `||` may not be used - // at the same time as let bindings. - (accepted, const_let, "1.33.0", Some(48821), None), - // Allows `#[cfg_attr(predicate, multiple, attributes, here)]`. - (accepted, cfg_attr_multi, "1.33.0", Some(54881), None), - // Allows top level or-patterns (`p | q`) in `if let` and `while let`. - (accepted, if_while_or_patterns, "1.33.0", Some(48215), None), - // Allows `cfg(target_vendor = "...")`. - (accepted, cfg_target_vendor, "1.33.0", Some(29718), None), - // Allows `extern crate self as foo;`. - // This puts local crate root into extern prelude under name `foo`. - (accepted, extern_crate_self, "1.34.0", Some(56409), None), - // Allows arbitrary delimited token streams in non-macro attributes. - (accepted, unrestricted_attribute_tokens, "1.34.0", Some(55208), None), - // Allows paths to enum variants on type aliases including `Self`. - (accepted, type_alias_enum_variants, "1.37.0", Some(49683), None), - // Allows using `#[repr(align(X))]` on enums with equivalent semantics - // to wrapping an enum in a wrapper struct with `#[repr(align(X))]`. - (accepted, repr_align_enum, "1.37.0", Some(57996), None), - // Allows `const _: TYPE = VALUE`. - (accepted, underscore_const_names, "1.37.0", Some(54912), None), - - // ------------------------------------------------------------------------- - // feature-group-end: accepted features - // ------------------------------------------------------------------------- -); - -// If you change this, please modify `src/doc/unstable-book` as well. You must -// move that documentation into the relevant place in the other docs, and -// remove the chapter on the flag. - -#[derive(Copy, Clone, PartialEq, Debug)] -pub enum AttributeType { - /// Normal, builtin attribute that is consumed - /// by the compiler before the unused_attribute check - Normal, - - /// Builtin attribute that may not be consumed by the compiler - /// before the unused_attribute check. These attributes - /// will be ignored by the unused_attribute lint - Whitelisted, - - /// Builtin attribute that is only allowed at the crate level - CrateLevel, -} - -pub enum AttributeGate { - /// Is gated by a given feature gate, reason - /// and function to check if enabled - Gated(Stability, Symbol, &'static str, fn(&Features) -> bool), - - /// Ungated attribute, can be used on all release channels - Ungated, -} - -/// A convenience macro for constructing attribute templates. -/// E.g., `template!(Word, List: "description")` means that the attribute -/// supports forms `#[attr]` and `#[attr(description)]`. -macro_rules! template { - (Word) => { template!(@ true, None, None) }; - (List: $descr: expr) => { template!(@ false, Some($descr), None) }; - (NameValueStr: $descr: expr) => { template!(@ false, None, Some($descr)) }; - (Word, List: $descr: expr) => { template!(@ true, Some($descr), None) }; - (Word, NameValueStr: $descr: expr) => { template!(@ true, None, Some($descr)) }; - (List: $descr1: expr, NameValueStr: $descr2: expr) => { - template!(@ false, Some($descr1), Some($descr2)) - }; - (Word, List: $descr1: expr, NameValueStr: $descr2: expr) => { - template!(@ true, Some($descr1), Some($descr2)) - }; - (@ $word: expr, $list: expr, $name_value_str: expr) => { AttributeTemplate { - word: $word, list: $list, name_value_str: $name_value_str - } }; -} - -impl AttributeGate { - fn is_deprecated(&self) -> bool { - match *self { - Gated(Stability::Deprecated(_, _), ..) => true, - _ => false, - } - } -} - -#[derive(Copy, Clone, Debug)] -pub enum Stability { - Unstable, - // First argument is tracking issue link; second argument is an optional - // help message, which defaults to "remove this attribute" - Deprecated(&'static str, Option<&'static str>), -} - -// fn() is not Debug -impl std::fmt::Debug for AttributeGate { - fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match *self { - Gated(ref stab, name, expl, _) => - write!(fmt, "Gated({:?}, {}, {})", stab, name, expl), - Ungated => write!(fmt, "Ungated") - } - } -} - -macro_rules! cfg_fn { - ($field: ident) => {{ - fn f(features: &Features) -> bool { - features.$field - } - f as fn(&Features) -> bool - }} -} - -pub fn deprecated_attributes() -> Vec<&'static (Symbol, AttributeType, - AttributeTemplate, AttributeGate)> { - BUILTIN_ATTRIBUTES.iter().filter(|(.., gate)| gate.is_deprecated()).collect() -} - -pub fn is_builtin_attr_name(name: ast::Name) -> bool { - BUILTIN_ATTRIBUTE_MAP.get(&name).is_some() -} - -pub fn is_builtin_attr(attr: &ast::Attribute) -> bool { - attr.ident().and_then(|ident| BUILTIN_ATTRIBUTE_MAP.get(&ident.name)).is_some() -} - -/// Attributes that have a special meaning to rustc or rustdoc -pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ - // Normal attributes - - ( - sym::warn, - Normal, - template!(List: r#"lint1, lint2, ..., /*opt*/ reason = "...""#), - Ungated - ), - ( - sym::allow, - Normal, - template!(List: r#"lint1, lint2, ..., /*opt*/ reason = "...""#), - Ungated - ), - ( - sym::forbid, - Normal, - template!(List: r#"lint1, lint2, ..., /*opt*/ reason = "...""#), - Ungated - ), - ( - sym::deny, - Normal, - template!(List: r#"lint1, lint2, ..., /*opt*/ reason = "...""#), - Ungated - ), - - (sym::macro_use, Normal, template!(Word, List: "name1, name2, ..."), Ungated), - (sym::macro_export, Normal, template!(Word, List: "local_inner_macros"), Ungated), - (sym::plugin_registrar, Normal, template!(Word), Ungated), - - (sym::cfg, Normal, template!(List: "predicate"), Ungated), - (sym::cfg_attr, Normal, template!(List: "predicate, attr1, attr2, ..."), Ungated), - (sym::main, Normal, template!(Word), Ungated), - (sym::start, Normal, template!(Word), Ungated), - (sym::repr, Normal, template!(List: "C, packed, ..."), Ungated), - (sym::path, Normal, template!(NameValueStr: "file"), Ungated), - (sym::automatically_derived, Normal, template!(Word), Ungated), - (sym::no_mangle, Whitelisted, template!(Word), Ungated), - (sym::no_link, Normal, template!(Word), Ungated), - (sym::derive, Normal, template!(List: "Trait1, Trait2, ..."), Ungated), - ( - sym::should_panic, - Normal, - template!(Word, List: r#"expected = "reason"#, NameValueStr: "reason"), - Ungated - ), - (sym::ignore, Normal, template!(Word, NameValueStr: "reason"), Ungated), - (sym::no_implicit_prelude, Normal, template!(Word), Ungated), - (sym::reexport_test_harness_main, Normal, template!(NameValueStr: "name"), Ungated), - (sym::link_args, Normal, template!(NameValueStr: "args"), Gated(Stability::Unstable, - sym::link_args, - "the `link_args` attribute is experimental and not \ - portable across platforms, it is recommended to \ - use `#[link(name = \"foo\")] instead", - cfg_fn!(link_args))), - (sym::macro_escape, Normal, template!(Word), Ungated), - - // RFC #1445. - (sym::structural_match, Whitelisted, template!(Word), Gated(Stability::Unstable, - sym::structural_match, - "the semantics of constant patterns is \ - not yet settled", - cfg_fn!(structural_match))), - - // RFC #2008 - (sym::non_exhaustive, Whitelisted, template!(Word), Gated(Stability::Unstable, - sym::non_exhaustive, - "non exhaustive is an experimental feature", - cfg_fn!(non_exhaustive))), - - // RFC #1268 - (sym::marker, Normal, template!(Word), Gated(Stability::Unstable, - sym::marker_trait_attr, - "marker traits is an experimental feature", - cfg_fn!(marker_trait_attr))), - - (sym::plugin, CrateLevel, template!(List: "name|name(args)"), Gated(Stability::Unstable, - sym::plugin, - "compiler plugins are experimental \ - and possibly buggy", - cfg_fn!(plugin))), - - (sym::no_std, CrateLevel, template!(Word), Ungated), - (sym::no_core, CrateLevel, template!(Word), Gated(Stability::Unstable, - sym::no_core, - "no_core is experimental", - cfg_fn!(no_core))), - (sym::lang, Normal, template!(NameValueStr: "name"), Gated(Stability::Unstable, - sym::lang_items, - "language items are subject to change", - cfg_fn!(lang_items))), - (sym::linkage, Whitelisted, template!(NameValueStr: "external|internal|..."), - Gated(Stability::Unstable, - sym::linkage, - "the `linkage` attribute is experimental \ - and not portable across platforms", - cfg_fn!(linkage))), - (sym::thread_local, Whitelisted, template!(Word), Gated(Stability::Unstable, - sym::thread_local, - "`#[thread_local]` is an experimental feature, and does \ - not currently handle destructors", - cfg_fn!(thread_local))), - - (sym::rustc_on_unimplemented, Whitelisted, template!(List: - r#"/*opt*/ message = "...", /*opt*/ label = "...", /*opt*/ note = "...""#, - NameValueStr: "message"), - Gated(Stability::Unstable, - sym::on_unimplemented, - "the `#[rustc_on_unimplemented]` attribute \ - is an experimental feature", - cfg_fn!(on_unimplemented))), - (sym::rustc_const_unstable, Normal, template!(List: r#"feature = "name""#), - Gated(Stability::Unstable, - sym::rustc_const_unstable, - "the `#[rustc_const_unstable]` attribute \ - is an internal feature", - cfg_fn!(rustc_const_unstable))), - (sym::default_lib_allocator, Whitelisted, template!(Word), Gated(Stability::Unstable, - sym::allocator_internals, - "the `#[default_lib_allocator]` \ - attribute is an experimental feature", - cfg_fn!(allocator_internals))), - (sym::needs_allocator, Normal, template!(Word), Gated(Stability::Unstable, - sym::allocator_internals, - "the `#[needs_allocator]` \ - attribute is an experimental \ - feature", - cfg_fn!(allocator_internals))), - (sym::panic_runtime, Whitelisted, template!(Word), Gated(Stability::Unstable, - sym::panic_runtime, - "the `#[panic_runtime]` attribute is \ - an experimental feature", - cfg_fn!(panic_runtime))), - (sym::needs_panic_runtime, Whitelisted, template!(Word), Gated(Stability::Unstable, - sym::needs_panic_runtime, - "the `#[needs_panic_runtime]` \ - attribute is an experimental \ - feature", - cfg_fn!(needs_panic_runtime))), - (sym::rustc_outlives, Normal, template!(Word), Gated(Stability::Unstable, - sym::rustc_attrs, - "the `#[rustc_outlives]` attribute \ - is just used for rustc unit tests \ - and will never be stable", - cfg_fn!(rustc_attrs))), - (sym::rustc_variance, Normal, template!(Word), Gated(Stability::Unstable, - sym::rustc_attrs, - "the `#[rustc_variance]` attribute \ - is just used for rustc unit tests \ - and will never be stable", - cfg_fn!(rustc_attrs))), - (sym::rustc_layout, Normal, template!(List: "field1, field2, ..."), - Gated(Stability::Unstable, - sym::rustc_attrs, - "the `#[rustc_layout]` attribute \ - is just used for rustc unit tests \ - and will never be stable", - cfg_fn!(rustc_attrs))), - (sym::rustc_layout_scalar_valid_range_start, Whitelisted, template!(List: "value"), - Gated(Stability::Unstable, - sym::rustc_attrs, - "the `#[rustc_layout_scalar_valid_range_start]` attribute \ - is just used to enable niche optimizations in libcore \ - and will never be stable", - cfg_fn!(rustc_attrs))), - (sym::rustc_layout_scalar_valid_range_end, Whitelisted, template!(List: "value"), - Gated(Stability::Unstable, - sym::rustc_attrs, - "the `#[rustc_layout_scalar_valid_range_end]` attribute \ - is just used to enable niche optimizations in libcore \ - and will never be stable", - cfg_fn!(rustc_attrs))), - (sym::rustc_nonnull_optimization_guaranteed, Whitelisted, template!(Word), - Gated(Stability::Unstable, - sym::rustc_attrs, - "the `#[rustc_nonnull_optimization_guaranteed]` attribute \ - is just used to enable niche optimizations in libcore \ - and will never be stable", - cfg_fn!(rustc_attrs))), - (sym::rustc_regions, Normal, template!(Word), Gated(Stability::Unstable, - sym::rustc_attrs, - "the `#[rustc_regions]` attribute \ - is just used for rustc unit tests \ - and will never be stable", - cfg_fn!(rustc_attrs))), - (sym::rustc_error, Whitelisted, template!(Word), Gated(Stability::Unstable, - sym::rustc_attrs, - "the `#[rustc_error]` attribute \ - is just used for rustc unit tests \ - and will never be stable", - cfg_fn!(rustc_attrs))), - (sym::rustc_dump_user_substs, Whitelisted, template!(Word), Gated(Stability::Unstable, - sym::rustc_attrs, - "this attribute \ - is just used for rustc unit tests \ - and will never be stable", - cfg_fn!(rustc_attrs))), - (sym::rustc_if_this_changed, Whitelisted, template!(Word, List: "DepNode"), - Gated(Stability::Unstable, - sym::rustc_attrs, - "the `#[rustc_if_this_changed]` attribute \ - is just used for rustc unit tests \ - and will never be stable", - cfg_fn!(rustc_attrs))), - (sym::rustc_then_this_would_need, Whitelisted, template!(List: "DepNode"), - Gated(Stability::Unstable, - sym::rustc_attrs, - "the `#[rustc_if_this_changed]` attribute \ - is just used for rustc unit tests \ - and will never be stable", - cfg_fn!(rustc_attrs))), - (sym::rustc_dirty, Whitelisted, template!(List: r#"cfg = "...", /*opt*/ label = "...", - /*opt*/ except = "...""#), - Gated(Stability::Unstable, - sym::rustc_attrs, - "the `#[rustc_dirty]` attribute \ - is just used for rustc unit tests \ - and will never be stable", - cfg_fn!(rustc_attrs))), - (sym::rustc_clean, Whitelisted, template!(List: r#"cfg = "...", /*opt*/ label = "...", - /*opt*/ except = "...""#), - Gated(Stability::Unstable, - sym::rustc_attrs, - "the `#[rustc_clean]` attribute \ - is just used for rustc unit tests \ - and will never be stable", - cfg_fn!(rustc_attrs))), - ( - sym::rustc_partition_reused, - Whitelisted, - template!(List: r#"cfg = "...", module = "...""#), - Gated( - Stability::Unstable, - sym::rustc_attrs, - "this attribute \ - is just used for rustc unit tests \ - and will never be stable", - cfg_fn!(rustc_attrs) - ) - ), - ( - sym::rustc_partition_codegened, - Whitelisted, - template!(List: r#"cfg = "...", module = "...""#), - Gated( - Stability::Unstable, - sym::rustc_attrs, - "this attribute \ - is just used for rustc unit tests \ - and will never be stable", - cfg_fn!(rustc_attrs), - ) - ), - (sym::rustc_expected_cgu_reuse, Whitelisted, template!(List: r#"cfg = "...", module = "...", - kind = "...""#), - Gated(Stability::Unstable, - sym::rustc_attrs, - "this attribute \ - is just used for rustc unit tests \ - and will never be stable", - cfg_fn!(rustc_attrs))), - (sym::rustc_synthetic, Whitelisted, template!(Word), Gated(Stability::Unstable, - sym::rustc_attrs, - "this attribute \ - is just used for rustc unit tests \ - and will never be stable", - cfg_fn!(rustc_attrs))), - (sym::rustc_symbol_name, Whitelisted, template!(Word), Gated(Stability::Unstable, - sym::rustc_attrs, - "internal rustc attributes will never be stable", - cfg_fn!(rustc_attrs))), - (sym::rustc_def_path, Whitelisted, template!(Word), Gated(Stability::Unstable, - sym::rustc_attrs, - "internal rustc attributes will never be stable", - cfg_fn!(rustc_attrs))), - (sym::rustc_mir, Whitelisted, template!(List: "arg1, arg2, ..."), Gated(Stability::Unstable, - sym::rustc_attrs, - "the `#[rustc_mir]` attribute \ - is just used for rustc unit tests \ - and will never be stable", - cfg_fn!(rustc_attrs))), - ( - sym::rustc_inherit_overflow_checks, - Whitelisted, - template!(Word), - Gated( - Stability::Unstable, - sym::rustc_attrs, - "the `#[rustc_inherit_overflow_checks]` \ - attribute is just used to control \ - overflow checking behavior of several \ - libcore functions that are inlined \ - across crates and will never be stable", - cfg_fn!(rustc_attrs), - ) - ), - - (sym::rustc_dump_program_clauses, Whitelisted, template!(Word), Gated(Stability::Unstable, - sym::rustc_attrs, - "the `#[rustc_dump_program_clauses]` \ - attribute is just used for rustc unit \ - tests and will never be stable", - cfg_fn!(rustc_attrs))), - (sym::rustc_dump_env_program_clauses, Whitelisted, template!(Word), Gated(Stability::Unstable, - sym::rustc_attrs, - "the `#[rustc_dump_env_program_clauses]` \ - attribute is just used for rustc unit \ - tests and will never be stable", - cfg_fn!(rustc_attrs))), - (sym::rustc_object_lifetime_default, Whitelisted, template!(Word), Gated(Stability::Unstable, - sym::rustc_attrs, - "the `#[rustc_object_lifetime_default]` \ - attribute is just used for rustc unit \ - tests and will never be stable", - cfg_fn!(rustc_attrs))), - (sym::rustc_test_marker, Normal, template!(Word), Gated(Stability::Unstable, - sym::rustc_attrs, - "the `#[rustc_test_marker]` attribute \ - is used internally to track tests", - cfg_fn!(rustc_attrs))), - (sym::rustc_macro_transparency, Whitelisted, template!(NameValueStr: - "transparent|semitransparent|opaque"), - Gated(Stability::Unstable, - sym::rustc_attrs, - "used internally for testing macro hygiene", - cfg_fn!(rustc_attrs))), - (sym::compiler_builtins, Whitelisted, template!(Word), Gated(Stability::Unstable, - sym::compiler_builtins, - "the `#[compiler_builtins]` attribute is used to \ - identify the `compiler_builtins` crate which \ - contains compiler-rt intrinsics and will never be \ - stable", - cfg_fn!(compiler_builtins))), - (sym::sanitizer_runtime, Whitelisted, template!(Word), Gated(Stability::Unstable, - sym::sanitizer_runtime, - "the `#[sanitizer_runtime]` attribute is used to \ - identify crates that contain the runtime of a \ - sanitizer and will never be stable", - cfg_fn!(sanitizer_runtime))), - (sym::profiler_runtime, Whitelisted, template!(Word), Gated(Stability::Unstable, - sym::profiler_runtime, - "the `#[profiler_runtime]` attribute is used to \ - identify the `profiler_builtins` crate which \ - contains the profiler runtime and will never be \ - stable", - cfg_fn!(profiler_runtime))), - - (sym::allow_internal_unstable, Normal, template!(Word, List: "feat1, feat2, ..."), - Gated(Stability::Unstable, - sym::allow_internal_unstable, - EXPLAIN_ALLOW_INTERNAL_UNSTABLE, - cfg_fn!(allow_internal_unstable))), - - (sym::allow_internal_unsafe, Normal, template!(Word), Gated(Stability::Unstable, - sym::allow_internal_unsafe, - EXPLAIN_ALLOW_INTERNAL_UNSAFE, - cfg_fn!(allow_internal_unsafe))), - - (sym::fundamental, Whitelisted, template!(Word), Gated(Stability::Unstable, - sym::fundamental, - "the `#[fundamental]` attribute \ - is an experimental feature", - cfg_fn!(fundamental))), - - (sym::proc_macro_derive, Normal, template!(List: "TraitName, \ - /*opt*/ attributes(name1, name2, ...)"), - Ungated), - - (sym::rustc_allocator, Whitelisted, template!(Word), Gated(Stability::Unstable, - sym::rustc_attrs, - "internal implementation detail", - cfg_fn!(rustc_attrs))), - - (sym::rustc_allocator_nounwind, Whitelisted, template!(Word), Gated(Stability::Unstable, - sym::rustc_attrs, - "internal implementation detail", - cfg_fn!(rustc_attrs))), - - (sym::rustc_builtin_macro, Whitelisted, template!(Word), Gated(Stability::Unstable, - sym::rustc_attrs, - "internal implementation detail", - cfg_fn!(rustc_attrs))), - - (sym::rustc_promotable, Whitelisted, template!(Word), Gated(Stability::Unstable, - sym::rustc_attrs, - "internal implementation detail", - cfg_fn!(rustc_attrs))), - - (sym::rustc_allow_const_fn_ptr, Whitelisted, template!(Word), Gated(Stability::Unstable, - sym::rustc_attrs, - "internal implementation detail", - cfg_fn!(rustc_attrs))), - - (sym::rustc_dummy, Normal, template!(Word /* doesn't matter*/), Gated(Stability::Unstable, - sym::rustc_attrs, - "used by the test suite", - cfg_fn!(rustc_attrs))), - - // FIXME: #14408 whitelist docs since rustdoc looks at them - ( - sym::doc, - Whitelisted, - template!(List: "hidden|inline|...", NameValueStr: "string"), - Ungated - ), - - // FIXME: #14406 these are processed in codegen, which happens after the - // lint pass - (sym::cold, Whitelisted, template!(Word), Ungated), - (sym::naked, Whitelisted, template!(Word), Gated(Stability::Unstable, - sym::naked_functions, - "the `#[naked]` attribute \ - is an experimental feature", - cfg_fn!(naked_functions))), - (sym::ffi_returns_twice, Whitelisted, template!(Word), Gated(Stability::Unstable, - sym::ffi_returns_twice, - "the `#[ffi_returns_twice]` attribute \ - is an experimental feature", - cfg_fn!(ffi_returns_twice))), - (sym::target_feature, Whitelisted, template!(List: r#"enable = "name""#), Ungated), - (sym::export_name, Whitelisted, template!(NameValueStr: "name"), Ungated), - (sym::inline, Whitelisted, template!(Word, List: "always|never"), Ungated), - (sym::link, Whitelisted, template!(List: r#"name = "...", /*opt*/ kind = "dylib|static|...", - /*opt*/ cfg = "...""#), Ungated), - (sym::link_name, Whitelisted, template!(NameValueStr: "name"), Ungated), - (sym::link_section, Whitelisted, template!(NameValueStr: "name"), Ungated), - (sym::no_builtins, Whitelisted, template!(Word), Ungated), - (sym::no_debug, Whitelisted, template!(Word), Gated( - Stability::Deprecated("https://github.com/rust-lang/rust/issues/29721", None), - sym::no_debug, - "the `#[no_debug]` attribute was an experimental feature that has been \ - deprecated due to lack of demand", - cfg_fn!(no_debug))), - ( - sym::omit_gdb_pretty_printer_section, - Whitelisted, - template!(Word), - Gated( - Stability::Unstable, - sym::omit_gdb_pretty_printer_section, - "the `#[omit_gdb_pretty_printer_section]` \ - attribute is just used for the Rust test \ - suite", - cfg_fn!(omit_gdb_pretty_printer_section) - ) - ), - (sym::may_dangle, - Normal, - template!(Word), - Gated(Stability::Unstable, - sym::dropck_eyepatch, - "`may_dangle` has unstable semantics and may be removed in the future", - cfg_fn!(dropck_eyepatch))), - (sym::unwind, Whitelisted, template!(List: "allowed|aborts"), Gated(Stability::Unstable, - sym::unwind_attributes, - "`#[unwind]` is experimental", - cfg_fn!(unwind_attributes))), - (sym::used, Whitelisted, template!(Word), Ungated), - - // used in resolve - (sym::prelude_import, Whitelisted, template!(Word), Gated(Stability::Unstable, - sym::prelude_import, - "`#[prelude_import]` is for use by rustc only", - cfg_fn!(prelude_import))), - - // FIXME: #14407 these are only looked at on-demand so we can't - // guarantee they'll have already been checked - ( - sym::rustc_deprecated, - Whitelisted, - template!(List: r#"since = "version", reason = "...""#), - Ungated - ), - (sym::must_use, Whitelisted, template!(Word, NameValueStr: "reason"), Ungated), - ( - sym::stable, - Whitelisted, - template!(List: r#"feature = "name", since = "version""#), - Ungated - ), - ( - sym::unstable, - Whitelisted, - template!(List: r#"feature = "name", reason = "...", issue = "N""#), - Ungated - ), - (sym::deprecated, - Normal, - template!( - Word, - List: r#"/*opt*/ since = "version", /*opt*/ note = "reason""#, - NameValueStr: "reason" - ), - Ungated - ), - - (sym::rustc_paren_sugar, Normal, template!(Word), Gated(Stability::Unstable, - sym::unboxed_closures, - "unboxed_closures are still evolving", - cfg_fn!(unboxed_closures))), - - (sym::windows_subsystem, Whitelisted, template!(NameValueStr: "windows|console"), Ungated), - - (sym::proc_macro_attribute, Normal, template!(Word), Ungated), - (sym::proc_macro, Normal, template!(Word), Ungated), - - (sym::rustc_proc_macro_decls, Normal, template!(Word), Gated(Stability::Unstable, - sym::rustc_attrs, - "used internally by rustc", - cfg_fn!(rustc_attrs))), - - (sym::allow_fail, Normal, template!(Word), Gated(Stability::Unstable, - sym::allow_fail, - "allow_fail attribute is currently unstable", - cfg_fn!(allow_fail))), - - (sym::rustc_std_internal_symbol, Whitelisted, template!(Word), Gated(Stability::Unstable, - sym::rustc_attrs, - "this is an internal attribute that will \ - never be stable", - cfg_fn!(rustc_attrs))), - - // whitelists "identity-like" conversion methods to suggest on type mismatch - (sym::rustc_conversion_suggestion, Whitelisted, template!(Word), Gated(Stability::Unstable, - sym::rustc_attrs, - "this is an internal attribute that will \ - never be stable", - cfg_fn!(rustc_attrs))), - - ( - sym::rustc_args_required_const, - Whitelisted, - template!(List: "N"), - Gated(Stability::Unstable, sym::rustc_attrs, "never will be stable", - cfg_fn!(rustc_attrs)) - ), - // RFC 2070 - (sym::panic_handler, Normal, template!(Word), Ungated), - - (sym::alloc_error_handler, Normal, template!(Word), Gated(Stability::Unstable, - sym::alloc_error_handler, - "`#[alloc_error_handler]` is an unstable feature", - cfg_fn!(alloc_error_handler))), - - // RFC 2412 - (sym::optimize, Whitelisted, template!(List: "size|speed"), Gated(Stability::Unstable, - sym::optimize_attribute, - "`#[optimize]` attribute is an unstable feature", - cfg_fn!(optimize_attribute))), - - // Crate level attributes - (sym::crate_name, CrateLevel, template!(NameValueStr: "name"), Ungated), - (sym::crate_type, CrateLevel, template!(NameValueStr: "bin|lib|..."), Ungated), - (sym::crate_id, CrateLevel, template!(NameValueStr: "ignored"), Ungated), - (sym::feature, CrateLevel, template!(List: "name1, name1, ..."), Ungated), - (sym::no_start, CrateLevel, template!(Word), Ungated), - (sym::no_main, CrateLevel, template!(Word), Ungated), - (sym::recursion_limit, CrateLevel, template!(NameValueStr: "N"), Ungated), - (sym::type_length_limit, CrateLevel, template!(NameValueStr: "N"), Ungated), - (sym::test_runner, CrateLevel, template!(List: "path"), Gated(Stability::Unstable, - sym::custom_test_frameworks, - "custom test frameworks are an unstable feature", - cfg_fn!(custom_test_frameworks))), -]; - -pub type BuiltinAttribute = (Symbol, AttributeType, AttributeTemplate, AttributeGate); - -lazy_static! { - pub static ref BUILTIN_ATTRIBUTE_MAP: FxHashMap<Symbol, &'static BuiltinAttribute> = { - let mut map = FxHashMap::default(); - for attr in BUILTIN_ATTRIBUTES.iter() { - if map.insert(attr.0, attr).is_some() { - panic!("duplicate builtin attribute `{}`", attr.0); - } - } - map - }; -} - -// cfg(...)'s that are feature gated -const GATED_CFGS: &[(Symbol, Symbol, fn(&Features) -> bool)] = &[ - // (name in cfg, feature, function to check if the feature is enabled) - (sym::target_thread_local, sym::cfg_target_thread_local, cfg_fn!(cfg_target_thread_local)), - (sym::target_has_atomic, sym::cfg_target_has_atomic, cfg_fn!(cfg_target_has_atomic)), - (sym::rustdoc, sym::doc_cfg, cfg_fn!(doc_cfg)), - (sym::doctest, sym::cfg_doctest, cfg_fn!(cfg_doctest)), -]; - -#[derive(Debug)] -pub struct GatedCfg { - span: Span, - index: usize, -} - -impl GatedCfg { - pub fn gate(cfg: &ast::MetaItem) -> Option<GatedCfg> { - GATED_CFGS.iter() - .position(|info| cfg.check_name(info.0)) - .map(|idx| { - GatedCfg { - span: cfg.span, - index: idx - } - }) - } - - pub fn check_and_emit(&self, sess: &ParseSess, features: &Features) { - let (cfg, feature, has_feature) = GATED_CFGS[self.index]; - if !has_feature(features) && !self.span.allows_unstable(feature) { - let explain = format!("`cfg({})` is experimental and subject to change", cfg); - emit_feature_err(sess, feature, self.span, GateIssue::Language, &explain); - } - } -} - -struct Context<'a> { - features: &'a Features, - parse_sess: &'a ParseSess, - plugin_attributes: &'a [(Symbol, AttributeType)], -} - -macro_rules! gate_feature_fn { - ($cx: expr, $has_feature: expr, $span: expr, $name: expr, $explain: expr, $level: expr) => {{ - let (cx, has_feature, span, - name, explain, level) = ($cx, $has_feature, $span, $name, $explain, $level); - let has_feature: bool = has_feature(&$cx.features); - debug!("gate_feature(feature = {:?}, span = {:?}); has? {}", name, span, has_feature); - if !has_feature && !span.allows_unstable($name) { - leveled_feature_err(cx.parse_sess, name, span, GateIssue::Language, explain, level) - .emit(); - } - }} -} - -macro_rules! gate_feature { - ($cx: expr, $feature: ident, $span: expr, $explain: expr) => { - gate_feature_fn!($cx, |x:&Features| x.$feature, $span, - sym::$feature, $explain, GateStrength::Hard) - }; - ($cx: expr, $feature: ident, $span: expr, $explain: expr, $level: expr) => { - gate_feature_fn!($cx, |x:&Features| x.$feature, $span, - sym::$feature, $explain, $level) - }; -} - -impl<'a> Context<'a> { - fn check_attribute( - &self, - attr: &ast::Attribute, - attr_info: Option<&BuiltinAttribute>, - is_macro: bool - ) { - debug!("check_attribute(attr = {:?})", attr); - if let Some(&(name, ty, _template, ref gateage)) = attr_info { - if let Gated(_, name, desc, ref has_feature) = *gateage { - if !attr.span.allows_unstable(name) { - gate_feature_fn!( - self, has_feature, attr.span, name, desc, GateStrength::Hard - ); - } - } else if name == sym::doc { - if let Some(content) = attr.meta_item_list() { - if content.iter().any(|c| c.check_name(sym::include)) { - gate_feature!(self, external_doc, attr.span, - "`#[doc(include = \"...\")]` is experimental" - ); - } - } - } - debug!("check_attribute: {:?} is builtin, {:?}, {:?}", attr.path, ty, gateage); - return; - } else { - for segment in &attr.path.segments { - if segment.ident.as_str().starts_with("rustc") { - let msg = "attributes starting with `rustc` are \ - reserved for use by the `rustc` compiler"; - gate_feature!(self, rustc_attrs, segment.ident.span, msg); - } - } - } - for &(n, ty) in self.plugin_attributes { - if attr.path == n { - // Plugins can't gate attributes, so we don't check for it - // unlike the code above; we only use this loop to - // short-circuit to avoid the checks below. - debug!("check_attribute: {:?} is registered by a plugin, {:?}", attr.path, ty); - return; - } - } - if !is_macro && !attr::is_known(attr) { - // Only run the custom attribute lint during regular feature gate - // checking. Macro gating runs before the plugin attributes are - // registered, so we skip this in that case. - let msg = format!("the attribute `{}` is currently unknown to the compiler and \ - may have meaning added to it in the future", attr.path); - gate_feature!(self, custom_attribute, attr.span, &msg); - } - } -} - -pub fn check_attribute(attr: &ast::Attribute, parse_sess: &ParseSess, features: &Features) { - let cx = Context { features, parse_sess, plugin_attributes: &[] }; - cx.check_attribute( - attr, - attr.ident().and_then(|ident| BUILTIN_ATTRIBUTE_MAP.get(&ident.name).map(|a| *a)), - true - ); -} - -fn find_lang_feature_issue(feature: Symbol) -> Option<u32> { - if let Some(info) = ACTIVE_FEATURES.iter().find(|t| t.0 == feature) { - let issue = info.2; - // FIXME (#28244): enforce that active features have issue numbers - // assert!(issue.is_some()) - issue - } else { - // search in Accepted, Removed, or Stable Removed features - let found = ACCEPTED_FEATURES.iter().chain(REMOVED_FEATURES).chain(STABLE_REMOVED_FEATURES) - .find(|t| t.0 == feature); - match found { - Some(&(_, _, issue, _)) => issue, - None => panic!("Feature `{}` is not declared anywhere", feature), - } - } -} - -pub enum GateIssue { - Language, - Library(Option<u32>) -} - -#[derive(Debug, Copy, Clone, PartialEq)] -pub enum GateStrength { - /// A hard error. (Most feature gates should use this.) - Hard, - /// Only a warning. (Use this only as backwards-compatibility demands.) - Soft, -} - -pub fn emit_feature_err( - sess: &ParseSess, - feature: Symbol, - span: Span, - issue: GateIssue, - explain: &str, -) { - feature_err(sess, feature, span, issue, explain).emit(); -} - -pub fn feature_err<'a, S: Into<MultiSpan>>( - sess: &'a ParseSess, - feature: Symbol, - span: S, - issue: GateIssue, - explain: &str, -) -> DiagnosticBuilder<'a> { - leveled_feature_err(sess, feature, span, issue, explain, GateStrength::Hard) -} - -fn leveled_feature_err<'a, S: Into<MultiSpan>>( - sess: &'a ParseSess, - feature: Symbol, - span: S, - issue: GateIssue, - explain: &str, - level: GateStrength, -) -> DiagnosticBuilder<'a> { - let diag = &sess.span_diagnostic; - - let issue = match issue { - GateIssue::Language => find_lang_feature_issue(feature), - GateIssue::Library(lib) => lib, - }; - - let mut err = match level { - GateStrength::Hard => { - diag.struct_span_err_with_code(span, explain, stringify_error_code!(E0658)) - } - GateStrength::Soft => diag.struct_span_warn(span, explain), - }; - - match issue { - None | Some(0) => {} // We still accept `0` as a stand-in for backwards compatibility - Some(n) => { - err.note(&format!( - "for more information, see https://github.com/rust-lang/rust/issues/{}", - n, - )); - } - } - - // #23973: do not suggest `#![feature(...)]` if we are in beta/stable - if sess.unstable_features.is_nightly_build() { - err.help(&format!("add `#![feature({})]` to the crate attributes to enable", feature)); - } - - // If we're on stable and only emitting a "soft" warning, add a note to - // clarify that the feature isn't "on" (rather than being on but - // warning-worthy). - if !sess.unstable_features.is_nightly_build() && level == GateStrength::Soft { - err.help("a nightly build of the compiler is required to enable this feature"); - } - - err - -} - -const EXPLAIN_BOX_SYNTAX: &str = - "box expression syntax is experimental; you can call `Box::new` instead"; - -pub const EXPLAIN_STMT_ATTR_SYNTAX: &str = - "attributes on expressions are experimental"; - -pub const EXPLAIN_ALLOW_INTERNAL_UNSTABLE: &str = - "allow_internal_unstable side-steps feature gating and stability checks"; -pub const EXPLAIN_ALLOW_INTERNAL_UNSAFE: &str = - "allow_internal_unsafe side-steps the unsafe_code lint"; - -pub const EXPLAIN_UNSIZED_TUPLE_COERCION: &str = - "unsized tuple coercion is not stable enough for use and is subject to change"; - -struct PostExpansionVisitor<'a> { - context: &'a Context<'a>, - builtin_attributes: &'static FxHashMap<Symbol, &'static BuiltinAttribute>, -} - -macro_rules! gate_feature_post { - ($cx: expr, $feature: ident, $span: expr, $explain: expr) => {{ - let (cx, span) = ($cx, $span); - if !span.allows_unstable(sym::$feature) { - gate_feature!(cx.context, $feature, span, $explain) - } - }}; - ($cx: expr, $feature: ident, $span: expr, $explain: expr, $level: expr) => {{ - let (cx, span) = ($cx, $span); - if !span.allows_unstable(sym::$feature) { - gate_feature!(cx.context, $feature, span, $explain, $level) - } - }} -} - -impl<'a> PostExpansionVisitor<'a> { - fn check_abi(&self, abi: Abi, span: Span) { - match abi { - Abi::RustIntrinsic => { - gate_feature_post!(&self, intrinsics, span, - "intrinsics are subject to change"); - }, - Abi::PlatformIntrinsic => { - gate_feature_post!(&self, platform_intrinsics, span, - "platform intrinsics are experimental and possibly buggy"); - }, - Abi::Vectorcall => { - gate_feature_post!(&self, abi_vectorcall, span, - "vectorcall is experimental and subject to change"); - }, - Abi::Thiscall => { - gate_feature_post!(&self, abi_thiscall, span, - "thiscall is experimental and subject to change"); - }, - Abi::RustCall => { - gate_feature_post!(&self, unboxed_closures, span, - "rust-call ABI is subject to change"); - }, - Abi::PtxKernel => { - gate_feature_post!(&self, abi_ptx, span, - "PTX ABIs are experimental and subject to change"); - }, - Abi::Unadjusted => { - gate_feature_post!(&self, abi_unadjusted, span, - "unadjusted ABI is an implementation detail and perma-unstable"); - }, - Abi::Msp430Interrupt => { - gate_feature_post!(&self, abi_msp430_interrupt, span, - "msp430-interrupt ABI is experimental and subject to change"); - }, - Abi::X86Interrupt => { - gate_feature_post!(&self, abi_x86_interrupt, span, - "x86-interrupt ABI is experimental and subject to change"); - }, - Abi::AmdGpuKernel => { - gate_feature_post!(&self, abi_amdgpu_kernel, span, - "amdgpu-kernel ABI is experimental and subject to change"); - }, - // Stable - Abi::Cdecl | - Abi::Stdcall | - Abi::Fastcall | - Abi::Aapcs | - Abi::Win64 | - Abi::SysV64 | - Abi::Rust | - Abi::C | - Abi::System => {} - } - } -} - -impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { - fn visit_attribute(&mut self, attr: &ast::Attribute) { - let attr_info = attr.ident().and_then(|ident| { - self.builtin_attributes.get(&ident.name).map(|a| *a) - }); - - // Check for gated attributes. - self.context.check_attribute(attr, attr_info, false); - - if attr.check_name(sym::doc) { - if let Some(content) = attr.meta_item_list() { - if content.len() == 1 && content[0].check_name(sym::cfg) { - gate_feature_post!(&self, doc_cfg, attr.span, - "`#[doc(cfg(...))]` is experimental" - ); - } else if content.iter().any(|c| c.check_name(sym::masked)) { - gate_feature_post!(&self, doc_masked, attr.span, - "`#[doc(masked)]` is experimental" - ); - } else if content.iter().any(|c| c.check_name(sym::spotlight)) { - gate_feature_post!(&self, doc_spotlight, attr.span, - "`#[doc(spotlight)]` is experimental" - ); - } else if content.iter().any(|c| c.check_name(sym::alias)) { - gate_feature_post!(&self, doc_alias, attr.span, - "`#[doc(alias = \"...\")]` is experimental" - ); - } else if content.iter().any(|c| c.check_name(sym::keyword)) { - gate_feature_post!(&self, doc_keyword, attr.span, - "`#[doc(keyword = \"...\")]` is experimental" - ); - } - } - } - - match attr_info { - // `rustc_dummy` doesn't have any restrictions specific to built-in attributes. - Some(&(name, _, template, _)) if name != sym::rustc_dummy => - check_builtin_attribute(self.context.parse_sess, attr, name, template), - _ => if let Some(TokenTree::Token(token)) = attr.tokens.trees().next() { - if token == token::Eq { - // All key-value attributes are restricted to meta-item syntax. - attr.parse_meta(self.context.parse_sess).map_err(|mut err| err.emit()).ok(); - } - } - } - } - - fn visit_name(&mut self, sp: Span, name: ast::Name) { - if !name.as_str().is_ascii() { - gate_feature_post!( - &self, - non_ascii_idents, - self.context.parse_sess.source_map().def_span(sp), - "non-ascii idents are not fully supported" - ); - } - } - - fn visit_item(&mut self, i: &'a ast::Item) { - match i.node { - ast::ItemKind::ForeignMod(ref foreign_module) => { - self.check_abi(foreign_module.abi, i.span); - } - - ast::ItemKind::Fn(..) => { - if attr::contains_name(&i.attrs[..], sym::plugin_registrar) { - gate_feature_post!(&self, plugin_registrar, i.span, - "compiler plugins are experimental and possibly buggy"); - } - if attr::contains_name(&i.attrs[..], sym::start) { - gate_feature_post!(&self, start, i.span, - "a `#[start]` function is an experimental \ - feature whose signature may change \ - over time"); - } - if attr::contains_name(&i.attrs[..], sym::main) { - gate_feature_post!(&self, main, i.span, - "declaration of a non-standard `#[main]` \ - function may change over time, for now \ - a top-level `fn main()` is required"); - } - } - - ast::ItemKind::Struct(..) => { - for attr in attr::filter_by_name(&i.attrs[..], sym::repr) { - for item in attr.meta_item_list().unwrap_or_else(Vec::new) { - if item.check_name(sym::simd) { - gate_feature_post!(&self, repr_simd, attr.span, - "SIMD types are experimental and possibly buggy"); - } - } - } - } - - ast::ItemKind::Enum(ast::EnumDef{ref variants, ..}, ..) => { - for variant in variants { - match (&variant.data, &variant.disr_expr) { - (ast::VariantData::Unit(..), _) => {}, - (_, Some(disr_expr)) => - gate_feature_post!( - &self, - arbitrary_enum_discriminant, - disr_expr.value.span, - "discriminants on non-unit variants are experimental"), - _ => {}, - } - } - - let has_feature = self.context.features.arbitrary_enum_discriminant; - if !has_feature && !i.span.allows_unstable(sym::arbitrary_enum_discriminant) { - Parser::maybe_report_invalid_custom_discriminants( - self.context.parse_sess, - &variants, - ); - } - } - - ast::ItemKind::Impl(_, polarity, defaultness, _, _, _, _) => { - if polarity == ast::ImplPolarity::Negative { - gate_feature_post!(&self, optin_builtin_traits, - i.span, - "negative trait bounds are not yet fully implemented; \ - use marker types for now"); - } - - if let ast::Defaultness::Default = defaultness { - gate_feature_post!(&self, specialization, - i.span, - "specialization is unstable"); - } - } - - ast::ItemKind::Trait(ast::IsAuto::Yes, ..) => { - gate_feature_post!(&self, optin_builtin_traits, - i.span, - "auto traits are experimental and possibly buggy"); - } - - ast::ItemKind::TraitAlias(..) => { - gate_feature_post!( - &self, - trait_alias, - i.span, - "trait aliases are experimental" - ); - } - - ast::ItemKind::MacroDef(ast::MacroDef { legacy: false, .. }) => { - let msg = "`macro` is experimental"; - gate_feature_post!(&self, decl_macro, i.span, msg); - } - - ast::ItemKind::OpaqueTy(..) => { - gate_feature_post!( - &self, - type_alias_impl_trait, - i.span, - "`impl Trait` in type aliases is unstable" - ); - } - - _ => {} - } - - visit::walk_item(self, i); - } - - fn visit_foreign_item(&mut self, i: &'a ast::ForeignItem) { - match i.node { - ast::ForeignItemKind::Fn(..) | - ast::ForeignItemKind::Static(..) => { - let link_name = attr::first_attr_value_str_by_name(&i.attrs, sym::link_name); - let links_to_llvm = match link_name { - Some(val) => val.as_str().starts_with("llvm."), - _ => false - }; - if links_to_llvm { - gate_feature_post!(&self, link_llvm_intrinsics, i.span, - "linking to LLVM intrinsics is experimental"); - } - } - ast::ForeignItemKind::Ty => { - gate_feature_post!(&self, extern_types, i.span, - "extern types are experimental"); - } - ast::ForeignItemKind::Macro(..) => {} - } - - visit::walk_foreign_item(self, i) - } - - fn visit_ty(&mut self, ty: &'a ast::Ty) { - match ty.node { - ast::TyKind::BareFn(ref bare_fn_ty) => { - self.check_abi(bare_fn_ty.abi, ty.span); - } - ast::TyKind::Never => { - gate_feature_post!(&self, never_type, ty.span, - "The `!` type is experimental"); - } - _ => {} - } - visit::walk_ty(self, ty) - } - - fn visit_fn_ret_ty(&mut self, ret_ty: &'a ast::FunctionRetTy) { - if let ast::FunctionRetTy::Ty(ref output_ty) = *ret_ty { - if let ast::TyKind::Never = output_ty.node { - // Do nothing. - } else { - self.visit_ty(output_ty) - } - } - } - - fn visit_expr(&mut self, e: &'a ast::Expr) { - match e.node { - ast::ExprKind::Box(_) => { - gate_feature_post!(&self, box_syntax, e.span, EXPLAIN_BOX_SYNTAX); - } - ast::ExprKind::Type(..) => { - // To avoid noise about type ascription in common syntax errors, only emit if it - // is the *only* error. - if self.context.parse_sess.span_diagnostic.err_count() == 0 { - gate_feature_post!(&self, type_ascription, e.span, - "type ascription is experimental"); - } - } - ast::ExprKind::TryBlock(_) => { - gate_feature_post!(&self, try_blocks, e.span, "`try` expression is experimental"); - } - ast::ExprKind::Block(_, opt_label) => { - if let Some(label) = opt_label { - gate_feature_post!(&self, label_break_value, label.ident.span, - "labels on blocks are unstable"); - } - } - ast::ExprKind::Async(..) => { - gate_feature_post!(&self, async_await, e.span, "async blocks are unstable"); - } - ast::ExprKind::Await(_) => { - gate_feature_post!(&self, async_await, e.span, "async/await is unstable"); - } - _ => {} - } - visit::walk_expr(self, e) - } - - fn visit_arm(&mut self, arm: &'a ast::Arm) { - visit::walk_arm(self, arm) - } - - fn visit_pat(&mut self, pattern: &'a ast::Pat) { - match &pattern.node { - PatKind::Slice(pats) => { - for pat in &*pats { - let span = pat.span; - let inner_pat = match &pat.node { - PatKind::Ident(.., Some(pat)) => pat, - _ => pat, - }; - if inner_pat.is_rest() { - gate_feature_post!( - &self, - slice_patterns, - span, - "subslice patterns are unstable" - ); - } - } - } - PatKind::Box(..) => { - gate_feature_post!(&self, box_patterns, - pattern.span, - "box pattern syntax is experimental"); - } - PatKind::Range(_, _, Spanned { node: RangeEnd::Excluded, .. }) => { - gate_feature_post!(&self, exclusive_range_pattern, pattern.span, - "exclusive range pattern syntax is experimental"); - } - _ => {} - } - visit::walk_pat(self, pattern) - } - - fn visit_fn(&mut self, - fn_kind: FnKind<'a>, - fn_decl: &'a ast::FnDecl, - span: Span, - _node_id: NodeId) { - if let Some(header) = fn_kind.header() { - // Check for const fn and async fn declarations. - if header.asyncness.node.is_async() { - gate_feature_post!(&self, async_await, span, "async fn is unstable"); - } - - // Stability of const fn methods are covered in - // `visit_trait_item` and `visit_impl_item` below; this is - // because default methods don't pass through this point. - self.check_abi(header.abi, span); - } - - if fn_decl.c_variadic { - gate_feature_post!(&self, c_variadic, span, "C-variadic functions are unstable"); - } - - visit::walk_fn(self, fn_kind, fn_decl, span) - } - - fn visit_generic_param(&mut self, param: &'a GenericParam) { - match param.kind { - GenericParamKind::Const { .. } => - gate_feature_post!(&self, const_generics, param.ident.span, - "const generics are unstable"), - _ => {} - } - visit::walk_generic_param(self, param) - } - - fn visit_assoc_ty_constraint(&mut self, constraint: &'a AssocTyConstraint) { - match constraint.kind { - AssocTyConstraintKind::Bound { .. } => - gate_feature_post!(&self, associated_type_bounds, constraint.span, - "associated type bounds are unstable"), - _ => {} - } - visit::walk_assoc_ty_constraint(self, constraint) - } - - fn visit_trait_item(&mut self, ti: &'a ast::TraitItem) { - match ti.node { - ast::TraitItemKind::Method(ref sig, ref block) => { - if block.is_none() { - self.check_abi(sig.header.abi, ti.span); - } - if sig.header.asyncness.node.is_async() { - gate_feature_post!(&self, async_await, ti.span, "async fn is unstable"); - } - if sig.decl.c_variadic { - gate_feature_post!(&self, c_variadic, ti.span, - "C-variadic functions are unstable"); - } - if sig.header.constness.node == ast::Constness::Const { - gate_feature_post!(&self, const_fn, ti.span, "const fn is unstable"); - } - } - ast::TraitItemKind::Type(_, ref default) => { - // We use three if statements instead of something like match guards so that all - // of these errors can be emitted if all cases apply. - if default.is_some() { - gate_feature_post!(&self, associated_type_defaults, ti.span, - "associated type defaults are unstable"); - } - if !ti.generics.params.is_empty() { - gate_feature_post!(&self, generic_associated_types, ti.span, - "generic associated types are unstable"); - } - if !ti.generics.where_clause.predicates.is_empty() { - gate_feature_post!(&self, generic_associated_types, ti.span, - "where clauses on associated types are unstable"); - } - } - _ => {} - } - visit::walk_trait_item(self, ti) - } - - fn visit_impl_item(&mut self, ii: &'a ast::ImplItem) { - if ii.defaultness == ast::Defaultness::Default { - gate_feature_post!(&self, specialization, - ii.span, - "specialization is unstable"); - } - - match ii.node { - ast::ImplItemKind::Method(..) => {} - ast::ImplItemKind::OpaqueTy(..) => { - gate_feature_post!( - &self, - type_alias_impl_trait, - ii.span, - "`impl Trait` in type aliases is unstable" - ); - } - ast::ImplItemKind::TyAlias(_) => { - if !ii.generics.params.is_empty() { - gate_feature_post!(&self, generic_associated_types, ii.span, - "generic associated types are unstable"); - } - if !ii.generics.where_clause.predicates.is_empty() { - gate_feature_post!(&self, generic_associated_types, ii.span, - "where clauses on associated types are unstable"); - } - } - _ => {} - } - visit::walk_impl_item(self, ii) - } - - fn visit_vis(&mut self, vis: &'a ast::Visibility) { - if let ast::VisibilityKind::Crate(ast::CrateSugar::JustCrate) = vis.node { - gate_feature_post!(&self, crate_visibility_modifier, vis.span, - "`crate` visibility modifier is experimental"); - } - visit::walk_vis(self, vis) - } -} - -pub fn get_features(span_handler: &Handler, krate_attrs: &[ast::Attribute], - crate_edition: Edition, allow_features: &Option<Vec<String>>) -> Features { - fn feature_removed(span_handler: &Handler, span: Span, reason: Option<&str>) { - let mut err = struct_span_err!(span_handler, span, E0557, "feature has been removed"); - if let Some(reason) = reason { - err.span_note(span, reason); - } else { - err.span_label(span, "feature has been removed"); - } - err.emit(); - } - - let mut features = Features::new(); - let mut edition_enabled_features = FxHashMap::default(); - - for &edition in ALL_EDITIONS { - if edition <= crate_edition { - // The `crate_edition` implies its respective umbrella feature-gate - // (i.e., `#![feature(rust_20XX_preview)]` isn't needed on edition 20XX). - edition_enabled_features.insert(edition.feature_name(), edition); - } - } - - for &(name, .., f_edition, set) in ACTIVE_FEATURES { - if let Some(f_edition) = f_edition { - if f_edition <= crate_edition { - set(&mut features, DUMMY_SP); - edition_enabled_features.insert(name, crate_edition); - } - } - } - - // Process the edition umbrella feature-gates first, to ensure - // `edition_enabled_features` is completed before it's queried. - for attr in krate_attrs { - if !attr.check_name(sym::feature) { - continue - } - - let list = match attr.meta_item_list() { - Some(list) => list, - None => continue, - }; - - for mi in list { - if !mi.is_word() { - continue; - } - - let name = mi.name_or_empty(); - - if let Some(edition) = ALL_EDITIONS.iter().find(|e| name == e.feature_name()) { - if *edition <= crate_edition { - continue; - } - - for &(name, .., f_edition, set) in ACTIVE_FEATURES { - if let Some(f_edition) = f_edition { - if f_edition <= *edition { - // FIXME(Manishearth) there is currently no way to set - // lib features by edition - set(&mut features, DUMMY_SP); - edition_enabled_features.insert(name, *edition); - } - } - } - } - } - } - - for attr in krate_attrs { - if !attr.check_name(sym::feature) { - continue - } - - let list = match attr.meta_item_list() { - Some(list) => list, - None => continue, - }; - - let bad_input = |span| { - struct_span_err!(span_handler, span, E0556, "malformed `feature` attribute input") - }; - - for mi in list { - let name = match mi.ident() { - Some(ident) if mi.is_word() => ident.name, - Some(ident) => { - bad_input(mi.span()).span_suggestion( - mi.span(), - "expected just one word", - format!("{}", ident.name), - Applicability::MaybeIncorrect, - ).emit(); - continue - } - None => { - bad_input(mi.span()).span_label(mi.span(), "expected just one word").emit(); - continue - } - }; - - if let Some(edition) = edition_enabled_features.get(&name) { - struct_span_warn!( - span_handler, - mi.span(), - E0705, - "the feature `{}` is included in the Rust {} edition", - name, - edition, - ).emit(); - continue; - } - - if ALL_EDITIONS.iter().any(|e| name == e.feature_name()) { - // Handled in the separate loop above. - continue; - } - - let removed = REMOVED_FEATURES.iter().find(|f| name == f.0); - let stable_removed = STABLE_REMOVED_FEATURES.iter().find(|f| name == f.0); - if let Some((.., reason)) = removed.or(stable_removed) { - feature_removed(span_handler, mi.span(), *reason); - continue; - } - - if let Some((_, since, ..)) = ACCEPTED_FEATURES.iter().find(|f| name == f.0) { - let since = Some(Symbol::intern(since)); - features.declared_lang_features.push((name, mi.span(), since)); - continue; - } - - if let Some(allowed) = allow_features.as_ref() { - if allowed.iter().find(|f| *f == name.as_str()).is_none() { - span_err!(span_handler, mi.span(), E0725, - "the feature `{}` is not in the list of allowed features", - name); - continue; - } - } - - if let Some((.., set)) = ACTIVE_FEATURES.iter().find(|f| name == f.0) { - set(&mut features, mi.span()); - features.declared_lang_features.push((name, mi.span(), None)); - continue; - } - - features.declared_lib_features.push((name, mi.span())); - } - } - - features -} - -pub fn check_crate(krate: &ast::Crate, - sess: &ParseSess, - features: &Features, - plugin_attributes: &[(Symbol, AttributeType)], - unstable: UnstableFeatures) { - maybe_stage_features(&sess.span_diagnostic, krate, unstable); - let ctx = Context { - features, - parse_sess: sess, - plugin_attributes, - }; - - macro_rules! gate_all { - ($spans:ident, $gate:ident, $msg:literal) => { - for span in &*sess.$spans.borrow() { gate_feature!(&ctx, $gate, *span, $msg); } - } - } - - gate_all!(param_attr_spans, param_attrs, "attributes on function parameters are unstable"); - gate_all!(let_chains_spans, let_chains, "`let` expressions in this position are experimental"); - gate_all!(async_closure_spans, async_closure, "async closures are unstable"); - gate_all!(yield_spans, generators, "yield syntax is experimental"); - gate_all!(or_pattern_spans, or_patterns, "or-patterns syntax is experimental"); - - let visitor = &mut PostExpansionVisitor { - context: &ctx, - builtin_attributes: &*BUILTIN_ATTRIBUTE_MAP, - }; - visit::walk_crate(visitor, krate); -} - -#[derive(Clone, Copy, Hash)] -pub enum UnstableFeatures { - /// Hard errors for unstable features are active, as on beta/stable channels. - Disallow, - /// Allow features to be activated, as on nightly. - Allow, - /// Errors are bypassed for bootstrapping. This is required any time - /// during the build that feature-related lints are set to warn or above - /// because the build turns on warnings-as-errors and uses lots of unstable - /// features. As a result, this is always required for building Rust itself. - Cheat -} - -impl UnstableFeatures { - pub fn from_environment() -> UnstableFeatures { - // Whether this is a feature-staged build, i.e., on the beta or stable channel - let disable_unstable_features = option_env!("CFG_DISABLE_UNSTABLE_FEATURES").is_some(); - // Whether we should enable unstable features for bootstrapping - let bootstrap = env::var("RUSTC_BOOTSTRAP").is_ok(); - match (disable_unstable_features, bootstrap) { - (_, true) => UnstableFeatures::Cheat, - (true, _) => UnstableFeatures::Disallow, - (false, _) => UnstableFeatures::Allow - } - } - - pub fn is_nightly_build(&self) -> bool { - match *self { - UnstableFeatures::Allow | UnstableFeatures::Cheat => true, - _ => false, - } - } -} - -fn maybe_stage_features(span_handler: &Handler, krate: &ast::Crate, - unstable: UnstableFeatures) { - let allow_features = match unstable { - UnstableFeatures::Allow => true, - UnstableFeatures::Disallow => false, - UnstableFeatures::Cheat => true - }; - if !allow_features { - for attr in &krate.attrs { - if attr.check_name(sym::feature) { - let release_channel = option_env!("CFG_RELEASE_CHANNEL").unwrap_or("(unknown)"); - span_err!(span_handler, attr.span, E0554, - "`#![feature]` may not be used on the {} release channel", - release_channel); - } - } - } -} diff --git a/src/libsyntax/feature_gate/accepted.rs b/src/libsyntax/feature_gate/accepted.rs new file mode 100644 index 00000000000..32a0b76d5f0 --- /dev/null +++ b/src/libsyntax/feature_gate/accepted.rs @@ -0,0 +1,236 @@ +//! List of the accepted feature gates. + +use crate::symbol::{Symbol, sym}; + +macro_rules! declare_features { + ($((accepted, $feature: ident, $ver: expr, $issue: expr, None),)+) => { + /// Those language feature has since been Accepted (it was once Active) + pub const ACCEPTED_FEATURES: &[(Symbol, &str, Option<u32>, Option<&str>)] = &[ + $((sym::$feature, $ver, $issue, None)),+ + ]; + } +} + +declare_features! ( + // ------------------------------------------------------------------------- + // feature-group-start: for testing purposes + // ------------------------------------------------------------------------- + + // A temporary feature gate used to enable parser extensions needed + // to bootstrap fix for #5723. + (accepted, issue_5723_bootstrap, "1.0.0", None, None), + // These are used to test this portion of the compiler, + // they don't actually mean anything. + (accepted, test_accepted_feature, "1.0.0", None, None), + + // ------------------------------------------------------------------------- + // feature-group-end: for testing purposes + // ------------------------------------------------------------------------- + + // ------------------------------------------------------------------------- + // feature-group-start: accepted features + // ------------------------------------------------------------------------- + + // Allows using associated `type`s in `trait`s. + (accepted, associated_types, "1.0.0", None, None), + // Allows using assigning a default type to type parameters in algebraic data type definitions. + (accepted, default_type_params, "1.0.0", None, None), + // FIXME: explain `globs`. + (accepted, globs, "1.0.0", None, None), + // Allows `macro_rules!` items. + (accepted, macro_rules, "1.0.0", None, None), + // Allows use of `&foo[a..b]` as a slicing syntax. + (accepted, slicing_syntax, "1.0.0", None, None), + // Allows struct variants `Foo { baz: u8, .. }` in enums (RFC 418). + (accepted, struct_variant, "1.0.0", None, None), + // Allows indexing tuples. + (accepted, tuple_indexing, "1.0.0", None, None), + // Allows the use of `if let` expressions. + (accepted, if_let, "1.0.0", None, None), + // Allows the use of `while let` expressions. + (accepted, while_let, "1.0.0", None, None), + // Allows using `#![no_std]`. + (accepted, no_std, "1.6.0", None, None), + // Allows overloading augmented assignment operations like `a += b`. + (accepted, augmented_assignments, "1.8.0", Some(28235), None), + // Allows empty structs and enum variants with braces. + (accepted, braced_empty_structs, "1.8.0", Some(29720), None), + // Allows `#[deprecated]` attribute. + (accepted, deprecated, "1.9.0", Some(29935), None), + // Allows macros to appear in the type position. + (accepted, type_macros, "1.13.0", Some(27245), None), + // Allows use of the postfix `?` operator in expressions. + (accepted, question_mark, "1.13.0", Some(31436), None), + // Allows `..` in tuple (struct) patterns. + (accepted, dotdot_in_tuple_patterns, "1.14.0", Some(33627), None), + // Allows some increased flexibility in the name resolution rules, + // especially around globs and shadowing (RFC 1560). + (accepted, item_like_imports, "1.15.0", Some(35120), None), + // Allows using `Self` and associated types in struct expressions and patterns. + (accepted, more_struct_aliases, "1.16.0", Some(37544), None), + // Allows elision of `'static` lifetimes in `static`s and `const`s. + (accepted, static_in_const, "1.17.0", Some(35897), None), + // Allows field shorthands (`x` meaning `x: x`) in struct literal expressions. + (accepted, field_init_shorthand, "1.17.0", Some(37340), None), + // Allows the definition recursive static items. + (accepted, static_recursion, "1.17.0", Some(29719), None), + // Allows `pub(restricted)` visibilities (RFC 1422). + (accepted, pub_restricted, "1.18.0", Some(32409), None), + // Allows `#![windows_subsystem]`. + (accepted, windows_subsystem, "1.18.0", Some(37499), None), + // Allows `break {expr}` with a value inside `loop`s. + (accepted, loop_break_value, "1.19.0", Some(37339), None), + // Allows numeric fields in struct expressions and patterns. + (accepted, relaxed_adts, "1.19.0", Some(35626), None), + // Allows coercing non capturing closures to function pointers. + (accepted, closure_to_fn_coercion, "1.19.0", Some(39817), None), + // Allows attributes on struct literal fields. + (accepted, struct_field_attributes, "1.20.0", Some(38814), None), + // Allows the definition of associated constants in `trait` or `impl` blocks. + (accepted, associated_consts, "1.20.0", Some(29646), None), + // Allows usage of the `compile_error!` macro. + (accepted, compile_error, "1.20.0", Some(40872), None), + // Allows code like `let x: &'static u32 = &42` to work (RFC 1414). + (accepted, rvalue_static_promotion, "1.21.0", Some(38865), None), + // Allows `Drop` types in constants (RFC 1440). + (accepted, drop_types_in_const, "1.22.0", Some(33156), None), + // Allows the sysV64 ABI to be specified on all platforms + // instead of just the platforms on which it is the C ABI. + (accepted, abi_sysv64, "1.24.0", Some(36167), None), + // Allows `repr(align(16))` struct attribute (RFC 1358). + (accepted, repr_align, "1.25.0", Some(33626), None), + // Allows '|' at beginning of match arms (RFC 1925). + (accepted, match_beginning_vert, "1.25.0", Some(44101), None), + // Allows nested groups in `use` items (RFC 2128). + (accepted, use_nested_groups, "1.25.0", Some(44494), None), + // Allows indexing into constant arrays. + (accepted, const_indexing, "1.26.0", Some(29947), None), + // Allows using `a..=b` and `..=b` as inclusive range syntaxes. + (accepted, inclusive_range_syntax, "1.26.0", Some(28237), None), + // Allows `..=` in patterns (RFC 1192). + (accepted, dotdoteq_in_patterns, "1.26.0", Some(28237), None), + // Allows `fn main()` with return types which implements `Termination` (RFC 1937). + (accepted, termination_trait, "1.26.0", Some(43301), None), + // Allows implementing `Clone` for closures where possible (RFC 2132). + (accepted, clone_closures, "1.26.0", Some(44490), None), + // Allows implementing `Copy` for closures where possible (RFC 2132). + (accepted, copy_closures, "1.26.0", Some(44490), None), + // Allows `impl Trait` in function arguments. + (accepted, universal_impl_trait, "1.26.0", Some(34511), None), + // Allows `impl Trait` in function return types. + (accepted, conservative_impl_trait, "1.26.0", Some(34511), None), + // Allows using the `u128` and `i128` types. + (accepted, i128_type, "1.26.0", Some(35118), None), + // Allows default match binding modes (RFC 2005). + (accepted, match_default_bindings, "1.26.0", Some(42640), None), + // Allows `'_` placeholder lifetimes. + (accepted, underscore_lifetimes, "1.26.0", Some(44524), None), + // Allows attributes on lifetime/type formal parameters in generics (RFC 1327). + (accepted, generic_param_attrs, "1.27.0", Some(48848), None), + // Allows `cfg(target_feature = "...")`. + (accepted, cfg_target_feature, "1.27.0", Some(29717), None), + // Allows `#[target_feature(...)]`. + (accepted, target_feature, "1.27.0", None, None), + // Allows using `dyn Trait` as a syntax for trait objects. + (accepted, dyn_trait, "1.27.0", Some(44662), None), + // Allows `#[must_use]` on functions, and introduces must-use operators (RFC 1940). + (accepted, fn_must_use, "1.27.0", Some(43302), None), + // Allows use of the `:lifetime` macro fragment specifier. + (accepted, macro_lifetime_matcher, "1.27.0", Some(34303), None), + // Allows `#[test]` functions where the return type implements `Termination` (RFC 1937). + (accepted, termination_trait_test, "1.27.0", Some(48854), None), + // Allows the `#[global_allocator]` attribute. + (accepted, global_allocator, "1.28.0", Some(27389), None), + // Allows `#[repr(transparent)]` attribute on newtype structs. + (accepted, repr_transparent, "1.28.0", Some(43036), None), + // Allows procedural macros in `proc-macro` crates. + (accepted, proc_macro, "1.29.0", Some(38356), None), + // Allows `foo.rs` as an alternative to `foo/mod.rs`. + (accepted, non_modrs_mods, "1.30.0", Some(44660), None), + // Allows use of the `:vis` macro fragment specifier + (accepted, macro_vis_matcher, "1.30.0", Some(41022), None), + // Allows importing and reexporting macros with `use`, + // enables macro modularization in general. + (accepted, use_extern_macros, "1.30.0", Some(35896), None), + // Allows keywords to be escaped for use as identifiers. + (accepted, raw_identifiers, "1.30.0", Some(48589), None), + // Allows attributes scoped to tools. + (accepted, tool_attributes, "1.30.0", Some(44690), None), + // Allows multi-segment paths in attributes and derives. + (accepted, proc_macro_path_invoc, "1.30.0", Some(38356), None), + // Allows all literals in attribute lists and values of key-value pairs. + (accepted, attr_literals, "1.30.0", Some(34981), None), + // Allows inferring outlives requirements (RFC 2093). + (accepted, infer_outlives_requirements, "1.30.0", Some(44493), None), + // Allows annotating functions conforming to `fn(&PanicInfo) -> !` with `#[panic_handler]`. + // This defines the behavior of panics. + (accepted, panic_handler, "1.30.0", Some(44489), None), + // Allows `#[used]` to preserve symbols (see llvm.used). + (accepted, used, "1.30.0", Some(40289), None), + // Allows `crate` in paths. + (accepted, crate_in_paths, "1.30.0", Some(45477), None), + // Allows resolving absolute paths as paths from other crates. + (accepted, extern_absolute_paths, "1.30.0", Some(44660), None), + // Allows access to crate names passed via `--extern` through prelude. + (accepted, extern_prelude, "1.30.0", Some(44660), None), + // Allows parentheses in patterns. + (accepted, pattern_parentheses, "1.31.0", Some(51087), None), + // Allows the definition of `const fn` functions. + (accepted, min_const_fn, "1.31.0", Some(53555), None), + // Allows scoped lints. + (accepted, tool_lints, "1.31.0", Some(44690), None), + // Allows lifetime elision in `impl` headers. For example: + // + `impl<I:Iterator> Iterator for &mut Iterator` + // + `impl Debug for Foo<'_>` + (accepted, impl_header_lifetime_elision, "1.31.0", Some(15872), None), + // Allows `extern crate foo as bar;`. This puts `bar` into extern prelude. + (accepted, extern_crate_item_prelude, "1.31.0", Some(55599), None), + // Allows use of the `:literal` macro fragment specifier (RFC 1576). + (accepted, macro_literal_matcher, "1.32.0", Some(35625), None), + // Allows use of `?` as the Kleene "at most one" operator in macros. + (accepted, macro_at_most_once_rep, "1.32.0", Some(48075), None), + // Allows `Self` struct constructor (RFC 2302). + (accepted, self_struct_ctor, "1.32.0", Some(51994), None), + // Allows `Self` in type definitions (RFC 2300). + (accepted, self_in_typedefs, "1.32.0", Some(49303), None), + // Allows `use x::y;` to search `x` in the current scope. + (accepted, uniform_paths, "1.32.0", Some(53130), None), + // Allows integer match exhaustiveness checking (RFC 2591). + (accepted, exhaustive_integer_patterns, "1.33.0", Some(50907), None), + // Allows `use path as _;` and `extern crate c as _;`. + (accepted, underscore_imports, "1.33.0", Some(48216), None), + // Allows `#[repr(packed(N))]` attribute on structs. + (accepted, repr_packed, "1.33.0", Some(33158), None), + // Allows irrefutable patterns in `if let` and `while let` statements (RFC 2086). + (accepted, irrefutable_let_patterns, "1.33.0", Some(44495), None), + // Allows calling `const unsafe fn` inside `unsafe` blocks in `const fn` functions. + (accepted, min_const_unsafe_fn, "1.33.0", Some(55607), None), + // Allows let bindings, assignments and destructuring in `const` functions and constants. + // As long as control flow is not implemented in const eval, `&&` and `||` may not be used + // at the same time as let bindings. + (accepted, const_let, "1.33.0", Some(48821), None), + // Allows `#[cfg_attr(predicate, multiple, attributes, here)]`. + (accepted, cfg_attr_multi, "1.33.0", Some(54881), None), + // Allows top level or-patterns (`p | q`) in `if let` and `while let`. + (accepted, if_while_or_patterns, "1.33.0", Some(48215), None), + // Allows `cfg(target_vendor = "...")`. + (accepted, cfg_target_vendor, "1.33.0", Some(29718), None), + // Allows `extern crate self as foo;`. + // This puts local crate root into extern prelude under name `foo`. + (accepted, extern_crate_self, "1.34.0", Some(56409), None), + // Allows arbitrary delimited token streams in non-macro attributes. + (accepted, unrestricted_attribute_tokens, "1.34.0", Some(55208), None), + // Allows paths to enum variants on type aliases including `Self`. + (accepted, type_alias_enum_variants, "1.37.0", Some(49683), None), + // Allows using `#[repr(align(X))]` on enums with equivalent semantics + // to wrapping an enum in a wrapper struct with `#[repr(align(X))]`. + (accepted, repr_align_enum, "1.37.0", Some(57996), None), + // Allows `const _: TYPE = VALUE`. + (accepted, underscore_const_names, "1.37.0", Some(54912), None), + // Allows free and inherent `async fn`s, `async` blocks, and `<expr>.await` expressions. + (accepted, async_await, "1.39.0", Some(50547), None), + + // ------------------------------------------------------------------------- + // feature-group-end: accepted features + // ------------------------------------------------------------------------- +); diff --git a/src/libsyntax/feature_gate/active.rs b/src/libsyntax/feature_gate/active.rs new file mode 100644 index 00000000000..0bff4ed24a4 --- /dev/null +++ b/src/libsyntax/feature_gate/active.rs @@ -0,0 +1,522 @@ +//! List of the active feature gates. + +use crate::edition::Edition; +use crate::symbol::{Symbol, sym}; +use syntax_pos::Span; + +macro_rules! set { + ($field: ident) => {{ + fn f(features: &mut Features, _: Span) { + features.$field = true; + } + f as fn(&mut Features, Span) + }} +} + +macro_rules! declare_features { + ($((active, $feature: ident, $ver: expr, $issue: expr, $edition: expr),)+) => { + /// Represents active features that are currently being implemented or + /// currently being considered for addition/removal. + pub const ACTIVE_FEATURES: + &[(Symbol, &str, Option<u32>, Option<Edition>, fn(&mut Features, Span))] = + &[$((sym::$feature, $ver, $issue, $edition, set!($feature))),+]; + + /// A set of features to be used by later passes. + #[derive(Clone)] + pub struct Features { + /// `#![feature]` attrs for language features, for error reporting + pub declared_lang_features: Vec<(Symbol, Span, Option<Symbol>)>, + /// `#![feature]` attrs for non-language (library) features + pub declared_lib_features: Vec<(Symbol, Span)>, + $(pub $feature: bool),+ + } + + impl Features { + pub fn new() -> Features { + Features { + declared_lang_features: Vec::new(), + declared_lib_features: Vec::new(), + $($feature: false),+ + } + } + + pub fn walk_feature_fields<F>(&self, mut f: F) + where F: FnMut(&str, bool) + { + $(f(stringify!($feature), self.$feature);)+ + } + } + }; +} + +// If you change this, please modify `src/doc/unstable-book` as well. +// +// Don't ever remove anything from this list; move them to `removed.rs`. +// +// The version numbers here correspond to the version in which the current status +// was set. This is most important for knowing when a particular feature became +// stable (active). +// +// Note that the features are grouped into internal/user-facing and then +// sorted by version inside those groups. This is inforced with tidy. +// +// N.B., `tools/tidy/src/features.rs` parses this information directly out of the +// source, so take care when modifying it. + +declare_features! ( + // ------------------------------------------------------------------------- + // feature-group-start: internal feature gates + // ------------------------------------------------------------------------- + + // no-tracking-issue-start + + // Allows using compiler's own crates. + (active, rustc_private, "1.0.0", Some(27812), None), + + // Allows using the `rust-intrinsic`'s "ABI". + (active, intrinsics, "1.0.0", None, None), + + // Allows using `#[lang = ".."]` attribute for linking items to special compiler logic. + (active, lang_items, "1.0.0", None, None), + + // Allows using the `#[stable]` and `#[unstable]` attributes. + (active, staged_api, "1.0.0", None, None), + + // Allows using `#[allow_internal_unstable]`. This is an + // attribute on `macro_rules!` and can't use the attribute handling + // below (it has to be checked before expansion possibly makes + // macros disappear). + (active, allow_internal_unstable, "1.0.0", None, None), + + // Allows using `#[allow_internal_unsafe]`. This is an + // attribute on `macro_rules!` and can't use the attribute handling + // below (it has to be checked before expansion possibly makes + // macros disappear). + (active, allow_internal_unsafe, "1.0.0", None, None), + + // Allows using the macros: + // + `__diagnostic_used` + // + `__register_diagnostic` + // +`__build_diagnostic_array` + (active, rustc_diagnostic_macros, "1.0.0", None, None), + + // Allows using `#[rustc_const_unstable(feature = "foo", ..)]` which + // lets a function to be `const` when opted into with `#![feature(foo)]`. + (active, rustc_const_unstable, "1.0.0", None, None), + + // no-tracking-issue-end + + // Allows using `#[link_name="llvm.*"]`. + (active, link_llvm_intrinsics, "1.0.0", Some(29602), None), + + // Allows using `rustc_*` attributes (RFC 572). + (active, rustc_attrs, "1.0.0", Some(29642), None), + + // Allows using `#[on_unimplemented(..)]` on traits. + (active, on_unimplemented, "1.0.0", Some(29628), None), + + // Allows using the `box $expr` syntax. + (active, box_syntax, "1.0.0", Some(49733), None), + + // Allows using `#[main]` to replace the entrypoint `#[lang = "start"]` calls. + (active, main, "1.0.0", Some(29634), None), + + // Allows using `#[start]` on a function indicating that it is the program entrypoint. + (active, start, "1.0.0", Some(29633), None), + + // Allows using the `#[fundamental]` attribute. + (active, fundamental, "1.0.0", Some(29635), None), + + // Allows using the `rust-call` ABI. + (active, unboxed_closures, "1.0.0", Some(29625), None), + + // Allows using the `#[linkage = ".."]` attribute. + (active, linkage, "1.0.0", Some(29603), None), + + // Allows features specific to OIBIT (auto traits). + (active, optin_builtin_traits, "1.0.0", Some(13231), None), + + // Allows using `box` in patterns (RFC 469). + (active, box_patterns, "1.0.0", Some(29641), None), + + // no-tracking-issue-start + + // Allows using `#[prelude_import]` on glob `use` items. + (active, prelude_import, "1.2.0", None, None), + + // no-tracking-issue-end + + // no-tracking-issue-start + + // Allows using `#[omit_gdb_pretty_printer_section]`. + (active, omit_gdb_pretty_printer_section, "1.5.0", None, None), + + // Allows using the `vectorcall` ABI. + (active, abi_vectorcall, "1.7.0", None, None), + + // no-tracking-issue-end + + // Allows using `#[structural_match]` which indicates that a type is structurally matchable. + (active, structural_match, "1.8.0", Some(31434), None), + + // Allows using the `may_dangle` attribute (RFC 1327). + (active, dropck_eyepatch, "1.10.0", Some(34761), None), + + // Allows using the `#![panic_runtime]` attribute. + (active, panic_runtime, "1.10.0", Some(32837), None), + + // Allows declaring with `#![needs_panic_runtime]` that a panic runtime is needed. + (active, needs_panic_runtime, "1.10.0", Some(32837), None), + + // no-tracking-issue-start + + // Allows identifying the `compiler_builtins` crate. + (active, compiler_builtins, "1.13.0", None, None), + + // Allows using the `unadjusted` ABI; perma-unstable. + (active, abi_unadjusted, "1.16.0", None, None), + + // Allows identifying crates that contain sanitizer runtimes. + (active, sanitizer_runtime, "1.17.0", None, None), + + // Used to identify crates that contain the profiler runtime. + (active, profiler_runtime, "1.18.0", None, None), + + // Allows using the `thiscall` ABI. + (active, abi_thiscall, "1.19.0", None, None), + + // Allows using `#![needs_allocator]`, an implementation detail of `#[global_allocator]`. + (active, allocator_internals, "1.20.0", None, None), + + // no-tracking-issue-end + + // Added for testing E0705; perma-unstable. + (active, test_2018_feature, "1.31.0", Some(0), Some(Edition::Edition2018)), + + // ------------------------------------------------------------------------- + // feature-group-end: internal feature gates + // ------------------------------------------------------------------------- + + // ------------------------------------------------------------------------- + // feature-group-start: actual feature gates (target features) + // ------------------------------------------------------------------------- + + // FIXME: Document these and merge with the list below. + + // Unstable `#[target_feature]` directives. + (active, arm_target_feature, "1.27.0", Some(44839), None), + (active, aarch64_target_feature, "1.27.0", Some(44839), None), + (active, hexagon_target_feature, "1.27.0", Some(44839), None), + (active, powerpc_target_feature, "1.27.0", Some(44839), None), + (active, mips_target_feature, "1.27.0", Some(44839), None), + (active, avx512_target_feature, "1.27.0", Some(44839), None), + (active, mmx_target_feature, "1.27.0", Some(44839), None), + (active, sse4a_target_feature, "1.27.0", Some(44839), None), + (active, tbm_target_feature, "1.27.0", Some(44839), None), + (active, wasm_target_feature, "1.30.0", Some(44839), None), + (active, adx_target_feature, "1.32.0", Some(44839), None), + (active, cmpxchg16b_target_feature, "1.32.0", Some(44839), None), + (active, movbe_target_feature, "1.34.0", Some(44839), None), + (active, rtm_target_feature, "1.35.0", Some(44839), None), + (active, f16c_target_feature, "1.36.0", Some(44839), None), + + // ------------------------------------------------------------------------- + // feature-group-end: actual feature gates (target features) + // ------------------------------------------------------------------------- + + // ------------------------------------------------------------------------- + // feature-group-start: actual feature gates + // ------------------------------------------------------------------------- + + // Allows using the `#[link_args]` attribute. + (active, link_args, "1.0.0", Some(29596), None), + + // Allows defining identifiers beyond ASCII. + (active, non_ascii_idents, "1.0.0", Some(55467), None), + + // Allows using `#[plugin_registrar]` on functions. + (active, plugin_registrar, "1.0.0", Some(29597), None), + + // Allows using `#![plugin(myplugin)]`. + (active, plugin, "1.0.0", Some(29597), None), + + // Allows using `#[thread_local]` on `static` items. + (active, thread_local, "1.0.0", Some(29594), None), + + // Allows the use of SIMD types in functions declared in `extern` blocks. + (active, simd_ffi, "1.0.0", Some(27731), None), + + // Allows using custom attributes (RFC 572). + (active, custom_attribute, "1.0.0", Some(29642), None), + + // Allows using non lexical lifetimes (RFC 2094). + (active, nll, "1.0.0", Some(43234), None), + + // Allows using slice patterns. + (active, slice_patterns, "1.0.0", Some(62254), None), + + // Allows the definition of `const` functions with some advanced features. + (active, const_fn, "1.2.0", Some(57563), None), + + // Allows associated type defaults. + (active, associated_type_defaults, "1.2.0", Some(29661), None), + + // Allows `#![no_core]`. + (active, no_core, "1.3.0", Some(29639), None), + + // Allows default type parameters to influence type inference. + (active, default_type_parameter_fallback, "1.3.0", Some(27336), None), + + // Allows `repr(simd)` and importing the various simd intrinsics. + (active, repr_simd, "1.4.0", Some(27731), None), + + // Allows `extern "platform-intrinsic" { ... }`. + (active, platform_intrinsics, "1.4.0", Some(27731), None), + + // Allows `#[unwind(..)]`. + // + // Permits specifying whether a function should permit unwinding or abort on unwind. + (active, unwind_attributes, "1.4.0", Some(58760), None), + + // Allows `#[no_debug]`. + (active, no_debug, "1.5.0", Some(29721), None), + + // Allows attributes on expressions and non-item statements. + (active, stmt_expr_attributes, "1.6.0", Some(15701), None), + + // Allows the use of type ascription in expressions. + (active, type_ascription, "1.6.0", Some(23416), None), + + // Allows `cfg(target_thread_local)`. + (active, cfg_target_thread_local, "1.7.0", Some(29594), None), + + // Allows specialization of implementations (RFC 1210). + (active, specialization, "1.7.0", Some(31844), None), + + // Allows using `#[naked]` on functions. + (active, naked_functions, "1.9.0", Some(32408), None), + + // Allows `cfg(target_has_atomic = "...")`. + (active, cfg_target_has_atomic, "1.9.0", Some(32976), None), + + // Allows `X..Y` patterns. + (active, exclusive_range_pattern, "1.11.0", Some(37854), None), + + // Allows the `!` type. Does not imply 'exhaustive_patterns' (below) any more. + (active, never_type, "1.13.0", Some(35121), None), + + // Allows exhaustive pattern matching on types that contain uninhabited types. + (active, exhaustive_patterns, "1.13.0", Some(51085), None), + + // Allows untagged unions `union U { ... }`. + (active, untagged_unions, "1.13.0", Some(32836), None), + + // Allows `#[link(..., cfg(..))]`. + (active, link_cfg, "1.14.0", Some(37406), None), + + // Allows `extern "ptx-*" fn()`. + (active, abi_ptx, "1.15.0", Some(38788), None), + + // Allows the `#[repr(i128)]` attribute for enums. + (active, repr128, "1.16.0", Some(35118), None), + + // Allows `#[link(kind="static-nobundle"...)]`. + (active, static_nobundle, "1.16.0", Some(37403), None), + + // Allows `extern "msp430-interrupt" fn()`. + (active, abi_msp430_interrupt, "1.16.0", Some(38487), None), + + // Allows declarative macros 2.0 (`macro`). + (active, decl_macro, "1.17.0", Some(39412), None), + + // Allows `extern "x86-interrupt" fn()`. + (active, abi_x86_interrupt, "1.17.0", Some(40180), None), + + // Allows overlapping impls of marker traits. + (active, overlapping_marker_traits, "1.18.0", Some(29864), None), + + // Allows a test to fail without failing the whole suite. + (active, allow_fail, "1.19.0", Some(46488), None), + + // Allows unsized tuple coercion. + (active, unsized_tuple_coercion, "1.20.0", Some(42877), None), + + // Allows defining generators. + (active, generators, "1.21.0", Some(43122), None), + + // Allows `#[doc(cfg(...))]`. + (active, doc_cfg, "1.21.0", Some(43781), None), + + // Allows `#[doc(masked)]`. + (active, doc_masked, "1.21.0", Some(44027), None), + + // Allows `#[doc(spotlight)]`. + (active, doc_spotlight, "1.22.0", Some(45040), None), + + // Allows `#[doc(include = "some-file")]`. + (active, external_doc, "1.22.0", Some(44732), None), + + // Allows future-proofing enums/structs with the `#[non_exhaustive]` attribute (RFC 2008). + (active, non_exhaustive, "1.22.0", Some(44109), None), + + // Allows using `crate` as visibility modifier, synonymous with `pub(crate)`. + (active, crate_visibility_modifier, "1.23.0", Some(53120), None), + + // Allows defining `extern type`s. + (active, extern_types, "1.23.0", Some(43467), None), + + // Allows trait methods with arbitrary self types. + (active, arbitrary_self_types, "1.23.0", Some(44874), None), + + // Allows in-band quantification of lifetime bindings (e.g., `fn foo(x: &'a u8) -> &'a u8`). + (active, in_band_lifetimes, "1.23.0", Some(44524), None), + + // Allows associated types to be generic, e.g., `type Foo<T>;` (RFC 1598). + (active, generic_associated_types, "1.23.0", Some(44265), None), + + // Allows defining `trait X = A + B;` alias items. + (active, trait_alias, "1.24.0", Some(41517), None), + + // Allows infering `'static` outlives requirements (RFC 2093). + (active, infer_static_outlives_requirements, "1.26.0", Some(54185), None), + + // Allows macro invocations in `extern {}` blocks. + (active, macros_in_extern, "1.27.0", Some(49476), None), + + // Allows accessing fields of unions inside `const` functions. + (active, const_fn_union, "1.27.0", Some(51909), None), + + // Allows casting raw pointers to `usize` during const eval. + (active, const_raw_ptr_to_usize_cast, "1.27.0", Some(51910), None), + + // Allows dereferencing raw pointers during const eval. + (active, const_raw_ptr_deref, "1.27.0", Some(51911), None), + + // Allows comparing raw pointers during const eval. + (active, const_compare_raw_pointers, "1.27.0", Some(53020), None), + + // Allows `#[doc(alias = "...")]`. + (active, doc_alias, "1.27.0", Some(50146), None), + + // Allows inconsistent bounds in where clauses. + (active, trivial_bounds, "1.28.0", Some(48214), None), + + // Allows `'a: { break 'a; }`. + (active, label_break_value, "1.28.0", Some(48594), None), + + // Allows using `#[doc(keyword = "...")]`. + (active, doc_keyword, "1.28.0", Some(51315), None), + + // Allows reinterpretation of the bits of a value of one type as another type during const eval. + (active, const_transmute, "1.29.0", Some(53605), None), + + // Allows using `try {...}` expressions. + (active, try_blocks, "1.29.0", Some(31436), None), + + // Allows defining an `#[alloc_error_handler]`. + (active, alloc_error_handler, "1.29.0", Some(51540), None), + + // Allows using the `amdgpu-kernel` ABI. + (active, abi_amdgpu_kernel, "1.29.0", Some(51575), None), + + // Allows panicking during const eval (producing compile-time errors). + (active, const_panic, "1.30.0", Some(51999), None), + + // Allows `#[marker]` on certain traits allowing overlapping implementations. + (active, marker_trait_attr, "1.30.0", Some(29864), None), + + // Allows macro invocations on modules expressions and statements and + // procedural macros to expand to non-items. + (active, proc_macro_hygiene, "1.30.0", Some(54727), None), + + // Allows unsized rvalues at arguments and parameters. + (active, unsized_locals, "1.30.0", Some(48055), None), + + // Allows custom test frameworks with `#![test_runner]` and `#[test_case]`. + (active, custom_test_frameworks, "1.30.0", Some(50297), None), + + // Allows non-builtin attributes in inner attribute position. + (active, custom_inner_attributes, "1.30.0", Some(54726), None), + + // Allows mixing bind-by-move in patterns and references to those identifiers in guards. + (active, bind_by_move_pattern_guards, "1.30.0", Some(15287), None), + + // Allows `impl Trait` in bindings (`let`, `const`, `static`). + (active, impl_trait_in_bindings, "1.30.0", Some(63065), None), + + // Allows using `reason` in lint attributes and the `#[expect(lint)]` lint check. + (active, lint_reasons, "1.31.0", Some(54503), None), + + // Allows exhaustive integer pattern matching on `usize` and `isize`. + (active, precise_pointer_size_matching, "1.32.0", Some(56354), None), + + // Allows relaxing the coherence rules such that + // `impl<T> ForeignTrait<LocalType> for ForeignType<T> is permitted. + (active, re_rebalance_coherence, "1.32.0", Some(55437), None), + + // Allows using `#[ffi_returns_twice]` on foreign functions. + (active, ffi_returns_twice, "1.34.0", Some(58314), None), + + // Allows const generic types (e.g. `struct Foo<const N: usize>(...);`). + (active, const_generics, "1.34.0", Some(44580), None), + + // Allows using `#[optimize(X)]`. + (active, optimize_attribute, "1.34.0", Some(54882), None), + + // Allows using C-variadics. + (active, c_variadic, "1.34.0", Some(44930), None), + + // Allows the user of associated type bounds. + (active, associated_type_bounds, "1.34.0", Some(52662), None), + + // Attributes on formal function params. + (active, param_attrs, "1.36.0", Some(60406), None), + + // Allows calling constructor functions in `const fn`. + (active, const_constructor, "1.37.0", Some(61456), None), + + // Allows `if/while p && let q = r && ...` chains. + (active, let_chains, "1.37.0", Some(53667), None), + + // Allows #[repr(transparent)] on enums (RFC 2645). + (active, transparent_enums, "1.37.0", Some(60405), None), + + // Allows #[repr(transparent)] on unions (RFC 2645). + (active, transparent_unions, "1.37.0", Some(60405), None), + + // Allows explicit discriminants on non-unit enum variants. + (active, arbitrary_enum_discriminant, "1.37.0", Some(60553), None), + + // Allows `impl Trait` with multiple unrelated lifetimes. + (active, member_constraints, "1.37.0", Some(61977), None), + + // Allows `async || body` closures. + (active, async_closure, "1.37.0", Some(62290), None), + + // Allows the use of `#[cfg(doctest)]`, set when rustdoc is collecting doctests + (active, cfg_doctest, "1.37.0", Some(62210), None), + + // Allows `[x; N]` where `x` is a constant (RFC 2203). + (active, const_in_array_repeat_expressions, "1.37.0", Some(49147), None), + + // Allows `impl Trait` to be used inside type aliases (RFC 2515). + (active, type_alias_impl_trait, "1.38.0", Some(63063), None), + + // Allows the use of or-patterns, e.g. `0 | 1`. + (active, or_patterns, "1.38.0", Some(54883), None), + + // ------------------------------------------------------------------------- + // feature-group-end: actual feature gates + // ------------------------------------------------------------------------- +); + +/// Some features are known to be incomplete and using them is likely to have +/// unanticipated results, such as compiler crashes. We warn the user about these +/// to alert them. +pub const INCOMPLETE_FEATURES: &[Symbol] = &[ + sym::impl_trait_in_bindings, + sym::generic_associated_types, + sym::const_generics, + sym::or_patterns, + sym::let_chains, +]; diff --git a/src/libsyntax/feature_gate/builtin_attrs.rs b/src/libsyntax/feature_gate/builtin_attrs.rs new file mode 100644 index 00000000000..b934f2e7f64 --- /dev/null +++ b/src/libsyntax/feature_gate/builtin_attrs.rs @@ -0,0 +1,562 @@ +//! Built-in attributes and `cfg` flag gating. + +use AttributeType::*; +use AttributeGate::*; + +use super::check::{emit_feature_err, GateIssue}; +use super::check::{Stability, EXPLAIN_ALLOW_INTERNAL_UNSAFE, EXPLAIN_ALLOW_INTERNAL_UNSTABLE}; +use super::active::Features; + +use crate::ast; +use crate::attr::AttributeTemplate; +use crate::symbol::{Symbol, sym}; +use crate::parse::ParseSess; + +use syntax_pos::Span; +use rustc_data_structures::fx::FxHashMap; +use lazy_static::lazy_static; + +type GateFn = fn(&Features) -> bool; + +macro_rules! cfg_fn { + ($field: ident) => { + (|features| { features.$field }) as GateFn + } +} + +/// `cfg(...)`'s that are feature gated. +const GATED_CFGS: &[(Symbol, Symbol, GateFn)] = &[ + // (name in cfg, feature, function to check if the feature is enabled) + (sym::target_thread_local, sym::cfg_target_thread_local, cfg_fn!(cfg_target_thread_local)), + (sym::target_has_atomic, sym::cfg_target_has_atomic, cfg_fn!(cfg_target_has_atomic)), + (sym::rustdoc, sym::doc_cfg, cfg_fn!(doc_cfg)), + (sym::doctest, sym::cfg_doctest, cfg_fn!(cfg_doctest)), +]; + +#[derive(Debug)] +pub struct GatedCfg { + span: Span, + index: usize, +} + +impl GatedCfg { + pub fn gate(cfg: &ast::MetaItem) -> Option<GatedCfg> { + GATED_CFGS.iter() + .position(|info| cfg.check_name(info.0)) + .map(|idx| { + GatedCfg { + span: cfg.span, + index: idx + } + }) + } + + pub fn check_and_emit(&self, sess: &ParseSess, features: &Features) { + let (cfg, feature, has_feature) = GATED_CFGS[self.index]; + if !has_feature(features) && !self.span.allows_unstable(feature) { + let explain = format!("`cfg({})` is experimental and subject to change", cfg); + emit_feature_err(sess, feature, self.span, GateIssue::Language, &explain); + } + } +} + +// If you change this, please modify `src/doc/unstable-book` as well. You must +// move that documentation into the relevant place in the other docs, and +// remove the chapter on the flag. + +#[derive(Copy, Clone, PartialEq, Debug)] +pub enum AttributeType { + /// Normal, builtin attribute that is consumed + /// by the compiler before the unused_attribute check + Normal, + + /// Builtin attribute that may not be consumed by the compiler + /// before the unused_attribute check. These attributes + /// will be ignored by the unused_attribute lint + Whitelisted, + + /// Builtin attribute that is only allowed at the crate level + CrateLevel, +} + +pub enum AttributeGate { + /// Is gated by a given feature gate, reason + /// and function to check if enabled + Gated(Stability, Symbol, &'static str, fn(&Features) -> bool), + + /// Ungated attribute, can be used on all release channels + Ungated, +} + +// fn() is not Debug +impl std::fmt::Debug for AttributeGate { + fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match *self { + Self::Gated(ref stab, name, expl, _) => + write!(fmt, "Gated({:?}, {}, {})", stab, name, expl), + Self::Ungated => write!(fmt, "Ungated") + } + } +} + +impl AttributeGate { + fn is_deprecated(&self) -> bool { + match *self { + Self::Gated(Stability::Deprecated(_, _), ..) => true, + _ => false, + } + } +} + +/// A convenience macro for constructing attribute templates. +/// E.g., `template!(Word, List: "description")` means that the attribute +/// supports forms `#[attr]` and `#[attr(description)]`. +macro_rules! template { + (Word) => { template!(@ true, None, None) }; + (List: $descr: expr) => { template!(@ false, Some($descr), None) }; + (NameValueStr: $descr: expr) => { template!(@ false, None, Some($descr)) }; + (Word, List: $descr: expr) => { template!(@ true, Some($descr), None) }; + (Word, NameValueStr: $descr: expr) => { template!(@ true, None, Some($descr)) }; + (List: $descr1: expr, NameValueStr: $descr2: expr) => { + template!(@ false, Some($descr1), Some($descr2)) + }; + (Word, List: $descr1: expr, NameValueStr: $descr2: expr) => { + template!(@ true, Some($descr1), Some($descr2)) + }; + (@ $word: expr, $list: expr, $name_value_str: expr) => { AttributeTemplate { + word: $word, list: $list, name_value_str: $name_value_str + } }; +} + +macro_rules! ungated { + ($attr:ident, $typ:expr, $tpl:expr $(,)?) => { + (sym::$attr, $typ, $tpl, Ungated) + }; +} + +macro_rules! gated { + ($attr:ident, $typ:expr, $tpl:expr, $gate:ident, $msg:expr $(,)?) => { + (sym::$attr, $typ, $tpl, Gated(Stability::Unstable, sym::$gate, $msg, cfg_fn!($gate))) + }; + ($attr:ident, $typ:expr, $tpl:expr, $msg:expr $(,)?) => { + (sym::$attr, $typ, $tpl, Gated(Stability::Unstable, sym::$attr, $msg, cfg_fn!($attr))) + }; +} + +macro_rules! rustc_attr { + (TEST, $attr:ident, $typ:expr, $tpl:expr $(,)?) => { + rustc_attr!( + $attr, $typ, $tpl, + concat!("the `#[", stringify!($attr), "]` attribute is just used for rustc unit tests \ + and will never be stable", + ), + ) + }; + ($attr:ident, $typ:expr, $tpl:expr, $msg:expr $(,)?) => { + (sym::$attr, $typ, $tpl, + Gated(Stability::Unstable, sym::rustc_attrs, $msg, cfg_fn!(rustc_attrs))) + }; +} + +macro_rules! experimental { + ($attr:ident) => { + concat!("the `#[", stringify!($attr), "]` attribute is an experimental feature") + } +} + +const IMPL_DETAIL: &str = "internal implementation detail"; +const INTERAL_UNSTABLE: &str = "this is an internal attribute that will never be stable"; + +pub type BuiltinAttribute = (Symbol, AttributeType, AttributeTemplate, AttributeGate); + +/// Attributes that have a special meaning to rustc or rustdoc +pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ + // ========================================================================== + // Stable attributes: + // ========================================================================== + + // Condtional compilation: + ungated!(cfg, Normal, template!(List: "predicate")), + ungated!(cfg_attr, Normal, template!(List: "predicate, attr1, attr2, ...")), + + // Testing: + ungated!(ignore, Normal, template!(Word, NameValueStr: "reason")), + ungated!( + should_panic, Normal, + template!(Word, List: r#"expected = "reason"#, NameValueStr: "reason"), + ), + // FIXME(Centril): This can be used on stable but shouldn't. + ungated!(reexport_test_harness_main, Normal, template!(NameValueStr: "name")), + + // Macros: + ungated!(derive, Normal, template!(List: "Trait1, Trait2, ...")), + ungated!(automatically_derived, Normal, template!(Word)), + // FIXME(#14407) + ungated!(macro_use, Normal, template!(Word, List: "name1, name2, ...")), + ungated!(macro_escape, Normal, template!(Word)), // Deprecated synonym for `macro_use`. + ungated!(macro_export, Normal, template!(Word, List: "local_inner_macros")), + ungated!(proc_macro, Normal, template!(Word)), + ungated!( + proc_macro_derive, Normal, + template!(List: "TraitName, /*opt*/ attributes(name1, name2, ...)"), + ), + ungated!(proc_macro_attribute, Normal, template!(Word)), + + // Lints: + ungated!(warn, Normal, template!(List: r#"lint1, lint2, ..., /*opt*/ reason = "...""#)), + ungated!(allow, Normal, template!(List: r#"lint1, lint2, ..., /*opt*/ reason = "...""#)), + ungated!(forbid, Normal, template!(List: r#"lint1, lint2, ..., /*opt*/ reason = "...""#)), + ungated!(deny, Normal, template!(List: r#"lint1, lint2, ..., /*opt*/ reason = "...""#)), + ungated!(must_use, Whitelisted, template!(Word, NameValueStr: "reason")), + // FIXME(#14407) + ungated!( + deprecated, Normal, + template!( + Word, + List: r#"/*opt*/ since = "version", /*opt*/ note = "reason""#, + NameValueStr: "reason" + ), + ), + + // Crate properties: + ungated!(crate_name, CrateLevel, template!(NameValueStr: "name")), + ungated!(crate_type, CrateLevel, template!(NameValueStr: "bin|lib|...")), + ungated!(crate_id, CrateLevel, template!(NameValueStr: "ignored")), + + // ABI, linking, symbols, and FFI + ungated!( + link, Whitelisted, + template!(List: r#"name = "...", /*opt*/ kind = "dylib|static|...", /*opt*/ cfg = "...""#), + ), + ungated!(link_name, Whitelisted, template!(NameValueStr: "name")), + ungated!(no_link, Normal, template!(Word)), + ungated!(repr, Normal, template!(List: "C, packed, ...")), + ungated!(export_name, Whitelisted, template!(NameValueStr: "name")), + ungated!(link_section, Whitelisted, template!(NameValueStr: "name")), + ungated!(no_mangle, Whitelisted, template!(Word)), + ungated!(used, Whitelisted, template!(Word)), + + // Limits: + ungated!(recursion_limit, CrateLevel, template!(NameValueStr: "N")), + ungated!(type_length_limit, CrateLevel, template!(NameValueStr: "N")), + + // Entry point: + ungated!(main, Normal, template!(Word)), + ungated!(start, Normal, template!(Word)), + ungated!(no_start, CrateLevel, template!(Word)), + ungated!(no_main, CrateLevel, template!(Word)), + + // Modules, prelude, and resolution: + ungated!(path, Normal, template!(NameValueStr: "file")), + ungated!(no_std, CrateLevel, template!(Word)), + ungated!(no_implicit_prelude, Normal, template!(Word)), + + // Runtime + ungated!(windows_subsystem, Whitelisted, template!(NameValueStr: "windows|console")), + ungated!(panic_handler, Normal, template!(Word)), // RFC 2070 + + // Code generation: + ungated!(inline, Whitelisted, template!(Word, List: "always|never")), + ungated!(cold, Whitelisted, template!(Word)), + ungated!(no_builtins, Whitelisted, template!(Word)), + ungated!(target_feature, Whitelisted, template!(List: r#"enable = "name""#)), + + // FIXME: #14408 whitelist docs since rustdoc looks at them + ungated!(doc, Whitelisted, template!(List: "hidden|inline|...", NameValueStr: "string")), + + // ========================================================================== + // Unstable attributes: + // ========================================================================== + + // Linking: + gated!(naked, Whitelisted, template!(Word), naked_functions, experimental!(naked)), + gated!( + link_args, Normal, template!(NameValueStr: "args"), + "the `link_args` attribute is experimental and not portable across platforms, \ + it is recommended to use `#[link(name = \"foo\")] instead", + ), + + // Plugins: + ungated!(plugin_registrar, Normal, template!(Word)), + gated!( + plugin, CrateLevel, template!(List: "name|name(args)"), + "compiler plugins are experimental and possibly buggy", + ), + + // Testing: + gated!(allow_fail, Normal, template!(Word), experimental!(allow_fail)), + gated!( + test_runner, CrateLevel, template!(List: "path"), custom_test_frameworks, + "custom test frameworks are an unstable feature", + ), + + // RFC #2008 + gated!(non_exhaustive, Whitelisted, template!(Word), experimental!(non_exhaustive)), + // RFC #1268 + gated!(marker, Normal, template!(Word), marker_trait_attr, experimental!(marker)), + gated!( + thread_local, Whitelisted, template!(Word), + "`#[thread_local]` is an experimental feature, and does not currently handle destructors", + ), + gated!(no_core, CrateLevel, template!(Word), experimental!(no_core)), + // RFC 2412 + gated!( + optimize, Whitelisted, template!(List: "size|speed"), optimize_attribute, + experimental!(optimize), + ), + + gated!(ffi_returns_twice, Whitelisted, template!(Word), experimental!(ffi_returns_twice)), + + // ========================================================================== + // Internal attributes: Stability, deprecation, and unsafe: + // ========================================================================== + + ungated!(feature, CrateLevel, template!(List: "name1, name1, ...")), + // FIXME(#14407) -- only looked at on-demand so we can't + // guarantee they'll have already been checked. + ungated!( + rustc_deprecated, Whitelisted, + template!(List: r#"since = "version", reason = "...""#) + ), + // FIXME(#14407) + ungated!(stable, Whitelisted, template!(List: r#"feature = "name", since = "version""#)), + // FIXME(#14407) + ungated!( + unstable, Whitelisted, + template!(List: r#"feature = "name", reason = "...", issue = "N""#), + ), + gated!( + rustc_const_unstable, Normal, template!(List: r#"feature = "name""#), + "the `#[rustc_const_unstable]` attribute is an internal feature", + ), + gated!( + allow_internal_unstable, Normal, template!(Word, List: "feat1, feat2, ..."), + EXPLAIN_ALLOW_INTERNAL_UNSTABLE, + ), + gated!(allow_internal_unsafe, Normal, template!(Word), EXPLAIN_ALLOW_INTERNAL_UNSAFE), + + // ========================================================================== + // Internal attributes: Type system related: + // ========================================================================== + + gated!(fundamental, Whitelisted, template!(Word), experimental!(fundamental)), + gated!( + // RFC #1445. + structural_match, Whitelisted, template!(Word), + "the semantics of constant patterns is not yet settled", + ), + gated!( + may_dangle, Normal, template!(Word), dropck_eyepatch, + "`may_dangle` has unstable semantics and may be removed in the future", + ), + + // ========================================================================== + // Internal attributes: Runtime related: + // ========================================================================== + + rustc_attr!(rustc_allocator, Whitelisted, template!(Word), IMPL_DETAIL), + rustc_attr!(rustc_allocator_nounwind, Whitelisted, template!(Word), IMPL_DETAIL), + gated!(alloc_error_handler, Normal, template!(Word), experimental!(alloc_error_handler)), + gated!( + default_lib_allocator, Whitelisted, template!(Word), allocator_internals, + experimental!(default_lib_allocator), + ), + gated!( + needs_allocator, Normal, template!(Word), allocator_internals, + experimental!(needs_allocator), + ), + gated!(panic_runtime, Whitelisted, template!(Word), experimental!(panic_runtime)), + gated!(needs_panic_runtime, Whitelisted, template!(Word), experimental!(needs_panic_runtime)), + gated!( + unwind, Whitelisted, template!(List: "allowed|aborts"), unwind_attributes, + experimental!(unwind), + ), + gated!( + compiler_builtins, Whitelisted, template!(Word), + "the `#[compiler_builtins]` attribute is used to identify the `compiler_builtins` crate \ + which contains compiler-rt intrinsics and will never be stable", + ), + gated!( + sanitizer_runtime, Whitelisted, template!(Word), + "the `#[sanitizer_runtime]` attribute is used to identify crates that contain the runtime \ + of a sanitizer and will never be stable", + ), + gated!( + profiler_runtime, Whitelisted, template!(Word), + "the `#[profiler_runtime]` attribute is used to identify the `profiler_builtins` crate \ + which contains the profiler runtime and will never be stable", + ), + + // ========================================================================== + // Internal attributes, Linkage: + // ========================================================================== + + gated!( + linkage, Whitelisted, template!(NameValueStr: "external|internal|..."), + "the `linkage` attribute is experimental and not portable across platforms", + ), + rustc_attr!(rustc_std_internal_symbol, Whitelisted, template!(Word), INTERAL_UNSTABLE), + + // ========================================================================== + // Internal attributes, Macro related: + // ========================================================================== + + rustc_attr!(rustc_builtin_macro, Whitelisted, template!(Word), IMPL_DETAIL), + rustc_attr!(rustc_proc_macro_decls, Normal, template!(Word), INTERAL_UNSTABLE), + rustc_attr!( + rustc_macro_transparency, Whitelisted, + template!(NameValueStr: "transparent|semitransparent|opaque"), + "used internally for testing macro hygiene", + ), + + // ========================================================================== + // Internal attributes, Diagnostics related: + // ========================================================================== + + gated!( + rustc_on_unimplemented, Whitelisted, + template!( + List: r#"/*opt*/ message = "...", /*opt*/ label = "...", /*opt*/ note = "...""#, + NameValueStr: "message" + ), + on_unimplemented, + experimental!(rustc_on_unimplemented), + ), + // Whitelists "identity-like" conversion methods to suggest on type mismatch. + rustc_attr!(rustc_conversion_suggestion, Whitelisted, template!(Word), INTERAL_UNSTABLE), + + // ========================================================================== + // Internal attributes, Const related: + // ========================================================================== + + rustc_attr!(rustc_promotable, Whitelisted, template!(Word), IMPL_DETAIL), + rustc_attr!(rustc_allow_const_fn_ptr, Whitelisted, template!(Word), IMPL_DETAIL), + rustc_attr!(rustc_args_required_const, Whitelisted, template!(List: "N"), INTERAL_UNSTABLE), + + // ========================================================================== + // Internal attributes, Layout related: + // ========================================================================== + + rustc_attr!( + rustc_layout_scalar_valid_range_start, Whitelisted, template!(List: "value"), + "the `#[rustc_layout_scalar_valid_range_start]` attribute is just used to enable \ + niche optimizations in libcore and will never be stable", + ), + rustc_attr!( + rustc_layout_scalar_valid_range_end, Whitelisted, template!(List: "value"), + "the `#[rustc_layout_scalar_valid_range_end]` attribute is just used to enable \ + niche optimizations in libcore and will never be stable", + ), + rustc_attr!( + rustc_nonnull_optimization_guaranteed, Whitelisted, template!(Word), + "the `#[rustc_nonnull_optimization_guaranteed]` attribute is just used to enable \ + niche optimizations in libcore and will never be stable", + ), + + // ========================================================================== + // Internal attributes, Misc: + // ========================================================================== + + gated!( + lang, Normal, template!(NameValueStr: "name"), lang_items, + "language items are subject to change", + ), + ( + sym::no_debug, Whitelisted, template!(Word), + Gated( + Stability::Deprecated("https://github.com/rust-lang/rust/issues/29721", None), + sym::no_debug, + "the `#[no_debug]` attribute was an experimental feature that has been \ + deprecated due to lack of demand", + cfg_fn!(no_debug) + ) + ), + gated!( + // Used in resolve: + prelude_import, Whitelisted, template!(Word), + "`#[prelude_import]` is for use by rustc only", + ), + gated!( + rustc_paren_sugar, Normal, template!(Word), unboxed_closures, + "unboxed_closures are still evolving", + ), + rustc_attr!( + rustc_inherit_overflow_checks, Whitelisted, template!(Word), + "the `#[rustc_inherit_overflow_checks]` attribute is just used to control \ + overflow checking behavior of several libcore functions that are inlined \ + across crates and will never be stable", + ), + rustc_attr!( + rustc_test_marker, Normal, template!(Word), + "the `#[rustc_test_marker]` attribute is used internally to track tests", + ), + + // ========================================================================== + // Internal attributes, Testing: + // ========================================================================== + + rustc_attr!(TEST, rustc_outlives, Normal, template!(Word)), + rustc_attr!(TEST, rustc_variance, Normal, template!(Word)), + rustc_attr!(TEST, rustc_layout, Normal, template!(List: "field1, field2, ...")), + rustc_attr!(TEST, rustc_regions, Normal, template!(Word)), + rustc_attr!(TEST, rustc_error, Whitelisted, template!(Word)), + rustc_attr!(TEST, rustc_dump_user_substs, Whitelisted, template!(Word)), + rustc_attr!(TEST, rustc_if_this_changed, Whitelisted, template!(Word, List: "DepNode")), + rustc_attr!(TEST, rustc_then_this_would_need, Whitelisted, template!(List: "DepNode")), + rustc_attr!( + TEST, rustc_dirty, Whitelisted, + template!(List: r#"cfg = "...", /*opt*/ label = "...", /*opt*/ except = "...""#), + ), + rustc_attr!( + TEST, rustc_clean, Whitelisted, + template!(List: r#"cfg = "...", /*opt*/ label = "...", /*opt*/ except = "...""#), + ), + rustc_attr!( + TEST, rustc_partition_reused, Whitelisted, + template!(List: r#"cfg = "...", module = "...""#), + ), + rustc_attr!( + TEST, rustc_partition_codegened, Whitelisted, + template!(List: r#"cfg = "...", module = "...""#), + ), + rustc_attr!( + TEST, rustc_expected_cgu_reuse, Whitelisted, + template!(List: r#"cfg = "...", module = "...", kind = "...""#), + ), + rustc_attr!(TEST, rustc_synthetic, Whitelisted, template!(Word)), + rustc_attr!(TEST, rustc_symbol_name, Whitelisted, template!(Word)), + rustc_attr!(TEST, rustc_def_path, Whitelisted, template!(Word)), + rustc_attr!(TEST, rustc_mir, Whitelisted, template!(List: "arg1, arg2, ...")), + rustc_attr!(TEST, rustc_dump_program_clauses, Whitelisted, template!(Word)), + rustc_attr!(TEST, rustc_dump_env_program_clauses, Whitelisted, template!(Word)), + rustc_attr!(TEST, rustc_object_lifetime_default, Whitelisted, template!(Word)), + rustc_attr!(TEST, rustc_dummy, Normal, template!(Word /* doesn't matter*/)), + gated!( + omit_gdb_pretty_printer_section, Whitelisted, template!(Word), + "the `#[omit_gdb_pretty_printer_section]` attribute is just used for the Rust test suite", + ), +]; + +pub fn deprecated_attributes() -> Vec<&'static BuiltinAttribute> { + BUILTIN_ATTRIBUTES.iter().filter(|(.., gate)| gate.is_deprecated()).collect() +} + +pub fn is_builtin_attr_name(name: ast::Name) -> bool { + BUILTIN_ATTRIBUTE_MAP.get(&name).is_some() +} + +pub fn is_builtin_attr(attr: &ast::Attribute) -> bool { + attr.ident().and_then(|ident| BUILTIN_ATTRIBUTE_MAP.get(&ident.name)).is_some() +} + +lazy_static! { + pub static ref BUILTIN_ATTRIBUTE_MAP: FxHashMap<Symbol, &'static BuiltinAttribute> = { + let mut map = FxHashMap::default(); + for attr in BUILTIN_ATTRIBUTES.iter() { + if map.insert(attr.0, attr).is_some() { + panic!("duplicate builtin attribute `{}`", attr.0); + } + } + map + }; +} diff --git a/src/libsyntax/feature_gate/check.rs b/src/libsyntax/feature_gate/check.rs new file mode 100644 index 00000000000..d82b287b6fb --- /dev/null +++ b/src/libsyntax/feature_gate/check.rs @@ -0,0 +1,951 @@ +use super::active::{ACTIVE_FEATURES, Features}; +use super::accepted::ACCEPTED_FEATURES; +use super::removed::{REMOVED_FEATURES, STABLE_REMOVED_FEATURES}; +use super::builtin_attrs::{AttributeGate, AttributeType, BuiltinAttribute, BUILTIN_ATTRIBUTE_MAP}; + +use crate::ast::{ + self, AssocTyConstraint, AssocTyConstraintKind, NodeId, GenericParam, GenericParamKind, + PatKind, RangeEnd, +}; +use crate::attr::{self, check_builtin_attribute}; +use crate::source_map::Spanned; +use crate::edition::{ALL_EDITIONS, Edition}; +use crate::visit::{self, FnKind, Visitor}; +use crate::parse::{token, ParseSess}; +use crate::parse::parser::Parser; +use crate::symbol::{Symbol, sym}; +use crate::tokenstream::TokenTree; + +use errors::{Applicability, DiagnosticBuilder, Handler}; +use rustc_data_structures::fx::FxHashMap; +use rustc_target::spec::abi::Abi; +use syntax_pos::{Span, DUMMY_SP, MultiSpan}; +use log::debug; + +use std::env; + +#[derive(Copy, Clone, Debug)] +pub enum Stability { + Unstable, + // First argument is tracking issue link; second argument is an optional + // help message, which defaults to "remove this attribute" + Deprecated(&'static str, Option<&'static str>), +} + +struct Context<'a> { + features: &'a Features, + parse_sess: &'a ParseSess, + plugin_attributes: &'a [(Symbol, AttributeType)], +} + +macro_rules! gate_feature_fn { + ($cx: expr, $has_feature: expr, $span: expr, $name: expr, $explain: expr, $level: expr) => {{ + let (cx, has_feature, span, + name, explain, level) = ($cx, $has_feature, $span, $name, $explain, $level); + let has_feature: bool = has_feature(&$cx.features); + debug!("gate_feature(feature = {:?}, span = {:?}); has? {}", name, span, has_feature); + if !has_feature && !span.allows_unstable($name) { + leveled_feature_err(cx.parse_sess, name, span, GateIssue::Language, explain, level) + .emit(); + } + }} +} + +macro_rules! gate_feature { + ($cx: expr, $feature: ident, $span: expr, $explain: expr) => { + gate_feature_fn!($cx, |x:&Features| x.$feature, $span, + sym::$feature, $explain, GateStrength::Hard) + }; + ($cx: expr, $feature: ident, $span: expr, $explain: expr, $level: expr) => { + gate_feature_fn!($cx, |x:&Features| x.$feature, $span, + sym::$feature, $explain, $level) + }; +} + +impl<'a> Context<'a> { + fn check_attribute( + &self, + attr: &ast::Attribute, + attr_info: Option<&BuiltinAttribute>, + is_macro: bool + ) { + debug!("check_attribute(attr = {:?})", attr); + if let Some(&(name, ty, _template, ref gateage)) = attr_info { + if let AttributeGate::Gated(_, name, desc, ref has_feature) = *gateage { + if !attr.span.allows_unstable(name) { + gate_feature_fn!( + self, has_feature, attr.span, name, desc, GateStrength::Hard + ); + } + } else if name == sym::doc { + if let Some(content) = attr.meta_item_list() { + if content.iter().any(|c| c.check_name(sym::include)) { + gate_feature!(self, external_doc, attr.span, + "`#[doc(include = \"...\")]` is experimental" + ); + } + } + } + debug!("check_attribute: {:?} is builtin, {:?}, {:?}", attr.path, ty, gateage); + return; + } else { + for segment in &attr.path.segments { + if segment.ident.as_str().starts_with("rustc") { + let msg = "attributes starting with `rustc` are \ + reserved for use by the `rustc` compiler"; + gate_feature!(self, rustc_attrs, segment.ident.span, msg); + } + } + } + for &(n, ty) in self.plugin_attributes { + if attr.path == n { + // Plugins can't gate attributes, so we don't check for it + // unlike the code above; we only use this loop to + // short-circuit to avoid the checks below. + debug!("check_attribute: {:?} is registered by a plugin, {:?}", attr.path, ty); + return; + } + } + if !is_macro && !attr::is_known(attr) { + // Only run the custom attribute lint during regular feature gate + // checking. Macro gating runs before the plugin attributes are + // registered, so we skip this in that case. + let msg = format!("the attribute `{}` is currently unknown to the compiler and \ + may have meaning added to it in the future", attr.path); + gate_feature!(self, custom_attribute, attr.span, &msg); + } + } +} + +pub fn check_attribute(attr: &ast::Attribute, parse_sess: &ParseSess, features: &Features) { + let cx = Context { features, parse_sess, plugin_attributes: &[] }; + cx.check_attribute( + attr, + attr.ident().and_then(|ident| BUILTIN_ATTRIBUTE_MAP.get(&ident.name).map(|a| *a)), + true + ); +} + +fn find_lang_feature_issue(feature: Symbol) -> Option<u32> { + if let Some(info) = ACTIVE_FEATURES.iter().find(|t| t.0 == feature) { + let issue = info.2; + // FIXME (#28244): enforce that active features have issue numbers + // assert!(issue.is_some()) + issue + } else { + // search in Accepted, Removed, or Stable Removed features + let found = ACCEPTED_FEATURES.iter().chain(REMOVED_FEATURES).chain(STABLE_REMOVED_FEATURES) + .find(|t| t.0 == feature); + match found { + Some(&(_, _, issue, _)) => issue, + None => panic!("Feature `{}` is not declared anywhere", feature), + } + } +} + +pub enum GateIssue { + Language, + Library(Option<u32>) +} + +#[derive(Debug, Copy, Clone, PartialEq)] +pub enum GateStrength { + /// A hard error. (Most feature gates should use this.) + Hard, + /// Only a warning. (Use this only as backwards-compatibility demands.) + Soft, +} + +pub fn emit_feature_err( + sess: &ParseSess, + feature: Symbol, + span: Span, + issue: GateIssue, + explain: &str, +) { + feature_err(sess, feature, span, issue, explain).emit(); +} + +pub fn feature_err<'a, S: Into<MultiSpan>>( + sess: &'a ParseSess, + feature: Symbol, + span: S, + issue: GateIssue, + explain: &str, +) -> DiagnosticBuilder<'a> { + leveled_feature_err(sess, feature, span, issue, explain, GateStrength::Hard) +} + +fn leveled_feature_err<'a, S: Into<MultiSpan>>( + sess: &'a ParseSess, + feature: Symbol, + span: S, + issue: GateIssue, + explain: &str, + level: GateStrength, +) -> DiagnosticBuilder<'a> { + let diag = &sess.span_diagnostic; + + let issue = match issue { + GateIssue::Language => find_lang_feature_issue(feature), + GateIssue::Library(lib) => lib, + }; + + let mut err = match level { + GateStrength::Hard => { + diag.struct_span_err_with_code(span, explain, stringify_error_code!(E0658)) + } + GateStrength::Soft => diag.struct_span_warn(span, explain), + }; + + match issue { + None | Some(0) => {} // We still accept `0` as a stand-in for backwards compatibility + Some(n) => { + err.note(&format!( + "for more information, see https://github.com/rust-lang/rust/issues/{}", + n, + )); + } + } + + // #23973: do not suggest `#![feature(...)]` if we are in beta/stable + if sess.unstable_features.is_nightly_build() { + err.help(&format!("add `#![feature({})]` to the crate attributes to enable", feature)); + } + + // If we're on stable and only emitting a "soft" warning, add a note to + // clarify that the feature isn't "on" (rather than being on but + // warning-worthy). + if !sess.unstable_features.is_nightly_build() && level == GateStrength::Soft { + err.help("a nightly build of the compiler is required to enable this feature"); + } + + err + +} + +const EXPLAIN_BOX_SYNTAX: &str = + "box expression syntax is experimental; you can call `Box::new` instead"; + +pub const EXPLAIN_STMT_ATTR_SYNTAX: &str = + "attributes on expressions are experimental"; + +pub const EXPLAIN_ALLOW_INTERNAL_UNSTABLE: &str = + "allow_internal_unstable side-steps feature gating and stability checks"; +pub const EXPLAIN_ALLOW_INTERNAL_UNSAFE: &str = + "allow_internal_unsafe side-steps the unsafe_code lint"; + +pub const EXPLAIN_UNSIZED_TUPLE_COERCION: &str = + "unsized tuple coercion is not stable enough for use and is subject to change"; + +struct PostExpansionVisitor<'a> { + context: &'a Context<'a>, + builtin_attributes: &'static FxHashMap<Symbol, &'static BuiltinAttribute>, +} + +macro_rules! gate_feature_post { + ($cx: expr, $feature: ident, $span: expr, $explain: expr) => {{ + let (cx, span) = ($cx, $span); + if !span.allows_unstable(sym::$feature) { + gate_feature!(cx.context, $feature, span, $explain) + } + }}; + ($cx: expr, $feature: ident, $span: expr, $explain: expr, $level: expr) => {{ + let (cx, span) = ($cx, $span); + if !span.allows_unstable(sym::$feature) { + gate_feature!(cx.context, $feature, span, $explain, $level) + } + }} +} + +impl<'a> PostExpansionVisitor<'a> { + fn check_abi(&self, abi: Abi, span: Span) { + match abi { + Abi::RustIntrinsic => { + gate_feature_post!(&self, intrinsics, span, + "intrinsics are subject to change"); + }, + Abi::PlatformIntrinsic => { + gate_feature_post!(&self, platform_intrinsics, span, + "platform intrinsics are experimental and possibly buggy"); + }, + Abi::Vectorcall => { + gate_feature_post!(&self, abi_vectorcall, span, + "vectorcall is experimental and subject to change"); + }, + Abi::Thiscall => { + gate_feature_post!(&self, abi_thiscall, span, + "thiscall is experimental and subject to change"); + }, + Abi::RustCall => { + gate_feature_post!(&self, unboxed_closures, span, + "rust-call ABI is subject to change"); + }, + Abi::PtxKernel => { + gate_feature_post!(&self, abi_ptx, span, + "PTX ABIs are experimental and subject to change"); + }, + Abi::Unadjusted => { + gate_feature_post!(&self, abi_unadjusted, span, + "unadjusted ABI is an implementation detail and perma-unstable"); + }, + Abi::Msp430Interrupt => { + gate_feature_post!(&self, abi_msp430_interrupt, span, + "msp430-interrupt ABI is experimental and subject to change"); + }, + Abi::X86Interrupt => { + gate_feature_post!(&self, abi_x86_interrupt, span, + "x86-interrupt ABI is experimental and subject to change"); + }, + Abi::AmdGpuKernel => { + gate_feature_post!(&self, abi_amdgpu_kernel, span, + "amdgpu-kernel ABI is experimental and subject to change"); + }, + // Stable + Abi::Cdecl | + Abi::Stdcall | + Abi::Fastcall | + Abi::Aapcs | + Abi::Win64 | + Abi::SysV64 | + Abi::Rust | + Abi::C | + Abi::System => {} + } + } +} + +impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { + fn visit_attribute(&mut self, attr: &ast::Attribute) { + let attr_info = attr.ident().and_then(|ident| { + self.builtin_attributes.get(&ident.name).map(|a| *a) + }); + + // Check for gated attributes. + self.context.check_attribute(attr, attr_info, false); + + if attr.check_name(sym::doc) { + if let Some(content) = attr.meta_item_list() { + if content.len() == 1 && content[0].check_name(sym::cfg) { + gate_feature_post!(&self, doc_cfg, attr.span, + "`#[doc(cfg(...))]` is experimental" + ); + } else if content.iter().any(|c| c.check_name(sym::masked)) { + gate_feature_post!(&self, doc_masked, attr.span, + "`#[doc(masked)]` is experimental" + ); + } else if content.iter().any(|c| c.check_name(sym::spotlight)) { + gate_feature_post!(&self, doc_spotlight, attr.span, + "`#[doc(spotlight)]` is experimental" + ); + } else if content.iter().any(|c| c.check_name(sym::alias)) { + gate_feature_post!(&self, doc_alias, attr.span, + "`#[doc(alias = \"...\")]` is experimental" + ); + } else if content.iter().any(|c| c.check_name(sym::keyword)) { + gate_feature_post!(&self, doc_keyword, attr.span, + "`#[doc(keyword = \"...\")]` is experimental" + ); + } + } + } + + match attr_info { + // `rustc_dummy` doesn't have any restrictions specific to built-in attributes. + Some(&(name, _, template, _)) if name != sym::rustc_dummy => + check_builtin_attribute(self.context.parse_sess, attr, name, template), + _ => if let Some(TokenTree::Token(token)) = attr.tokens.trees().next() { + if token == token::Eq { + // All key-value attributes are restricted to meta-item syntax. + attr.parse_meta(self.context.parse_sess).map_err(|mut err| err.emit()).ok(); + } + } + } + } + + fn visit_name(&mut self, sp: Span, name: ast::Name) { + if !name.as_str().is_ascii() { + gate_feature_post!( + &self, + non_ascii_idents, + self.context.parse_sess.source_map().def_span(sp), + "non-ascii idents are not fully supported" + ); + } + } + + fn visit_item(&mut self, i: &'a ast::Item) { + match i.node { + ast::ItemKind::ForeignMod(ref foreign_module) => { + self.check_abi(foreign_module.abi, i.span); + } + + ast::ItemKind::Fn(..) => { + if attr::contains_name(&i.attrs[..], sym::plugin_registrar) { + gate_feature_post!(&self, plugin_registrar, i.span, + "compiler plugins are experimental and possibly buggy"); + } + if attr::contains_name(&i.attrs[..], sym::start) { + gate_feature_post!(&self, start, i.span, + "a `#[start]` function is an experimental \ + feature whose signature may change \ + over time"); + } + if attr::contains_name(&i.attrs[..], sym::main) { + gate_feature_post!(&self, main, i.span, + "declaration of a non-standard `#[main]` \ + function may change over time, for now \ + a top-level `fn main()` is required"); + } + } + + ast::ItemKind::Struct(..) => { + for attr in attr::filter_by_name(&i.attrs[..], sym::repr) { + for item in attr.meta_item_list().unwrap_or_else(Vec::new) { + if item.check_name(sym::simd) { + gate_feature_post!(&self, repr_simd, attr.span, + "SIMD types are experimental and possibly buggy"); + } + } + } + } + + ast::ItemKind::Enum(ast::EnumDef{ref variants, ..}, ..) => { + for variant in variants { + match (&variant.data, &variant.disr_expr) { + (ast::VariantData::Unit(..), _) => {}, + (_, Some(disr_expr)) => + gate_feature_post!( + &self, + arbitrary_enum_discriminant, + disr_expr.value.span, + "discriminants on non-unit variants are experimental"), + _ => {}, + } + } + + let has_feature = self.context.features.arbitrary_enum_discriminant; + if !has_feature && !i.span.allows_unstable(sym::arbitrary_enum_discriminant) { + Parser::maybe_report_invalid_custom_discriminants( + self.context.parse_sess, + &variants, + ); + } + } + + ast::ItemKind::Impl(_, polarity, defaultness, ..) => { + if polarity == ast::ImplPolarity::Negative { + gate_feature_post!(&self, optin_builtin_traits, + i.span, + "negative trait bounds are not yet fully implemented; \ + use marker types for now"); + } + + if let ast::Defaultness::Default = defaultness { + gate_feature_post!(&self, specialization, + i.span, + "specialization is unstable"); + } + } + + ast::ItemKind::Trait(ast::IsAuto::Yes, ..) => { + gate_feature_post!(&self, optin_builtin_traits, + i.span, + "auto traits are experimental and possibly buggy"); + } + + ast::ItemKind::TraitAlias(..) => { + gate_feature_post!( + &self, + trait_alias, + i.span, + "trait aliases are experimental" + ); + } + + ast::ItemKind::MacroDef(ast::MacroDef { legacy: false, .. }) => { + let msg = "`macro` is experimental"; + gate_feature_post!(&self, decl_macro, i.span, msg); + } + + ast::ItemKind::OpaqueTy(..) => { + gate_feature_post!( + &self, + type_alias_impl_trait, + i.span, + "`impl Trait` in type aliases is unstable" + ); + } + + _ => {} + } + + visit::walk_item(self, i); + } + + fn visit_foreign_item(&mut self, i: &'a ast::ForeignItem) { + match i.node { + ast::ForeignItemKind::Fn(..) | + ast::ForeignItemKind::Static(..) => { + let link_name = attr::first_attr_value_str_by_name(&i.attrs, sym::link_name); + let links_to_llvm = match link_name { + Some(val) => val.as_str().starts_with("llvm."), + _ => false + }; + if links_to_llvm { + gate_feature_post!(&self, link_llvm_intrinsics, i.span, + "linking to LLVM intrinsics is experimental"); + } + } + ast::ForeignItemKind::Ty => { + gate_feature_post!(&self, extern_types, i.span, + "extern types are experimental"); + } + ast::ForeignItemKind::Macro(..) => {} + } + + visit::walk_foreign_item(self, i) + } + + fn visit_ty(&mut self, ty: &'a ast::Ty) { + match ty.node { + ast::TyKind::BareFn(ref bare_fn_ty) => { + self.check_abi(bare_fn_ty.abi, ty.span); + } + ast::TyKind::Never => { + gate_feature_post!(&self, never_type, ty.span, + "The `!` type is experimental"); + } + _ => {} + } + visit::walk_ty(self, ty) + } + + fn visit_fn_ret_ty(&mut self, ret_ty: &'a ast::FunctionRetTy) { + if let ast::FunctionRetTy::Ty(ref output_ty) = *ret_ty { + if let ast::TyKind::Never = output_ty.node { + // Do nothing. + } else { + self.visit_ty(output_ty) + } + } + } + + fn visit_expr(&mut self, e: &'a ast::Expr) { + match e.node { + ast::ExprKind::Box(_) => { + gate_feature_post!(&self, box_syntax, e.span, EXPLAIN_BOX_SYNTAX); + } + ast::ExprKind::Type(..) => { + // To avoid noise about type ascription in common syntax errors, only emit if it + // is the *only* error. + if self.context.parse_sess.span_diagnostic.err_count() == 0 { + gate_feature_post!(&self, type_ascription, e.span, + "type ascription is experimental"); + } + } + ast::ExprKind::TryBlock(_) => { + gate_feature_post!(&self, try_blocks, e.span, "`try` expression is experimental"); + } + ast::ExprKind::Block(_, opt_label) => { + if let Some(label) = opt_label { + gate_feature_post!(&self, label_break_value, label.ident.span, + "labels on blocks are unstable"); + } + } + _ => {} + } + visit::walk_expr(self, e) + } + + fn visit_arm(&mut self, arm: &'a ast::Arm) { + visit::walk_arm(self, arm) + } + + fn visit_pat(&mut self, pattern: &'a ast::Pat) { + match &pattern.node { + PatKind::Slice(pats) => { + for pat in &*pats { + let span = pat.span; + let inner_pat = match &pat.node { + PatKind::Ident(.., Some(pat)) => pat, + _ => pat, + }; + if inner_pat.is_rest() { + gate_feature_post!( + &self, + slice_patterns, + span, + "subslice patterns are unstable" + ); + } + } + } + PatKind::Box(..) => { + gate_feature_post!(&self, box_patterns, + pattern.span, + "box pattern syntax is experimental"); + } + PatKind::Range(_, _, Spanned { node: RangeEnd::Excluded, .. }) => { + gate_feature_post!(&self, exclusive_range_pattern, pattern.span, + "exclusive range pattern syntax is experimental"); + } + _ => {} + } + visit::walk_pat(self, pattern) + } + + fn visit_fn(&mut self, + fn_kind: FnKind<'a>, + fn_decl: &'a ast::FnDecl, + span: Span, + _node_id: NodeId) { + if let Some(header) = fn_kind.header() { + // Stability of const fn methods are covered in + // `visit_trait_item` and `visit_impl_item` below; this is + // because default methods don't pass through this point. + self.check_abi(header.abi, span); + } + + if fn_decl.c_variadic { + gate_feature_post!(&self, c_variadic, span, "C-variadic functions are unstable"); + } + + visit::walk_fn(self, fn_kind, fn_decl, span) + } + + fn visit_generic_param(&mut self, param: &'a GenericParam) { + match param.kind { + GenericParamKind::Const { .. } => + gate_feature_post!(&self, const_generics, param.ident.span, + "const generics are unstable"), + _ => {} + } + visit::walk_generic_param(self, param) + } + + fn visit_assoc_ty_constraint(&mut self, constraint: &'a AssocTyConstraint) { + match constraint.kind { + AssocTyConstraintKind::Bound { .. } => + gate_feature_post!(&self, associated_type_bounds, constraint.span, + "associated type bounds are unstable"), + _ => {} + } + visit::walk_assoc_ty_constraint(self, constraint) + } + + fn visit_trait_item(&mut self, ti: &'a ast::TraitItem) { + match ti.node { + ast::TraitItemKind::Method(ref sig, ref block) => { + if block.is_none() { + self.check_abi(sig.header.abi, ti.span); + } + if sig.decl.c_variadic { + gate_feature_post!(&self, c_variadic, ti.span, + "C-variadic functions are unstable"); + } + if sig.header.constness.node == ast::Constness::Const { + gate_feature_post!(&self, const_fn, ti.span, "const fn is unstable"); + } + } + ast::TraitItemKind::Type(_, ref default) => { + // We use three if statements instead of something like match guards so that all + // of these errors can be emitted if all cases apply. + if default.is_some() { + gate_feature_post!(&self, associated_type_defaults, ti.span, + "associated type defaults are unstable"); + } + if !ti.generics.params.is_empty() { + gate_feature_post!(&self, generic_associated_types, ti.span, + "generic associated types are unstable"); + } + if !ti.generics.where_clause.predicates.is_empty() { + gate_feature_post!(&self, generic_associated_types, ti.span, + "where clauses on associated types are unstable"); + } + } + _ => {} + } + visit::walk_trait_item(self, ti) + } + + fn visit_impl_item(&mut self, ii: &'a ast::ImplItem) { + if ii.defaultness == ast::Defaultness::Default { + gate_feature_post!(&self, specialization, + ii.span, + "specialization is unstable"); + } + + match ii.node { + ast::ImplItemKind::Method(..) => {} + ast::ImplItemKind::OpaqueTy(..) => { + gate_feature_post!( + &self, + type_alias_impl_trait, + ii.span, + "`impl Trait` in type aliases is unstable" + ); + } + ast::ImplItemKind::TyAlias(_) => { + if !ii.generics.params.is_empty() { + gate_feature_post!(&self, generic_associated_types, ii.span, + "generic associated types are unstable"); + } + if !ii.generics.where_clause.predicates.is_empty() { + gate_feature_post!(&self, generic_associated_types, ii.span, + "where clauses on associated types are unstable"); + } + } + _ => {} + } + visit::walk_impl_item(self, ii) + } + + fn visit_vis(&mut self, vis: &'a ast::Visibility) { + if let ast::VisibilityKind::Crate(ast::CrateSugar::JustCrate) = vis.node { + gate_feature_post!(&self, crate_visibility_modifier, vis.span, + "`crate` visibility modifier is experimental"); + } + visit::walk_vis(self, vis) + } +} + +pub fn get_features(span_handler: &Handler, krate_attrs: &[ast::Attribute], + crate_edition: Edition, allow_features: &Option<Vec<String>>) -> Features { + fn feature_removed(span_handler: &Handler, span: Span, reason: Option<&str>) { + let mut err = struct_span_err!(span_handler, span, E0557, "feature has been removed"); + if let Some(reason) = reason { + err.span_note(span, reason); + } else { + err.span_label(span, "feature has been removed"); + } + err.emit(); + } + + let mut features = Features::new(); + let mut edition_enabled_features = FxHashMap::default(); + + for &edition in ALL_EDITIONS { + if edition <= crate_edition { + // The `crate_edition` implies its respective umbrella feature-gate + // (i.e., `#![feature(rust_20XX_preview)]` isn't needed on edition 20XX). + edition_enabled_features.insert(edition.feature_name(), edition); + } + } + + for &(name, .., f_edition, set) in ACTIVE_FEATURES { + if let Some(f_edition) = f_edition { + if f_edition <= crate_edition { + set(&mut features, DUMMY_SP); + edition_enabled_features.insert(name, crate_edition); + } + } + } + + // Process the edition umbrella feature-gates first, to ensure + // `edition_enabled_features` is completed before it's queried. + for attr in krate_attrs { + if !attr.check_name(sym::feature) { + continue + } + + let list = match attr.meta_item_list() { + Some(list) => list, + None => continue, + }; + + for mi in list { + if !mi.is_word() { + continue; + } + + let name = mi.name_or_empty(); + + if let Some(edition) = ALL_EDITIONS.iter().find(|e| name == e.feature_name()) { + if *edition <= crate_edition { + continue; + } + + for &(name, .., f_edition, set) in ACTIVE_FEATURES { + if let Some(f_edition) = f_edition { + if f_edition <= *edition { + // FIXME(Manishearth) there is currently no way to set + // lib features by edition + set(&mut features, DUMMY_SP); + edition_enabled_features.insert(name, *edition); + } + } + } + } + } + } + + for attr in krate_attrs { + if !attr.check_name(sym::feature) { + continue + } + + let list = match attr.meta_item_list() { + Some(list) => list, + None => continue, + }; + + let bad_input = |span| { + struct_span_err!(span_handler, span, E0556, "malformed `feature` attribute input") + }; + + for mi in list { + let name = match mi.ident() { + Some(ident) if mi.is_word() => ident.name, + Some(ident) => { + bad_input(mi.span()).span_suggestion( + mi.span(), + "expected just one word", + format!("{}", ident.name), + Applicability::MaybeIncorrect, + ).emit(); + continue + } + None => { + bad_input(mi.span()).span_label(mi.span(), "expected just one word").emit(); + continue + } + }; + + if let Some(edition) = edition_enabled_features.get(&name) { + struct_span_warn!( + span_handler, + mi.span(), + E0705, + "the feature `{}` is included in the Rust {} edition", + name, + edition, + ).emit(); + continue; + } + + if ALL_EDITIONS.iter().any(|e| name == e.feature_name()) { + // Handled in the separate loop above. + continue; + } + + let removed = REMOVED_FEATURES.iter().find(|f| name == f.0); + let stable_removed = STABLE_REMOVED_FEATURES.iter().find(|f| name == f.0); + if let Some((.., reason)) = removed.or(stable_removed) { + feature_removed(span_handler, mi.span(), *reason); + continue; + } + + if let Some((_, since, ..)) = ACCEPTED_FEATURES.iter().find(|f| name == f.0) { + let since = Some(Symbol::intern(since)); + features.declared_lang_features.push((name, mi.span(), since)); + continue; + } + + if let Some(allowed) = allow_features.as_ref() { + if allowed.iter().find(|f| *f == name.as_str()).is_none() { + span_err!(span_handler, mi.span(), E0725, + "the feature `{}` is not in the list of allowed features", + name); + continue; + } + } + + if let Some((.., set)) = ACTIVE_FEATURES.iter().find(|f| name == f.0) { + set(&mut features, mi.span()); + features.declared_lang_features.push((name, mi.span(), None)); + continue; + } + + features.declared_lib_features.push((name, mi.span())); + } + } + + features +} + +pub fn check_crate(krate: &ast::Crate, + sess: &ParseSess, + features: &Features, + plugin_attributes: &[(Symbol, AttributeType)], + unstable: UnstableFeatures) { + maybe_stage_features(&sess.span_diagnostic, krate, unstable); + let ctx = Context { + features, + parse_sess: sess, + plugin_attributes, + }; + + macro_rules! gate_all { + ($gate:ident, $msg:literal) => { gate_all!($gate, $gate, $msg); }; + ($spans:ident, $gate:ident, $msg:literal) => { + for span in &*sess.gated_spans.$spans.borrow() { + gate_feature!(&ctx, $gate, *span, $msg); + } + } + } + + gate_all!(param_attrs, "attributes on function parameters are unstable"); + gate_all!(let_chains, "`let` expressions in this position are experimental"); + gate_all!(async_closure, "async closures are unstable"); + gate_all!(yields, generators, "yield syntax is experimental"); + gate_all!(or_patterns, "or-patterns syntax is experimental"); + + let visitor = &mut PostExpansionVisitor { + context: &ctx, + builtin_attributes: &*BUILTIN_ATTRIBUTE_MAP, + }; + visit::walk_crate(visitor, krate); +} + +#[derive(Clone, Copy, Hash)] +pub enum UnstableFeatures { + /// Hard errors for unstable features are active, as on beta/stable channels. + Disallow, + /// Allow features to be activated, as on nightly. + Allow, + /// Errors are bypassed for bootstrapping. This is required any time + /// during the build that feature-related lints are set to warn or above + /// because the build turns on warnings-as-errors and uses lots of unstable + /// features. As a result, this is always required for building Rust itself. + Cheat +} + +impl UnstableFeatures { + pub fn from_environment() -> UnstableFeatures { + // Whether this is a feature-staged build, i.e., on the beta or stable channel + let disable_unstable_features = option_env!("CFG_DISABLE_UNSTABLE_FEATURES").is_some(); + // Whether we should enable unstable features for bootstrapping + let bootstrap = env::var("RUSTC_BOOTSTRAP").is_ok(); + match (disable_unstable_features, bootstrap) { + (_, true) => UnstableFeatures::Cheat, + (true, _) => UnstableFeatures::Disallow, + (false, _) => UnstableFeatures::Allow + } + } + + pub fn is_nightly_build(&self) -> bool { + match *self { + UnstableFeatures::Allow | UnstableFeatures::Cheat => true, + _ => false, + } + } +} + +fn maybe_stage_features(span_handler: &Handler, krate: &ast::Crate, unstable: UnstableFeatures) { + let allow_features = match unstable { + UnstableFeatures::Allow => true, + UnstableFeatures::Disallow => false, + UnstableFeatures::Cheat => true + }; + if !allow_features { + for attr in &krate.attrs { + if attr.check_name(sym::feature) { + let release_channel = option_env!("CFG_RELEASE_CHANNEL").unwrap_or("(unknown)"); + span_err!(span_handler, attr.span, E0554, + "`#![feature]` may not be used on the {} release channel", + release_channel); + } + } + } +} diff --git a/src/libsyntax/feature_gate/mod.rs b/src/libsyntax/feature_gate/mod.rs new file mode 100644 index 00000000000..97793bca1f5 --- /dev/null +++ b/src/libsyntax/feature_gate/mod.rs @@ -0,0 +1,31 @@ +//! # Feature gating +//! +//! This module implements the gating necessary for preventing certain compiler +//! features from being used by default. This module will crawl a pre-expanded +//! AST to ensure that there are no features which are used that are not +//! enabled. +//! +//! Features are enabled in programs via the crate-level attributes of +//! `#![feature(...)]` with a comma-separated list of features. +//! +//! For the purpose of future feature-tracking, once code for detection of feature +//! gate usage is added, *do not remove it again* even once the feature +//! becomes stable. + +mod accepted; +mod removed; +mod active; +mod builtin_attrs; +mod check; + +pub use active::{Features, INCOMPLETE_FEATURES}; +pub use builtin_attrs::{ + AttributeGate, AttributeType, GatedCfg, + BuiltinAttribute, BUILTIN_ATTRIBUTES, BUILTIN_ATTRIBUTE_MAP, + deprecated_attributes, is_builtin_attr, is_builtin_attr_name, +}; +pub use check::{ + check_attribute, check_crate, get_features, feature_err, emit_feature_err, + Stability, GateIssue, UnstableFeatures, + EXPLAIN_STMT_ATTR_SYNTAX, EXPLAIN_UNSIZED_TUPLE_COERCION, +}; diff --git a/src/libsyntax/feature_gate/removed.rs b/src/libsyntax/feature_gate/removed.rs new file mode 100644 index 00000000000..6ebfeb29f67 --- /dev/null +++ b/src/libsyntax/feature_gate/removed.rs @@ -0,0 +1,82 @@ +//! List of the removed feature gates. + +use crate::symbol::{Symbol, sym}; + +macro_rules! declare_features { + ($((removed, $feature: ident, $ver: expr, $issue: expr, None, $reason: expr),)+) => { + /// Represents unstable features which have since been removed (it was once Active) + pub const REMOVED_FEATURES: &[(Symbol, &str, Option<u32>, Option<&str>)] = &[ + $((sym::$feature, $ver, $issue, $reason)),+ + ]; + }; + + ($((stable_removed, $feature: ident, $ver: expr, $issue: expr, None),)+) => { + /// Represents stable features which have since been removed (it was once Accepted) + pub const STABLE_REMOVED_FEATURES: &[(Symbol, &str, Option<u32>, Option<&str>)] = &[ + $((sym::$feature, $ver, $issue, None)),+ + ]; + }; +} + +declare_features! ( + // ------------------------------------------------------------------------- + // feature-group-start: removed features + // ------------------------------------------------------------------------- + + (removed, import_shadowing, "1.0.0", None, None, None), + (removed, managed_boxes, "1.0.0", None, None, None), + // Allows use of unary negate on unsigned integers, e.g., -e for e: u8 + (removed, negate_unsigned, "1.0.0", Some(29645), None, None), + (removed, reflect, "1.0.0", Some(27749), None, None), + // A way to temporarily opt out of opt in copy. This will *never* be accepted. + (removed, opt_out_copy, "1.0.0", None, None, None), + (removed, quad_precision_float, "1.0.0", None, None, None), + (removed, struct_inherit, "1.0.0", None, None, None), + (removed, test_removed_feature, "1.0.0", None, None, None), + (removed, visible_private_types, "1.0.0", None, None, None), + (removed, unsafe_no_drop_flag, "1.0.0", None, None, None), + // Allows using items which are missing stability attributes + (removed, unmarked_api, "1.0.0", None, None, None), + (removed, allocator, "1.0.0", None, None, None), + (removed, simd, "1.0.0", Some(27731), None, + Some("removed in favor of `#[repr(simd)]`")), + (removed, advanced_slice_patterns, "1.0.0", Some(62254), None, + Some("merged into `#![feature(slice_patterns)]`")), + (removed, macro_reexport, "1.0.0", Some(29638), None, + Some("subsumed by `pub use`")), + (removed, pushpop_unsafe, "1.2.0", None, None, None), + (removed, needs_allocator, "1.4.0", Some(27389), None, + Some("subsumed by `#![feature(allocator_internals)]`")), + (removed, proc_macro_mod, "1.27.0", Some(54727), None, + Some("subsumed by `#![feature(proc_macro_hygiene)]`")), + (removed, proc_macro_expr, "1.27.0", Some(54727), None, + Some("subsumed by `#![feature(proc_macro_hygiene)]`")), + (removed, proc_macro_non_items, "1.27.0", Some(54727), None, + Some("subsumed by `#![feature(proc_macro_hygiene)]`")), + (removed, proc_macro_gen, "1.27.0", Some(54727), None, + Some("subsumed by `#![feature(proc_macro_hygiene)]`")), + (removed, panic_implementation, "1.28.0", Some(44489), None, + Some("subsumed by `#[panic_handler]`")), + // Allows the use of `#[derive(Anything)]` as sugar for `#[derive_Anything]`. + (removed, custom_derive, "1.32.0", Some(29644), None, + Some("subsumed by `#[proc_macro_derive]`")), + // Paths of the form: `extern::foo::bar` + (removed, extern_in_paths, "1.33.0", Some(55600), None, + Some("subsumed by `::foo::bar` paths")), + (removed, quote, "1.33.0", Some(29601), None, None), + // Allows using `#[unsafe_destructor_blind_to_params]` (RFC 1238). + (removed, dropck_parametricity, "1.38.0", Some(28498), None, None), + (removed, await_macro, "1.38.0", Some(50547), None, + Some("subsumed by `.await` syntax")), + // Allows defining `existential type`s. + (removed, existential_type, "1.38.0", Some(63063), None, + Some("removed in favor of `#![feature(type_alias_impl_trait)]`")), + + // ------------------------------------------------------------------------- + // feature-group-end: removed features + // ------------------------------------------------------------------------- +); + +declare_features! ( + (stable_removed, no_stack_check, "1.0.0", None, None), +); diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs index 8ac48d8d74a..1741932c1b8 100644 --- a/src/libsyntax/lib.rs +++ b/src/libsyntax/lib.rs @@ -124,7 +124,6 @@ pub mod diagnostics { #[macro_use] pub mod macros; pub mod plugin; - pub mod metadata; } // N.B., this module needs to be declared first so diagnostics are diff --git a/src/libsyntax/parse/attr.rs b/src/libsyntax/parse/attr.rs index a42da112360..c703058e795 100644 --- a/src/libsyntax/parse/attr.rs +++ b/src/libsyntax/parse/attr.rs @@ -21,9 +21,8 @@ const DEFAULT_UNEXPECTED_INNER_ATTR_ERR_MSG: &str = "an inner attribute is not \ impl<'a> Parser<'a> { crate fn parse_arg_attributes(&mut self) -> PResult<'a, Vec<ast::Attribute>> { let attrs = self.parse_outer_attributes()?; - attrs.iter().for_each(|a| - self.sess.param_attr_spans.borrow_mut().push(a.span) - ); + self.sess.gated_spans.param_attrs.borrow_mut() + .extend(attrs.iter().map(|a| a.span)); Ok(attrs) } diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs index b1f3612a839..b1af4806e2d 100644 --- a/src/libsyntax/parse/mod.rs +++ b/src/libsyntax/parse/mod.rs @@ -39,6 +39,22 @@ crate mod unescape_error_reporting; pub type PResult<'a, T> = Result<T, DiagnosticBuilder<'a>>; +/// Collected spans during parsing for places where a certain feature was +/// used and should be feature gated accordingly in `check_crate`. +#[derive(Default)] +pub struct GatedSpans { + /// Spans collected for gating `param_attrs`, e.g. `fn foo(#[attr] x: u8) {}`. + pub param_attrs: Lock<Vec<Span>>, + /// Spans collected for gating `let_chains`, e.g. `if a && let b = c {}`. + pub let_chains: Lock<Vec<Span>>, + /// Spans collected for gating `async_closure`, e.g. `async || ..`. + pub async_closure: Lock<Vec<Span>>, + /// Spans collected for gating `yield e?` expressions (`generators` gate). + pub yields: Lock<Vec<Span>>, + /// Spans collected for gating `or_patterns`, e.g. `Some(Foo | Bar)`. + pub or_patterns: Lock<Vec<Span>>, +} + /// Info about a parsing session. pub struct ParseSess { pub span_diagnostic: Handler, @@ -58,16 +74,8 @@ pub struct ParseSess { /// operation token that followed it, but that the parser cannot identify without further /// analysis. pub ambiguous_block_expr_parse: Lock<FxHashMap<Span, Span>>, - pub param_attr_spans: Lock<Vec<Span>>, - // Places where `let` exprs were used and should be feature gated according to `let_chains`. - pub let_chains_spans: Lock<Vec<Span>>, - // Places where `async || ..` exprs were used and should be feature gated. - pub async_closure_spans: Lock<Vec<Span>>, - // Places where `yield e?` exprs were used and should be feature gated. - pub yield_spans: Lock<Vec<Span>>, pub injected_crate_name: Once<Symbol>, - // Places where or-patterns e.g. `Some(Foo | Bar)` were used and should be feature gated. - pub or_pattern_spans: Lock<Vec<Span>>, + pub gated_spans: GatedSpans, } impl ParseSess { @@ -93,12 +101,8 @@ impl ParseSess { buffered_lints: Lock::new(vec![]), edition: ExpnId::root().expn_data().edition, ambiguous_block_expr_parse: Lock::new(FxHashMap::default()), - param_attr_spans: Lock::new(Vec::new()), - let_chains_spans: Lock::new(Vec::new()), - async_closure_spans: Lock::new(Vec::new()), - yield_spans: Lock::new(Vec::new()), injected_crate_name: Once::new(), - or_pattern_spans: Lock::new(Vec::new()), + gated_spans: GatedSpans::default(), } } diff --git a/src/libsyntax/parse/parser/expr.rs b/src/libsyntax/parse/parser/expr.rs index ccc6bd15067..5da9b75d53b 100644 --- a/src/libsyntax/parse/parser/expr.rs +++ b/src/libsyntax/parse/parser/expr.rs @@ -999,7 +999,7 @@ impl<'a> Parser<'a> { } let span = lo.to(hi); - self.sess.yield_spans.borrow_mut().push(span); + self.sess.gated_spans.yields.borrow_mut().push(span); } else if self.eat_keyword(kw::Let) { return self.parse_let_expr(attrs); } else if is_span_rust_2018 && self.eat_keyword(kw::Await) { @@ -1111,7 +1111,7 @@ impl<'a> Parser<'a> { }; if asyncness.is_async() { // Feature gate `async ||` closures. - self.sess.async_closure_spans.borrow_mut().push(self.prev_span); + self.sess.gated_spans.async_closure.borrow_mut().push(self.prev_span); } let capture_clause = self.parse_capture_clause(); @@ -1234,7 +1234,7 @@ impl<'a> Parser<'a> { if let ExprKind::Let(..) = cond.node { // Remove the last feature gating of a `let` expression since it's stable. - let last = self.sess.let_chains_spans.borrow_mut().pop(); + let last = self.sess.gated_spans.let_chains.borrow_mut().pop(); debug_assert_eq!(cond.span, last.unwrap()); } @@ -1252,7 +1252,7 @@ impl<'a> Parser<'a> { |this| this.parse_assoc_expr_with(1 + prec_let_scrutinee_needs_par(), None.into()) )?; let span = lo.to(expr.span); - self.sess.let_chains_spans.borrow_mut().push(span); + self.sess.gated_spans.let_chains.borrow_mut().push(span); Ok(self.mk_expr(span, ExprKind::Let(pats, expr), attrs)) } diff --git a/src/libsyntax/parse/parser/item.rs b/src/libsyntax/parse/parser/item.rs index 72819c99660..03d7e922123 100644 --- a/src/libsyntax/parse/parser/item.rs +++ b/src/libsyntax/parse/parser/item.rs @@ -825,6 +825,7 @@ impl<'a> Parser<'a> { self.is_keyword_ahead(1, &[ kw::Impl, kw::Const, + kw::Async, kw::Fn, kw::Unsafe, kw::Extern, diff --git a/src/libsyntax/parse/parser/pat.rs b/src/libsyntax/parse/parser/pat.rs index fd458aec743..8cfa6abbe62 100644 --- a/src/libsyntax/parse/parser/pat.rs +++ b/src/libsyntax/parse/parser/pat.rs @@ -123,7 +123,7 @@ impl<'a> Parser<'a> { let or_pattern_span = lo.to(self.prev_span); - self.sess.or_pattern_spans.borrow_mut().push(or_pattern_span); + self.sess.gated_spans.or_patterns.borrow_mut().push(or_pattern_span); Ok(self.mk_pat(or_pattern_span, PatKind::Or(pats))) } diff --git a/src/libsyntax/tokenstream.rs b/src/libsyntax/tokenstream.rs index 09a1b93c7bb..0d9f3769ce9 100644 --- a/src/libsyntax/tokenstream.rs +++ b/src/libsyntax/tokenstream.rs @@ -19,7 +19,7 @@ use crate::parse::Directory; use crate::parse::token::{self, DelimToken, Token, TokenKind}; use crate::print::pprust; -use syntax_pos::{BytePos, ExpnId, Span, DUMMY_SP}; +use syntax_pos::{BytePos, Span, DUMMY_SP}; #[cfg(target_arch = "x86_64")] use rustc_data_structures::static_assert_size; use rustc_data_structures::sync::Lrc; @@ -547,11 +547,4 @@ impl DelimSpan { pub fn entire(self) -> Span { self.open.with_hi(self.close.hi()) } - - pub fn apply_mark(self, expn_id: ExpnId) -> Self { - DelimSpan { - open: self.open.apply_mark(expn_id), - close: self.close.apply_mark(expn_id), - } - } } diff --git a/src/libsyntax_ext/asm.rs b/src/libsyntax_ext/asm.rs index 644a44f1989..28f907441d8 100644 --- a/src/libsyntax_ext/asm.rs +++ b/src/libsyntax_ext/asm.rs @@ -63,7 +63,7 @@ pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt<'_>, MacEager::expr(P(ast::Expr { id: ast::DUMMY_NODE_ID, node: ast::ExprKind::InlineAsm(P(inline_asm)), - span: sp.with_ctxt(cx.backtrace()), + span: cx.with_legacy_ctxt(sp), attrs: ThinVec::new(), })) } diff --git a/src/libsyntax_ext/assert.rs b/src/libsyntax_ext/assert.rs index 6301283460a..84583d0e5ec 100644 --- a/src/libsyntax_ext/assert.rs +++ b/src/libsyntax_ext/assert.rs @@ -23,7 +23,7 @@ pub fn expand_assert<'cx>( } }; - let sp = sp.apply_mark(cx.current_expansion.id); + let sp = cx.with_legacy_ctxt(sp); let panic_call = Mac { path: Path::from_ident(Ident::new(sym::panic, sp)), tts: custom_message.unwrap_or_else(|| { diff --git a/src/libsyntax_ext/cfg.rs b/src/libsyntax_ext/cfg.rs index 0e52c1af908..21cee8ae1cb 100644 --- a/src/libsyntax_ext/cfg.rs +++ b/src/libsyntax_ext/cfg.rs @@ -16,7 +16,7 @@ pub fn expand_cfg( sp: Span, tts: &[tokenstream::TokenTree], ) -> Box<dyn base::MacResult + 'static> { - let sp = sp.apply_mark(cx.current_expansion.id); + let sp = cx.with_legacy_ctxt(sp); match parse_cfg(cx, sp, tts) { Ok(cfg) => { diff --git a/src/libsyntax_ext/concat.rs b/src/libsyntax_ext/concat.rs index 4cd17531a45..ffa5154ca0c 100644 --- a/src/libsyntax_ext/concat.rs +++ b/src/libsyntax_ext/concat.rs @@ -59,6 +59,6 @@ pub fn expand_syntax_ext( } else if has_errors { return DummyResult::any(sp); } - let sp = sp.apply_mark(cx.current_expansion.id); + let sp = cx.with_legacy_ctxt(sp); base::MacEager::expr(cx.expr_str(sp, Symbol::intern(&accumulator))) } diff --git a/src/libsyntax_ext/concat_idents.rs b/src/libsyntax_ext/concat_idents.rs index 8184fc44267..96677072d1b 100644 --- a/src/libsyntax_ext/concat_idents.rs +++ b/src/libsyntax_ext/concat_idents.rs @@ -39,7 +39,7 @@ pub fn expand_syntax_ext<'cx>(cx: &'cx mut ExtCtxt<'_>, } } - let ident = ast::Ident::new(Symbol::intern(&res_str), sp.apply_mark(cx.current_expansion.id)); + let ident = ast::Ident::new(Symbol::intern(&res_str), cx.with_legacy_ctxt(sp)); struct ConcatIdentsResult { ident: ast::Ident } diff --git a/src/libsyntax_ext/deriving/clone.rs b/src/libsyntax_ext/deriving/clone.rs index d030ea4a56e..4dd0ecfebef 100644 --- a/src/libsyntax_ext/deriving/clone.rs +++ b/src/libsyntax_ext/deriving/clone.rs @@ -112,7 +112,7 @@ fn cs_clone_shallow(name: &str, ty: P<ast::Ty>, span: Span, helper_name: &str) { // Generate statement `let _: helper_name<ty>;`, // set the expn ID so we can use the unstable struct. - let span = span.with_ctxt(cx.backtrace()); + let span = cx.with_def_site_ctxt(span); let assert_path = cx.path_all(span, true, cx.std_path(&[sym::clone, Symbol::intern(helper_name)]), vec![GenericArg::Type(ty)], vec![]); diff --git a/src/libsyntax_ext/deriving/cmp/eq.rs b/src/libsyntax_ext/deriving/cmp/eq.rs index 54027c600b4..32ab47969ad 100644 --- a/src/libsyntax_ext/deriving/cmp/eq.rs +++ b/src/libsyntax_ext/deriving/cmp/eq.rs @@ -53,7 +53,7 @@ fn cs_total_eq_assert(cx: &mut ExtCtxt<'_>, ty: P<ast::Ty>, span: Span, helper_name: &str) { // Generate statement `let _: helper_name<ty>;`, // set the expn ID so we can use the unstable struct. - let span = span.with_ctxt(cx.backtrace()); + let span = cx.with_def_site_ctxt(span); let assert_path = cx.path_all(span, true, cx.std_path(&[sym::cmp, Symbol::intern(helper_name)]), vec![GenericArg::Type(ty)], vec![]); diff --git a/src/libsyntax_ext/deriving/debug.rs b/src/libsyntax_ext/deriving/debug.rs index 44153541048..781645a574e 100644 --- a/src/libsyntax_ext/deriving/debug.rs +++ b/src/libsyntax_ext/deriving/debug.rs @@ -60,7 +60,7 @@ fn show_substructure(cx: &mut ExtCtxt<'_>, span: Span, substr: &Substructure<'_> }; // We want to make sure we have the ctxt set so that we can use unstable methods - let span = span.with_ctxt(cx.backtrace()); + let span = cx.with_def_site_ctxt(span); let name = cx.expr_lit(span, ast::LitKind::Str(ident.name, ast::StrStyle::Cooked)); let builder = Ident::from_str_and_span("debug_trait_builder", span); let builder_expr = cx.expr_ident(span, builder.clone()); diff --git a/src/libsyntax_ext/deriving/generic/ty.rs b/src/libsyntax_ext/deriving/generic/ty.rs index 7fcf036fc81..cb1c7b21fee 100644 --- a/src/libsyntax_ext/deriving/generic/ty.rs +++ b/src/libsyntax_ext/deriving/generic/ty.rs @@ -85,7 +85,7 @@ impl<'a> Path<'a> { PathKind::Global => cx.path_all(span, true, idents, params, Vec::new()), PathKind::Local => cx.path_all(span, false, idents, params, Vec::new()), PathKind::Std => { - let def_site = DUMMY_SP.apply_mark(cx.current_expansion.id); + let def_site = cx.with_def_site_ctxt(DUMMY_SP); idents.insert(0, Ident::new(kw::DollarCrate, def_site)); cx.path_all(span, false, idents, params, Vec::new()) } diff --git a/src/libsyntax_ext/deriving/mod.rs b/src/libsyntax_ext/deriving/mod.rs index da68eea0c50..60b6eba7a4b 100644 --- a/src/libsyntax_ext/deriving/mod.rs +++ b/src/libsyntax_ext/deriving/mod.rs @@ -48,6 +48,9 @@ impl MultiItemModifier for BuiltinDerive { meta_item: &MetaItem, item: Annotatable) -> Vec<Annotatable> { + // FIXME: Built-in derives often forget to give spans contexts, + // so we are doing it here in a centralized way. + let span = ecx.with_def_site_ctxt(span); let mut items = Vec::new(); (self.0)(ecx, span, meta_item, &item, &mut |a| items.push(a)); items @@ -60,7 +63,7 @@ fn call_intrinsic(cx: &ExtCtxt<'_>, intrinsic: &str, args: Vec<P<ast::Expr>>) -> P<ast::Expr> { - let span = span.with_ctxt(cx.backtrace()); + let span = cx.with_def_site_ctxt(span); let path = cx.std_path(&[sym::intrinsics, Symbol::intern(intrinsic)]); let call = cx.expr_call_global(span, path, args); diff --git a/src/libsyntax_ext/env.rs b/src/libsyntax_ext/env.rs index 9834130fa23..6343d218de8 100644 --- a/src/libsyntax_ext/env.rs +++ b/src/libsyntax_ext/env.rs @@ -20,7 +20,7 @@ pub fn expand_option_env<'cx>(cx: &'cx mut ExtCtxt<'_>, Some(v) => v, }; - let sp = sp.apply_mark(cx.current_expansion.id); + let sp = cx.with_legacy_ctxt(sp); let e = match env::var(&*var.as_str()) { Err(..) => { let lt = cx.lifetime(sp, Ident::with_dummy_span(kw::StaticLifetime)); diff --git a/src/libsyntax_ext/format.rs b/src/libsyntax_ext/format.rs index 83764205a19..47394c02b41 100644 --- a/src/libsyntax_ext/format.rs +++ b/src/libsyntax_ext/format.rs @@ -12,7 +12,7 @@ use syntax::parse::token; use syntax::ptr::P; use syntax::symbol::{Symbol, sym}; use syntax::tokenstream; -use syntax_pos::{MultiSpan, Span, DUMMY_SP}; +use syntax_pos::{MultiSpan, Span}; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use std::borrow::Cow; @@ -666,8 +666,7 @@ impl<'a, 'b> Context<'a, 'b> { // passed to this function. for (i, e) in self.args.into_iter().enumerate() { let name = names_pos[i]; - let span = - DUMMY_SP.with_ctxt(e.span.ctxt().apply_mark(self.ecx.current_expansion.id)); + let span = self.ecx.with_def_site_ctxt(e.span); pats.push(self.ecx.pat_ident(span, name)); for ref arg_ty in self.arg_unique_types[i].iter() { locals.push(Context::format_arg(self.ecx, self.macsp, e.span, arg_ty, name)); @@ -745,7 +744,7 @@ impl<'a, 'b> Context<'a, 'b> { ty: &ArgumentType, arg: ast::Ident, ) -> P<ast::Expr> { - sp = sp.apply_mark(ecx.current_expansion.id); + sp = ecx.with_def_site_ctxt(sp); let arg = ecx.expr_ident(sp, arg); let trait_ = match *ty { Placeholder(ref tyname) => { @@ -798,7 +797,7 @@ fn expand_format_args_impl<'cx>( tts: &[tokenstream::TokenTree], nl: bool, ) -> Box<dyn base::MacResult + 'cx> { - sp = sp.apply_mark(ecx.current_expansion.id); + sp = ecx.with_def_site_ctxt(sp); match parse_args(ecx, sp, tts) { Ok((efmt, args, names)) => { MacEager::expr(expand_preparsed_format_args(ecx, sp, efmt, args, names, nl)) @@ -842,7 +841,7 @@ pub fn expand_preparsed_format_args( let arg_unique_types: Vec<_> = (0..args.len()).map(|_| Vec::new()).collect(); let mut macsp = ecx.call_site(); - macsp = macsp.with_ctxt(ecx.backtrace()); + macsp = ecx.with_def_site_ctxt(macsp); let msg = "format argument must be a string literal"; let fmt_sp = efmt.span; diff --git a/src/libsyntax_ext/global_allocator.rs b/src/libsyntax_ext/global_allocator.rs index d2121abe3b4..97b8087ad15 100644 --- a/src/libsyntax_ext/global_allocator.rs +++ b/src/libsyntax_ext/global_allocator.rs @@ -3,7 +3,6 @@ use syntax::ast::{self, Arg, Attribute, Expr, FnHeader, Generics, Ident}; use syntax::attr::check_builtin_macro_attribute; use syntax::ext::allocator::{AllocatorKind, AllocatorMethod, AllocatorTy, ALLOCATOR_METHODS}; use syntax::ext::base::{Annotatable, ExtCtxt}; -use syntax::ext::hygiene::SyntaxContext; use syntax::ptr::P; use syntax::symbol::{kw, sym, Symbol}; use syntax_pos::Span; @@ -29,7 +28,7 @@ pub fn expand( }; // Generate a bunch of new items using the AllocFnFactory - let span = item.span.with_ctxt(SyntaxContext::root().apply_mark(ecx.current_expansion.id)); + let span = ecx.with_legacy_ctxt(item.span); let f = AllocFnFactory { span, kind: AllocatorKind::Global, diff --git a/src/libsyntax_ext/global_asm.rs b/src/libsyntax_ext/global_asm.rs index 73ebeaec454..a8b61593db7 100644 --- a/src/libsyntax_ext/global_asm.rs +++ b/src/libsyntax_ext/global_asm.rs @@ -30,7 +30,7 @@ pub fn expand_global_asm<'cx>(cx: &'cx mut ExtCtxt<'_>, id: ast::DUMMY_NODE_ID, node: ast::ItemKind::GlobalAsm(P(global_asm)), vis: respan(sp.shrink_to_lo(), ast::VisibilityKind::Inherited), - span: sp.with_ctxt(cx.backtrace()), + span: cx.with_legacy_ctxt(sp), tokens: None, })]) } diff --git a/src/libsyntax_ext/test.rs b/src/libsyntax_ext/test.rs index 08582e714cc..5fd87d3a0e5 100644 --- a/src/libsyntax_ext/test.rs +++ b/src/libsyntax_ext/test.rs @@ -4,7 +4,6 @@ use syntax::ast; use syntax::attr::{self, check_builtin_macro_attribute}; use syntax::ext::base::*; -use syntax::ext::hygiene::SyntaxContext; use syntax::print::pprust; use syntax::source_map::respan; use syntax::symbol::{Symbol, sym}; @@ -29,7 +28,7 @@ pub fn expand_test_case( if !ecx.ecfg.should_test { return vec![]; } - let sp = attr_sp.with_ctxt(SyntaxContext::root().apply_mark(ecx.current_expansion.id)); + let sp = ecx.with_legacy_ctxt(attr_sp); let mut item = anno_item.expect_item(); item = item.map(|mut item| { item.vis = respan(item.vis.span, ast::VisibilityKind::Public); @@ -93,8 +92,7 @@ pub fn expand_test_or_bench( return vec![Annotatable::Item(item)]; } - let ctxt = SyntaxContext::root().apply_mark(cx.current_expansion.id); - let (sp, attr_sp) = (item.span.with_ctxt(ctxt), attr_sp.with_ctxt(ctxt)); + let (sp, attr_sp) = (cx.with_legacy_ctxt(item.span), cx.with_legacy_ctxt(attr_sp)); // Gensym "test" so we can extern crate without conflicting with any local names let test_id = cx.ident_of("test").gensym(); diff --git a/src/libsyntax_pos/hygiene.rs b/src/libsyntax_pos/hygiene.rs index ebfb0764fa2..733f6f04490 100644 --- a/src/libsyntax_pos/hygiene.rs +++ b/src/libsyntax_pos/hygiene.rs @@ -119,18 +119,6 @@ impl ExpnId { pub fn outer_expn_is_descendant_of(self, ctxt: SyntaxContext) -> bool { HygieneData::with(|data| data.is_descendant_of(self, data.outer_expn(ctxt))) } - - // Used for enabling some compatibility fallback in resolve. - #[inline] - pub fn looks_like_proc_macro_derive(self) -> bool { - HygieneData::with(|data| { - let expn_data = data.expn_data(self); - if let ExpnKind::Macro(MacroKind::Derive, _) = expn_data.kind { - return expn_data.default_transparency == Transparency::Opaque; - } - false - }) - } } #[derive(Debug)] @@ -195,24 +183,25 @@ impl HygieneData { self.syntax_context_data[ctxt.0 as usize].outer_expn } - fn outer_transparency(&self, ctxt: SyntaxContext) -> Transparency { - self.syntax_context_data[ctxt.0 as usize].outer_transparency + fn outer_mark(&self, ctxt: SyntaxContext) -> (ExpnId, Transparency) { + let data = &self.syntax_context_data[ctxt.0 as usize]; + (data.outer_expn, data.outer_transparency) } fn parent_ctxt(&self, ctxt: SyntaxContext) -> SyntaxContext { self.syntax_context_data[ctxt.0 as usize].parent } - fn remove_mark(&self, ctxt: &mut SyntaxContext) -> ExpnId { - let outer_expn = self.outer_expn(*ctxt); + fn remove_mark(&self, ctxt: &mut SyntaxContext) -> (ExpnId, Transparency) { + let outer_mark = self.outer_mark(*ctxt); *ctxt = self.parent_ctxt(*ctxt); - outer_expn + outer_mark } fn marks(&self, mut ctxt: SyntaxContext) -> Vec<(ExpnId, Transparency)> { let mut marks = Vec::new(); while ctxt != SyntaxContext::root() { - marks.push((self.outer_expn(ctxt), self.outer_transparency(ctxt))); + marks.push(self.outer_mark(ctxt)); ctxt = self.parent_ctxt(ctxt); } marks.reverse(); @@ -229,20 +218,14 @@ impl HygieneData { fn adjust(&self, ctxt: &mut SyntaxContext, expn_id: ExpnId) -> Option<ExpnId> { let mut scope = None; while !self.is_descendant_of(expn_id, self.outer_expn(*ctxt)) { - scope = Some(self.remove_mark(ctxt)); + scope = Some(self.remove_mark(ctxt).0); } scope } - fn apply_mark(&mut self, ctxt: SyntaxContext, expn_id: ExpnId) -> SyntaxContext { - assert_ne!(expn_id, ExpnId::root()); - self.apply_mark_with_transparency( - ctxt, expn_id, self.expn_data(expn_id).default_transparency - ) - } - - fn apply_mark_with_transparency(&mut self, ctxt: SyntaxContext, expn_id: ExpnId, - transparency: Transparency) -> SyntaxContext { + fn apply_mark( + &mut self, ctxt: SyntaxContext, expn_id: ExpnId, transparency: Transparency + ) -> SyntaxContext { assert_ne!(expn_id, ExpnId::root()); if transparency == Transparency::Opaque { return self.apply_mark_internal(ctxt, expn_id, transparency); @@ -376,15 +359,9 @@ impl SyntaxContext { SyntaxContext(raw) } - /// Extend a syntax context with a given expansion and default transparency for that expansion. - pub fn apply_mark(self, expn_id: ExpnId) -> SyntaxContext { - HygieneData::with(|data| data.apply_mark(self, expn_id)) - } - /// Extend a syntax context with a given expansion and transparency. - pub fn apply_mark_with_transparency(self, expn_id: ExpnId, transparency: Transparency) - -> SyntaxContext { - HygieneData::with(|data| data.apply_mark_with_transparency(self, expn_id, transparency)) + pub fn apply_mark(self, expn_id: ExpnId, transparency: Transparency) -> SyntaxContext { + HygieneData::with(|data| data.apply_mark(self, expn_id, transparency)) } /// Pulls a single mark off of the syntax context. This effectively moves the @@ -404,7 +381,7 @@ impl SyntaxContext { /// invocation of f that created g1. /// Returns the mark that was removed. pub fn remove_mark(&mut self) -> ExpnId { - HygieneData::with(|data| data.remove_mark(self)) + HygieneData::with(|data| data.remove_mark(self).0) } pub fn marks(self) -> Vec<(ExpnId, Transparency)> { @@ -477,8 +454,8 @@ impl SyntaxContext { let mut scope = None; let mut glob_ctxt = data.modern(glob_span.ctxt()); while !data.is_descendant_of(expn_id, data.outer_expn(glob_ctxt)) { - scope = Some(data.remove_mark(&mut glob_ctxt)); - if data.remove_mark(self) != scope.unwrap() { + scope = Some(data.remove_mark(&mut glob_ctxt).0); + if data.remove_mark(self).0 != scope.unwrap() { return None; } } @@ -509,9 +486,9 @@ impl SyntaxContext { marks.push(data.remove_mark(&mut glob_ctxt)); } - let scope = marks.last().cloned(); - while let Some(mark) = marks.pop() { - *self = data.apply_mark(*self, mark); + let scope = marks.last().map(|mark| mark.0); + while let Some((expn_id, transparency)) = marks.pop() { + *self = data.apply_mark(*self, expn_id, transparency); } Some(scope) }) @@ -547,13 +524,11 @@ impl SyntaxContext { HygieneData::with(|data| data.expn_data(data.outer_expn(self)).clone()) } - /// `ctxt.outer_expn_with_data()` is equivalent to but faster than - /// `{ let outer = ctxt.outer_expn(); (outer, outer.expn_data()) }`. #[inline] - pub fn outer_expn_with_data(self) -> (ExpnId, ExpnData) { + pub fn outer_mark_with_data(self) -> (ExpnId, Transparency, ExpnData) { HygieneData::with(|data| { - let outer = data.outer_expn(self); - (outer, data.expn_data(outer).clone()) + let (expn_id, transparency) = data.outer_mark(self); + (expn_id, transparency, data.expn_data(expn_id).clone()) }) } @@ -575,9 +550,15 @@ impl Span { /// The returned span belongs to the created expansion and has the new properties, /// but its location is inherited from the current span. pub fn fresh_expansion(self, expn_data: ExpnData) -> Span { + self.fresh_expansion_with_transparency(expn_data, Transparency::SemiTransparent) + } + + pub fn fresh_expansion_with_transparency( + self, expn_data: ExpnData, transparency: Transparency + ) -> Span { HygieneData::with(|data| { let expn_id = data.fresh_expn(Some(expn_data)); - self.with_ctxt(data.apply_mark(SyntaxContext::root(), expn_id)) + self.with_ctxt(data.apply_mark(SyntaxContext::root(), expn_id, transparency)) }) } } @@ -609,8 +590,6 @@ pub struct ExpnData { /// The span of the macro definition (possibly dummy). /// This span serves only informational purpose and is not used for resolution. pub def_site: Span, - /// Transparency used by `apply_mark` for the expansion with this expansion data by default. - pub default_transparency: Transparency, /// List of #[unstable]/feature-gated features that the macro is allowed to use /// internally without forcing the whole crate to opt-in /// to them. @@ -633,7 +612,6 @@ impl ExpnData { parent: ExpnId::root(), call_site, def_site: DUMMY_SP, - default_transparency: Transparency::SemiTransparent, allow_internal_unstable: None, allow_internal_unsafe: false, local_inner_macros: false, diff --git a/src/libsyntax_pos/lib.rs b/src/libsyntax_pos/lib.rs index a17cd7625fb..3d8bfc77a89 100644 --- a/src/libsyntax_pos/lib.rs +++ b/src/libsyntax_pos/lib.rs @@ -22,6 +22,7 @@ pub mod edition; use edition::Edition; pub mod hygiene; pub use hygiene::{ExpnId, SyntaxContext, ExpnData, ExpnKind, MacroKind, DesugaringKind}; +use hygiene::Transparency; mod span_encoding; pub use span_encoding::{Span, DUMMY_SP}; @@ -512,10 +513,17 @@ impl Span { span.ctxt) } + /// Produces a span with the same location as `self` and context produced by a macro with the + /// given ID and transparency, assuming that macro was defined directly and not produced by + /// some other macro (which is the case for built-in and procedural macros). + pub fn with_ctxt_from_mark(self, expn_id: ExpnId, transparency: Transparency) -> Span { + self.with_ctxt(SyntaxContext::root().apply_mark(expn_id, transparency)) + } + #[inline] - pub fn apply_mark(self, mark: ExpnId) -> Span { + pub fn apply_mark(self, expn_id: ExpnId, transparency: Transparency) -> Span { let span = self.data(); - span.with_ctxt(span.ctxt.apply_mark(mark)) + span.with_ctxt(span.ctxt.apply_mark(expn_id, transparency)) } #[inline] diff --git a/src/libterm/Cargo.toml b/src/libterm/Cargo.toml index 4eba9a9d79c..2931e0bda95 100644 --- a/src/libterm/Cargo.toml +++ b/src/libterm/Cargo.toml @@ -5,6 +5,8 @@ version = "0.0.0" edition = "2018" [lib] -name = "term" path = "lib.rs" -crate-type = ["dylib", "rlib"] + +[dependencies] +core = { path = "../libcore" } +std = { path = "../libstd" } diff --git a/src/libtest/Cargo.toml b/src/libtest/Cargo.toml index a72e4c70502..170fbb984cf 100644 --- a/src/libtest/Cargo.toml +++ b/src/libtest/Cargo.toml @@ -10,8 +10,22 @@ path = "lib.rs" crate-type = ["dylib", "rlib"] [dependencies] -getopts = "0.2.19" +getopts = { version = "0.2.21", features = ['rustc-dep-of-std'] } term = { path = "../libterm" } +std = { path = "../libstd" } +core = { path = "../libcore" } +libc = { version = "0.2", default-features = false } +panic_unwind = { path = "../libpanic_unwind" } +panic_abort = { path = "../libpanic_abort" } # not actually used but needed to always have proc_macro in the sysroot proc_macro = { path = "../libproc_macro" } + +# Forward features to the `std` crate as necessary +[features] +backtrace = ["std/backtrace"] +compiler-builtins-c = ["std/compiler-builtins-c"] +llvm-libunwind = ["std/llvm-libunwind"] +panic-unwind = ["std/panic_unwind"] +panic_immediate_abort = ["std/panic_immediate_abort"] +profiler = ["std/profiler"] diff --git a/src/libtest/lib.rs b/src/libtest/lib.rs index ef66c4df99d..5e0f19fe553 100644 --- a/src/libtest/lib.rs +++ b/src/libtest/lib.rs @@ -965,12 +965,11 @@ fn use_color(opts: &TestOpts) -> bool { #[cfg(any( target_os = "cloudabi", - target_os = "redox", all(target_arch = "wasm32", not(target_os = "emscripten")), all(target_vendor = "fortanix", target_env = "sgx") ))] fn stdout_isatty() -> bool { - // FIXME: Implement isatty on Redox and SGX + // FIXME: Implement isatty on SGX false } #[cfg(unix)] @@ -1193,15 +1192,15 @@ fn get_concurrency() -> usize { } } - #[cfg(target_os = "redox")] + #[cfg(target_os = "vxworks")] fn num_cpus() -> usize { - // FIXME: Implement num_cpus on Redox + // FIXME: Implement num_cpus on vxWorks 1 } - #[cfg(target_os = "vxworks")] + #[cfg(target_os = "redox")] fn num_cpus() -> usize { - // FIXME: Implement num_cpus on vxWorks + // FIXME: Implement num_cpus on Redox 1 } @@ -1221,7 +1220,7 @@ fn get_concurrency() -> usize { target_os = "ios", target_os = "linux", target_os = "macos", - target_os = "solaris" + target_os = "solaris", ))] fn num_cpus() -> usize { unsafe { libc::sysconf(libc::_SC_NPROCESSORS_ONLN) as usize } diff --git a/src/test/codegen/integer-cmp.rs b/src/test/codegen/integer-cmp.rs new file mode 100644 index 00000000000..1373b12e372 --- /dev/null +++ b/src/test/codegen/integer-cmp.rs @@ -0,0 +1,28 @@ +// This is test for more optimal Ord implementation for integers. +// See <https://github.com/rust-lang/rust/issues/63758> for more info. + +// compile-flags: -C opt-level=3 + +#![crate_type = "lib"] + +use std::cmp::Ordering; + +// CHECK-LABEL: @cmp_signed +#[no_mangle] +pub fn cmp_signed(a: i64, b: i64) -> Ordering { +// CHECK: icmp slt +// CHECK: icmp sgt +// CHECK: zext i1 +// CHECK: select i1 + a.cmp(&b) +} + +// CHECK-LABEL: @cmp_unsigned +#[no_mangle] +pub fn cmp_unsigned(a: u32, b: u32) -> Ordering { +// CHECK: icmp ult +// CHECK: icmp ugt +// CHECK: zext i1 +// CHECK: select i1 + a.cmp(&b) +} diff --git a/src/test/codegen/issue-45222.rs b/src/test/codegen/issue-45222.rs index 7f99ca724cf..7aadc8a0954 100644 --- a/src/test/codegen/issue-45222.rs +++ b/src/test/codegen/issue-45222.rs @@ -5,7 +5,6 @@ // verify that LLVM recognizes a loop involving 0..=n and will const-fold it. -//------------------------------------------------------------------------------ // Example from original issue #45222 fn foo2(n: u64) -> u64 { @@ -25,7 +24,6 @@ pub fn check_foo2() -> u64 { foo2(100000) } -//------------------------------------------------------------------------------ // Simplified example of #45222 fn triangle_inc(n: u64) -> u64 { @@ -43,7 +41,6 @@ pub fn check_triangle_inc() -> u64 { triangle_inc(100000) } -//------------------------------------------------------------------------------ // Demo in #48012 fn foo3r(n: u64) -> u64 { diff --git a/src/test/incremental/hashes/call_expressions.rs b/src/test/incremental/hashes/call_expressions.rs index d859cbef39f..50d3657d417 100644 --- a/src/test/incremental/hashes/call_expressions.rs +++ b/src/test/incremental/hashes/call_expressions.rs @@ -18,7 +18,7 @@ fn callee1(_x: u32, _y: i64) {} fn callee2(_x: u32, _y: i64) {} -// Change Callee (Function) ---------------------------------------------------- +// Change Callee (Function) #[cfg(cfail1)] pub fn change_callee_function() { callee1(1, 2) @@ -33,7 +33,7 @@ pub fn change_callee_function() { -// Change Argument (Function) -------------------------------------------------- +// Change Argument (Function) #[cfg(cfail1)] pub fn change_argument_function() { callee1(1, 2) @@ -48,7 +48,7 @@ pub fn change_argument_function() { -// Change Callee Indirectly (Function) ----------------------------------------- +// Change Callee Indirectly (Function) mod change_callee_indirectly_function { #[cfg(cfail1)] use super::callee1 as callee; @@ -73,7 +73,7 @@ impl Struct { fn method2(&self, _x: char, _y: bool) {} } -// Change Callee (Method) ------------------------------------------------------ +// Change Callee (Method) #[cfg(cfail1)] pub fn change_callee_method() { let s = Struct; @@ -90,7 +90,7 @@ pub fn change_callee_method() { -// Change Argument (Method) ---------------------------------------------------- +// Change Argument (Method) #[cfg(cfail1)] pub fn change_argument_method() { let s = Struct; @@ -107,7 +107,7 @@ pub fn change_argument_method() { -// Change Callee (Method, UFCS) ------------------------------------------------ +// Change Callee (Method, UFCS) #[cfg(cfail1)] pub fn change_ufcs_callee_method() { let s = Struct; @@ -124,7 +124,7 @@ pub fn change_ufcs_callee_method() { -// Change Argument (Method, UFCS) ---------------------------------------------- +// Change Argument (Method, UFCS) #[cfg(cfail1)] pub fn change_argument_method_ufcs() { let s = Struct; @@ -141,7 +141,7 @@ pub fn change_argument_method_ufcs() { -// Change To UFCS -------------------------------------------------------------- +// Change To UFCS #[cfg(cfail1)] pub fn change_to_ufcs() { let s = Struct; @@ -164,7 +164,7 @@ impl Struct2 { fn method1(&self, _x: char, _y: bool) {} } -// Change UFCS Callee Indirectly ----------------------------------------------- +// Change UFCS Callee Indirectly pub mod change_ufcs_callee_indirectly { #[cfg(cfail1)] use super::Struct as Struct; diff --git a/src/test/incremental/hashes/closure_expressions.rs b/src/test/incremental/hashes/closure_expressions.rs index 24ab6b8e184..08693560d0b 100644 --- a/src/test/incremental/hashes/closure_expressions.rs +++ b/src/test/incremental/hashes/closure_expressions.rs @@ -14,7 +14,7 @@ #![crate_type="rlib"] -// Change closure body --------------------------------------------------------- +// Change closure body #[cfg(cfail1)] pub fn change_closure_body() { let _ = || 1u32; @@ -29,7 +29,7 @@ pub fn change_closure_body() { -// Add parameter --------------------------------------------------------------- +// Add parameter #[cfg(cfail1)] pub fn add_parameter() { let x = 0u32; @@ -46,7 +46,7 @@ pub fn add_parameter() { -// Change parameter pattern ---------------------------------------------------- +// Change parameter pattern #[cfg(cfail1)] pub fn change_parameter_pattern() { let _ = |x: (u32,)| x; @@ -61,7 +61,7 @@ pub fn change_parameter_pattern() { -// Add `move` to closure ------------------------------------------------------- +// Add `move` to closure #[cfg(cfail1)] pub fn add_move() { let _ = || 1; @@ -76,7 +76,7 @@ pub fn add_move() { -// Add type ascription to parameter -------------------------------------------- +// Add type ascription to parameter #[cfg(cfail1)] pub fn add_type_ascription_to_parameter() { let closure = |x| x + 1u32; @@ -93,7 +93,7 @@ pub fn add_type_ascription_to_parameter() { -// Change parameter type ------------------------------------------------------- +// Change parameter type #[cfg(cfail1)] pub fn change_parameter_type() { let closure = |x: u32| (x as u64) + 1; diff --git a/src/test/incremental/hashes/consts.rs b/src/test/incremental/hashes/consts.rs index 8e713a1d992..3d2eed89636 100644 --- a/src/test/incremental/hashes/consts.rs +++ b/src/test/incremental/hashes/consts.rs @@ -14,7 +14,7 @@ #![crate_type="rlib"] -// Change const visibility --------------------------------------------------- +// Change const visibility #[cfg(cfail1)] const CONST_VISIBILITY: u8 = 0; @@ -24,7 +24,7 @@ const CONST_VISIBILITY: u8 = 0; pub const CONST_VISIBILITY: u8 = 0; -// Change type from i32 to u32 ------------------------------------------------ +// Change type from i32 to u32 #[cfg(cfail1)] const CONST_CHANGE_TYPE_1: i32 = 0; @@ -34,7 +34,7 @@ const CONST_CHANGE_TYPE_1: i32 = 0; const CONST_CHANGE_TYPE_1: u32 = 0; -// Change type from Option<u32> to Option<u64> -------------------------------- +// Change type from Option<u32> to Option<u64> #[cfg(cfail1)] const CONST_CHANGE_TYPE_2: Option<u32> = None; @@ -44,7 +44,7 @@ const CONST_CHANGE_TYPE_2: Option<u32> = None; const CONST_CHANGE_TYPE_2: Option<u64> = None; -// Change value between simple literals --------------------------------------- +// Change value between simple literals #[rustc_clean(cfg="cfail2", except="HirBody")] #[rustc_clean(cfg="cfail3")] const CONST_CHANGE_VALUE_1: i16 = { @@ -56,7 +56,7 @@ const CONST_CHANGE_VALUE_1: i16 = { }; -// Change value between expressions ------------------------------------------- +// Change value between expressions #[rustc_clean(cfg="cfail2", except="HirBody")] #[rustc_clean(cfg="cfail3")] const CONST_CHANGE_VALUE_2: i16 = { @@ -88,7 +88,7 @@ const CONST_CHANGE_VALUE_4: i16 = { }; -// Change type indirectly ----------------------------------------------------- +// Change type indirectly struct ReferencedType1; struct ReferencedType2; diff --git a/src/test/incremental/hashes/if_expressions.rs b/src/test/incremental/hashes/if_expressions.rs index b84c393573b..4b73f1371f8 100644 --- a/src/test/incremental/hashes/if_expressions.rs +++ b/src/test/incremental/hashes/if_expressions.rs @@ -14,7 +14,7 @@ #![feature(rustc_attrs)] #![crate_type="rlib"] -// Change condition (if) ------------------------------------------------------- +// Change condition (if) #[cfg(cfail1)] pub fn change_condition(x: bool) -> u32 { if x { @@ -35,7 +35,7 @@ pub fn change_condition(x: bool) -> u32 { return 0 } -// Change then branch (if) ----------------------------------------------------- +// Change then branch (if) #[cfg(cfail1)] pub fn change_then_branch(x: bool) -> u32 { if x { @@ -58,7 +58,7 @@ pub fn change_then_branch(x: bool) -> u32 { -// Change else branch (if) ----------------------------------------------------- +// Change else branch (if) #[cfg(cfail1)] pub fn change_else_branch(x: bool) -> u32 { if x { @@ -81,7 +81,7 @@ pub fn change_else_branch(x: bool) -> u32 { -// Add else branch (if) -------------------------------------------------------- +// Add else branch (if) #[cfg(cfail1)] pub fn add_else_branch(x: bool) -> u32 { let mut ret = 1; @@ -109,7 +109,7 @@ pub fn add_else_branch(x: bool) -> u32 { -// Change condition (if let) --------------------------------------------------- +// Change condition (if let) #[cfg(cfail1)] pub fn change_condition_if_let(x: Option<u32>) -> u32 { if let Some(_x) = x { @@ -132,7 +132,7 @@ pub fn change_condition_if_let(x: Option<u32>) -> u32 { -// Change then branch (if let) ------------------------------------------------- +// Change then branch (if let) #[cfg(cfail1)] pub fn change_then_branch_if_let(x: Option<u32>) -> u32 { if let Some(x) = x { @@ -155,7 +155,7 @@ pub fn change_then_branch_if_let(x: Option<u32>) -> u32 { -// Change else branch (if let) ------------------------------------------------- +// Change else branch (if let) #[cfg(cfail1)] pub fn change_else_branch_if_let(x: Option<u32>) -> u32 { if let Some(x) = x { @@ -178,7 +178,7 @@ pub fn change_else_branch_if_let(x: Option<u32>) -> u32 { -// Add else branch (if let) ---------------------------------------------------- +// Add else branch (if let) #[cfg(cfail1)] pub fn add_else_branch_if_let(x: Option<u32>) -> u32 { let mut ret = 1; diff --git a/src/test/incremental/hashes/indexing_expressions.rs b/src/test/incremental/hashes/indexing_expressions.rs index 4d39ed68701..08cf19d7760 100644 --- a/src/test/incremental/hashes/indexing_expressions.rs +++ b/src/test/incremental/hashes/indexing_expressions.rs @@ -13,7 +13,7 @@ #![feature(rustc_attrs)] #![crate_type="rlib"] -// Change simple index --------------------------------------------------------- +// Change simple index #[cfg(cfail1)] fn change_simple_index(slice: &[u32]) -> u32 { slice[3] @@ -30,7 +30,7 @@ fn change_simple_index(slice: &[u32]) -> u32 { -// Change lower bound ---------------------------------------------------------- +// Change lower bound #[cfg(cfail1)] fn change_lower_bound(slice: &[u32]) -> &[u32] { &slice[3..5] @@ -47,7 +47,7 @@ fn change_lower_bound(slice: &[u32]) -> &[u32] { -// Change upper bound ---------------------------------------------------------- +// Change upper bound #[cfg(cfail1)] fn change_upper_bound(slice: &[u32]) -> &[u32] { &slice[3..5] @@ -64,7 +64,7 @@ fn change_upper_bound(slice: &[u32]) -> &[u32] { -// Add lower bound ------------------------------------------------------------- +// Add lower bound #[cfg(cfail1)] fn add_lower_bound(slice: &[u32]) -> &[u32] { &slice[..4] @@ -81,7 +81,7 @@ fn add_lower_bound(slice: &[u32]) -> &[u32] { -// Add upper bound ------------------------------------------------------------- +// Add upper bound #[cfg(cfail1)] fn add_upper_bound(slice: &[u32]) -> &[u32] { &slice[3..] @@ -98,7 +98,7 @@ fn add_upper_bound(slice: &[u32]) -> &[u32] { -// Change mutability ----------------------------------------------------------- +// Change mutability #[cfg(cfail1)] fn change_mutability(slice: &mut [u32]) -> u32 { (&mut slice[3..5])[0] @@ -115,7 +115,7 @@ fn change_mutability(slice: &mut [u32]) -> u32 { -// Exclusive to inclusive range ------------------------------------------------ +// Exclusive to inclusive range #[cfg(cfail1)] fn exclusive_to_inclusive_range(slice: &[u32]) -> &[u32] { &slice[3..7] diff --git a/src/test/incremental/hashes/inline_asm.rs b/src/test/incremental/hashes/inline_asm.rs index deb1c45a528..c50ee73d714 100644 --- a/src/test/incremental/hashes/inline_asm.rs +++ b/src/test/incremental/hashes/inline_asm.rs @@ -16,7 +16,7 @@ -// Change template ------------------------------------------------------------- +// Change template #[cfg(cfail1)] #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] pub fn change_template(a: i32) -> i32 { @@ -51,7 +51,7 @@ pub fn change_template(a: i32) -> i32 { -// Change output ------------------------------------------------------------- +// Change output #[cfg(cfail1)] #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] pub fn change_output(a: i32) -> i32 { @@ -88,7 +88,7 @@ pub fn change_output(a: i32) -> i32 { -// Change input ------------------------------------------------------------- +// Change input #[cfg(cfail1)] #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] pub fn change_input(_a: i32, _b: i32) -> i32 { @@ -123,7 +123,7 @@ pub fn change_input(_a: i32, _b: i32) -> i32 { -// Change input constraint ----------------------------------------------------- +// Change input constraint #[cfg(cfail1)] #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] pub fn change_input_constraint(_a: i32, _b: i32) -> i32 { @@ -158,7 +158,7 @@ pub fn change_input_constraint(_a: i32, _b: i32) -> i32 { -// Change clobber -------------------------------------------------------------- +// Change clobber #[cfg(cfail1)] #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] pub fn change_clobber(_a: i32) -> i32 { @@ -193,7 +193,7 @@ pub fn change_clobber(_a: i32) -> i32 { -// Change options -------------------------------------------------------------- +// Change options #[cfg(cfail1)] #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] pub fn change_options(_a: i32) -> i32 { diff --git a/src/test/incremental/hashes/loop_expressions.rs b/src/test/incremental/hashes/loop_expressions.rs index 6222d948c98..a2222db4c59 100644 --- a/src/test/incremental/hashes/loop_expressions.rs +++ b/src/test/incremental/hashes/loop_expressions.rs @@ -14,7 +14,7 @@ #![crate_type="rlib"] -// Change loop body ------------------------------------------------------------ +// Change loop body #[cfg(cfail1)] pub fn change_loop_body() { let mut _x = 0; @@ -37,7 +37,7 @@ pub fn change_loop_body() { -// Add break ------------------------------------------------------------------- +// Add break #[cfg(cfail1)] pub fn add_break() { let mut _x = 0; @@ -59,7 +59,7 @@ pub fn add_break() { -// Add loop label -------------------------------------------------------------- +// Add loop label #[cfg(cfail1)] pub fn add_loop_label() { let mut _x = 0; @@ -82,7 +82,7 @@ pub fn add_loop_label() { -// Add loop label to break ----------------------------------------------------- +// Add loop label to break #[cfg(cfail1)] pub fn add_loop_label_to_break() { let mut _x = 0; @@ -105,7 +105,7 @@ pub fn add_loop_label_to_break() { -// Change break label ---------------------------------------------------------- +// Change break label #[cfg(cfail1)] pub fn change_break_label() { let mut _x = 0; @@ -132,7 +132,7 @@ pub fn change_break_label() { -// Add loop label to continue -------------------------------------------------- +// Add loop label to continue #[cfg(cfail1)] pub fn add_loop_label_to_continue() { let mut _x = 0; @@ -155,7 +155,7 @@ pub fn add_loop_label_to_continue() { -// Change continue label ---------------------------------------------------------- +// Change continue label #[cfg(cfail1)] pub fn change_continue_label() { let mut _x = 0; @@ -182,7 +182,7 @@ pub fn change_continue_label() { -// Change continue to break ---------------------------------------------------- +// Change continue to break #[cfg(cfail1)] pub fn change_continue_to_break() { let mut _x = 0; diff --git a/src/test/incremental/hashes/panic_exprs.rs b/src/test/incremental/hashes/panic_exprs.rs index b370fcce8ef..70b0a5ab78c 100644 --- a/src/test/incremental/hashes/panic_exprs.rs +++ b/src/test/incremental/hashes/panic_exprs.rs @@ -17,7 +17,7 @@ #![crate_type="rlib"] -// Indexing expression --------------------------------------------------------- +// Indexing expression #[rustc_clean(cfg="cfail2", except="HirBody,mir_built,optimized_mir")] #[rustc_clean(cfg="cfail3")] pub fn indexing(slice: &[u8]) -> u8 { @@ -32,7 +32,7 @@ pub fn indexing(slice: &[u8]) -> u8 { } -// Arithmetic overflow plus ---------------------------------------------------- +// Arithmetic overflow plus #[rustc_clean(cfg="cfail2", except="HirBody,mir_built,optimized_mir")] #[rustc_clean(cfg="cfail3")] pub fn arithmetic_overflow_plus(val: i32) -> i32 { @@ -47,7 +47,7 @@ pub fn arithmetic_overflow_plus(val: i32) -> i32 { } -// Arithmetic overflow minus ---------------------------------------------------- +// Arithmetic overflow minus #[rustc_clean(cfg="cfail2", except="HirBody,mir_built,optimized_mir")] #[rustc_clean(cfg="cfail3")] pub fn arithmetic_overflow_minus(val: i32) -> i32 { @@ -62,7 +62,7 @@ pub fn arithmetic_overflow_minus(val: i32) -> i32 { } -// Arithmetic overflow mult ---------------------------------------------------- +// Arithmetic overflow mult #[rustc_clean(cfg="cfail2", except="HirBody,mir_built,optimized_mir")] #[rustc_clean(cfg="cfail3")] pub fn arithmetic_overflow_mult(val: i32) -> i32 { @@ -77,7 +77,7 @@ pub fn arithmetic_overflow_mult(val: i32) -> i32 { } -// Arithmetic overflow negation ------------------------------------------------ +// Arithmetic overflow negation #[rustc_clean(cfg="cfail2", except="HirBody,mir_built,optimized_mir")] #[rustc_clean(cfg="cfail3")] pub fn arithmetic_overflow_negation(val: i32) -> i32 { @@ -92,7 +92,7 @@ pub fn arithmetic_overflow_negation(val: i32) -> i32 { } -// Division by zero ------------------------------------------------------------ +// Division by zero #[rustc_clean(cfg="cfail2", except="HirBody,mir_built,optimized_mir")] #[rustc_clean(cfg="cfail3")] pub fn division_by_zero(val: i32) -> i32 { @@ -106,7 +106,7 @@ pub fn division_by_zero(val: i32) -> i32 { } } -// Division by zero ------------------------------------------------------------ +// Division by zero #[rustc_clean(cfg="cfail2", except="HirBody,mir_built,optimized_mir")] #[rustc_clean(cfg="cfail3")] pub fn mod_by_zero(val: i32) -> i32 { @@ -121,7 +121,7 @@ pub fn mod_by_zero(val: i32) -> i32 { } -// shift left ------------------------------------------------------------------ +// shift left #[rustc_clean(cfg="cfail2", except="HirBody,mir_built,optimized_mir")] #[rustc_clean(cfg="cfail3")] pub fn shift_left(val: i32, shift: usize) -> i32 { @@ -136,7 +136,7 @@ pub fn shift_left(val: i32, shift: usize) -> i32 { } -// shift right ------------------------------------------------------------------ +// shift right #[rustc_clean(cfg="cfail2", except="HirBody,mir_built,optimized_mir")] #[rustc_clean(cfg="cfail3")] pub fn shift_right(val: i32, shift: usize) -> i32 { diff --git a/src/test/incremental/hashes/statics.rs b/src/test/incremental/hashes/statics.rs index 6f74e0fdbc0..d70ebb08b71 100644 --- a/src/test/incremental/hashes/statics.rs +++ b/src/test/incremental/hashes/statics.rs @@ -16,7 +16,7 @@ #![crate_type="rlib"] -// Change static visibility --------------------------------------------------- +// Change static visibility #[cfg(cfail1)] static STATIC_VISIBILITY: u8 = 0; @@ -26,7 +26,7 @@ static STATIC_VISIBILITY: u8 = 0; pub static STATIC_VISIBILITY: u8 = 0; -// Change static mutability --------------------------------------------------- +// Change static mutability #[cfg(cfail1)] static STATIC_MUTABILITY: u8 = 0; @@ -36,7 +36,7 @@ static STATIC_MUTABILITY: u8 = 0; static mut STATIC_MUTABILITY: u8 = 0; -// Add linkage attribute ------------------------------------------------------ +// Add linkage attribute #[cfg(cfail1)] static STATIC_LINKAGE: u8 = 0; @@ -47,7 +47,7 @@ static STATIC_LINKAGE: u8 = 0; static STATIC_LINKAGE: u8 = 0; -// Add no_mangle attribute ---------------------------------------------------- +// Add no_mangle attribute #[cfg(cfail1)] static STATIC_NO_MANGLE: u8 = 0; @@ -58,7 +58,7 @@ static STATIC_NO_MANGLE: u8 = 0; static STATIC_NO_MANGLE: u8 = 0; -// Add thread_local attribute ------------------------------------------------- +// Add thread_local attribute #[cfg(cfail1)] static STATIC_THREAD_LOCAL: u8 = 0; @@ -69,7 +69,7 @@ static STATIC_THREAD_LOCAL: u8 = 0; static STATIC_THREAD_LOCAL: u8 = 0; -// Change type from i16 to u64 ------------------------------------------------ +// Change type from i16 to u64 #[cfg(cfail1)] static STATIC_CHANGE_TYPE_1: i16 = 0; @@ -79,7 +79,7 @@ static STATIC_CHANGE_TYPE_1: i16 = 0; static STATIC_CHANGE_TYPE_1: u64 = 0; -// Change type from Option<i8> to Option<u16> --------------------------------- +// Change type from Option<i8> to Option<u16> #[cfg(cfail1)] static STATIC_CHANGE_TYPE_2: Option<i8> = None; @@ -89,7 +89,7 @@ static STATIC_CHANGE_TYPE_2: Option<i8> = None; static STATIC_CHANGE_TYPE_2: Option<u16> = None; -// Change value between simple literals --------------------------------------- +// Change value between simple literals #[rustc_clean(cfg="cfail2", except="HirBody")] #[rustc_clean(cfg="cfail3")] static STATIC_CHANGE_VALUE_1: i16 = { @@ -101,7 +101,7 @@ static STATIC_CHANGE_VALUE_1: i16 = { }; -// Change value between expressions ------------------------------------------- +// Change value between expressions #[rustc_clean(cfg="cfail2", except="HirBody")] #[rustc_clean(cfg="cfail3")] static STATIC_CHANGE_VALUE_2: i16 = { @@ -133,7 +133,7 @@ static STATIC_CHANGE_VALUE_4: i16 = { }; -// Change type indirectly ----------------------------------------------------- +// Change type indirectly struct ReferencedType1; struct ReferencedType2; diff --git a/src/test/incremental/hashes/struct_constructors.rs b/src/test/incremental/hashes/struct_constructors.rs index b708b99eabc..456d5e74751 100644 --- a/src/test/incremental/hashes/struct_constructors.rs +++ b/src/test/incremental/hashes/struct_constructors.rs @@ -20,7 +20,7 @@ pub struct RegularStruct { z: i16, } -// Change field value (regular struct) ----------------------------------------- +// Change field value (regular struct) #[cfg(cfail1)] pub fn change_field_value_regular_struct() -> RegularStruct { RegularStruct { @@ -43,7 +43,7 @@ pub fn change_field_value_regular_struct() -> RegularStruct { -// Change field order (regular struct) ----------------------------------------- +// Change field order (regular struct) #[cfg(cfail1)] pub fn change_field_order_regular_struct() -> RegularStruct { RegularStruct { @@ -66,7 +66,7 @@ pub fn change_field_order_regular_struct() -> RegularStruct { -// Add field (regular struct) -------------------------------------------------- +// Add field (regular struct) #[cfg(cfail1)] pub fn add_field_regular_struct() -> RegularStruct { let struct1 = RegularStruct { @@ -100,7 +100,7 @@ pub fn add_field_regular_struct() -> RegularStruct { -// Change field label (regular struct) ----------------------------------------- +// Change field label (regular struct) #[cfg(cfail1)] pub fn change_field_label_regular_struct() -> RegularStruct { let struct1 = RegularStruct { @@ -141,7 +141,7 @@ pub struct RegularStruct2 { z: i8, } -// Change constructor path (regular struct) ------------------------------------ +// Change constructor path (regular struct) #[cfg(cfail1)] pub fn change_constructor_path_regular_struct() { let _ = RegularStruct { @@ -164,7 +164,7 @@ pub fn change_constructor_path_regular_struct() { -// Change constructor path indirectly (regular struct) ------------------------- +// Change constructor path indirectly (regular struct) pub mod change_constructor_path_indirectly_regular_struct { #[cfg(cfail1)] use super::RegularStruct as Struct; @@ -189,7 +189,7 @@ pub mod change_constructor_path_indirectly_regular_struct { pub struct TupleStruct(i32, i64, i16); -// Change field value (tuple struct) ------------------------------------------- +// Change field value (tuple struct) #[cfg(cfail1)] pub fn change_field_value_tuple_struct() -> TupleStruct { TupleStruct(0, 1, 2) @@ -206,7 +206,7 @@ pub fn change_field_value_tuple_struct() -> TupleStruct { pub struct TupleStruct2(u16, u16, u16); -// Change constructor path (tuple struct) -------------------------------------- +// Change constructor path (tuple struct) #[cfg(cfail1)] pub fn change_constructor_path_tuple_struct() { let _ = TupleStruct(0, 1, 2); @@ -221,7 +221,7 @@ pub fn change_constructor_path_tuple_struct() { -// Change constructor path indirectly (tuple struct) --------------------------- +// Change constructor path indirectly (tuple struct) pub mod change_constructor_path_indirectly_tuple_struct { #[cfg(cfail1)] use super::TupleStruct as Struct; diff --git a/src/test/incremental/hashes/trait_defs.rs b/src/test/incremental/hashes/trait_defs.rs index 30b4e306820..81ff99533fc 100644 --- a/src/test/incremental/hashes/trait_defs.rs +++ b/src/test/incremental/hashes/trait_defs.rs @@ -21,7 +21,7 @@ #![feature(intrinsics)] -// Change trait visibility -------------------------------------------------------- +// Change trait visibility #[cfg(cfail1)] trait TraitVisibility { } @@ -32,7 +32,7 @@ pub trait TraitVisibility { } -// Change trait unsafety ---------------------------------------------------------- +// Change trait unsafety #[cfg(cfail1)] trait TraitUnsafety { } @@ -43,7 +43,7 @@ unsafe trait TraitUnsafety { } -// Add method --------------------------------------------------------------------- +// Add method #[cfg(cfail1)] trait TraitAddMethod { } @@ -57,7 +57,7 @@ pub trait TraitAddMethod { -// Change name of method ---------------------------------------------------------- +// Change name of method #[cfg(cfail1)] trait TraitChangeMethodName { fn method(); @@ -72,7 +72,7 @@ trait TraitChangeMethodName { -// Add return type to method ------------------------------------------------------ +// Add return type to method #[cfg(cfail1)] trait TraitAddReturnType { fn method(); @@ -89,7 +89,7 @@ trait TraitAddReturnType { -// Change return type of method --------------------------------------------------- +// Change return type of method #[cfg(cfail1)] trait TraitChangeReturnType { fn method() -> u32; @@ -106,7 +106,7 @@ trait TraitChangeReturnType { -// Add parameter to method -------------------------------------------------------- +// Add parameter to method #[cfg(cfail1)] trait TraitAddParameterToMethod { fn method(); @@ -123,7 +123,7 @@ trait TraitAddParameterToMethod { -// Change name of method parameter ------------------------------------------------ +// Change name of method parameter #[cfg(cfail1)] trait TraitChangeMethodParameterName { fn method(a: u32); @@ -148,7 +148,7 @@ trait TraitChangeMethodParameterName { -// Change type of method parameter (i32 => i64) ----------------------------------- +// Change type of method parameter (i32 => i64) #[cfg(cfail1)] trait TraitChangeMethodParameterType { fn method(a: i32); @@ -165,7 +165,7 @@ trait TraitChangeMethodParameterType { -// Change type of method parameter (&i32 => &mut i32) ----------------------------- +// Change type of method parameter (&i32 => &mut i32) #[cfg(cfail1)] trait TraitChangeMethodParameterTypeRef { fn method(a: &i32); @@ -182,7 +182,7 @@ trait TraitChangeMethodParameterTypeRef { -// Change order of method parameters ---------------------------------------------- +// Change order of method parameters #[cfg(cfail1)] trait TraitChangeMethodParametersOrder { fn method(a: i32, b: i64); @@ -199,7 +199,7 @@ trait TraitChangeMethodParametersOrder { -// Add default implementation to method ------------------------------------------- +// Add default implementation to method #[cfg(cfail1)] trait TraitAddMethodAutoImplementation { fn method(); @@ -216,7 +216,7 @@ trait TraitAddMethodAutoImplementation { -// Change order of methods -------------------------------------------------------- +// Change order of methods #[cfg(cfail1)] trait TraitChangeOrderOfMethods { fn method0(); @@ -233,7 +233,7 @@ trait TraitChangeOrderOfMethods { -// Change mode of self parameter -------------------------------------------------- +// Change mode of self parameter #[cfg(cfail1)] trait TraitChangeModeSelfRefToMut { fn method(&self); @@ -284,7 +284,7 @@ trait TraitChangeModeSelfOwnToRef { -// Add unsafe modifier to method -------------------------------------------------- +// Add unsafe modifier to method #[cfg(cfail1)] trait TraitAddUnsafeModifier { fn method(); @@ -301,7 +301,7 @@ trait TraitAddUnsafeModifier { -// Add extern modifier to method -------------------------------------------------- +// Add extern modifier to method #[cfg(cfail1)] trait TraitAddExternModifier { fn method(); @@ -318,7 +318,7 @@ trait TraitAddExternModifier { -// Change extern "C" to extern "rust-intrinsic" ----------------------------------- +// Change extern "C" to extern "rust-intrinsic" #[cfg(cfail1)] trait TraitChangeExternCToRustIntrinsic { extern "C" fn method(); @@ -335,7 +335,7 @@ trait TraitChangeExternCToRustIntrinsic { -// Add type parameter to method --------------------------------------------------- +// Add type parameter to method #[cfg(cfail1)] trait TraitAddTypeParameterToMethod { fn method(); @@ -352,7 +352,7 @@ trait TraitAddTypeParameterToMethod { -// Add lifetime parameter to method ----------------------------------------------- +// Add lifetime parameter to method #[cfg(cfail1)] trait TraitAddLifetimeParameterToMethod { fn method(); @@ -373,7 +373,7 @@ trait TraitAddLifetimeParameterToMethod { trait ReferencedTrait0 { } trait ReferencedTrait1 { } -// Add trait bound to method type parameter --------------------------------------- +// Add trait bound to method type parameter #[cfg(cfail1)] trait TraitAddTraitBoundToMethodTypeParameter { fn method<T>(); @@ -390,7 +390,7 @@ trait TraitAddTraitBoundToMethodTypeParameter { -// Add builtin bound to method type parameter ------------------------------------- +// Add builtin bound to method type parameter #[cfg(cfail1)] trait TraitAddBuiltinBoundToMethodTypeParameter { fn method<T>(); @@ -407,7 +407,7 @@ trait TraitAddBuiltinBoundToMethodTypeParameter { -// Add lifetime bound to method lifetime parameter ------------------------------------ +// Add lifetime bound to method lifetime parameter #[cfg(cfail1)] trait TraitAddLifetimeBoundToMethodLifetimeParameter { fn method<'a, 'b>(a: &'a u32, b: &'b u32); @@ -424,7 +424,7 @@ trait TraitAddLifetimeBoundToMethodLifetimeParameter { -// Add second trait bound to method type parameter -------------------------------- +// Add second trait bound to method type parameter #[cfg(cfail1)] trait TraitAddSecondTraitBoundToMethodTypeParameter { fn method<T: ReferencedTrait0>(); @@ -441,7 +441,7 @@ trait TraitAddSecondTraitBoundToMethodTypeParameter { -// Add second builtin bound to method type parameter ------------------------------ +// Add second builtin bound to method type parameter #[cfg(cfail1)] trait TraitAddSecondBuiltinBoundToMethodTypeParameter { fn method<T: Sized>(); @@ -458,7 +458,7 @@ trait TraitAddSecondBuiltinBoundToMethodTypeParameter { -// Add second lifetime bound to method lifetime parameter ----------------------------- +// Add second lifetime bound to method lifetime parameter #[cfg(cfail1)] trait TraitAddSecondLifetimeBoundToMethodLifetimeParameter { fn method<'a, 'b, 'c: 'a>(a: &'a u32, b: &'b u32, c: &'c u32); @@ -475,7 +475,7 @@ trait TraitAddSecondLifetimeBoundToMethodLifetimeParameter { -// Add associated type ------------------------------------------------------------ +// Add associated type #[cfg(cfail1)] trait TraitAddAssociatedType { @@ -495,7 +495,7 @@ trait TraitAddAssociatedType { -// Add trait bound to associated type --------------------------------------------- +// Add trait bound to associated type #[cfg(cfail1)] trait TraitAddTraitBoundToAssociatedType { type Associated; @@ -519,7 +519,7 @@ trait TraitAddTraitBoundToAssociatedType { -// Add lifetime bound to associated type ------------------------------------------ +// Add lifetime bound to associated type #[cfg(cfail1)] trait TraitAddLifetimeBoundToAssociatedType<'a> { type Associated; @@ -540,7 +540,7 @@ trait TraitAddLifetimeBoundToAssociatedType<'a> { -// Add default to associated type ------------------------------------------------- +// Add default to associated type #[cfg(cfail1)] trait TraitAddDefaultToAssociatedType { type Associated; @@ -561,7 +561,7 @@ trait TraitAddDefaultToAssociatedType { -// Add associated constant -------------------------------------------------------- +// Add associated constant #[cfg(cfail1)] trait TraitAddAssociatedConstant { fn method(); @@ -578,7 +578,7 @@ trait TraitAddAssociatedConstant { -// Add initializer to associated constant ----------------------------------------- +// Add initializer to associated constant #[cfg(cfail1)] trait TraitAddInitializerToAssociatedConstant { const Value: u32; @@ -601,7 +601,7 @@ trait TraitAddInitializerToAssociatedConstant { -// Change type of associated constant --------------------------------------------- +// Change type of associated constant #[cfg(cfail1)] trait TraitChangeTypeOfAssociatedConstant { const Value: u32; @@ -624,7 +624,7 @@ trait TraitChangeTypeOfAssociatedConstant { -// Add super trait ---------------------------------------------------------------- +// Add super trait #[cfg(cfail1)] trait TraitAddSuperTrait { } @@ -635,7 +635,7 @@ trait TraitAddSuperTrait : ReferencedTrait0 { } -// Add builtin bound (Send or Copy) ----------------------------------------------- +// Add builtin bound (Send or Copy) #[cfg(cfail1)] trait TraitAddBuiltiBound { } @@ -646,7 +646,7 @@ trait TraitAddBuiltiBound : Send { } -// Add 'static lifetime bound to trait -------------------------------------------- +// Add 'static lifetime bound to trait #[cfg(cfail1)] trait TraitAddStaticLifetimeBound { } @@ -657,7 +657,7 @@ trait TraitAddStaticLifetimeBound : 'static { } -// Add super trait as second bound ------------------------------------------------ +// Add super trait as second bound #[cfg(cfail1)] trait TraitAddTraitAsSecondBound : ReferencedTrait0 { } @@ -676,7 +676,7 @@ trait TraitAddTraitAsSecondBoundFromBuiltin : Send + ReferencedTrait0 { } -// Add builtin bound as second bound ---------------------------------------------- +// Add builtin bound as second bound #[cfg(cfail1)] trait TraitAddBuiltinBoundAsSecondBound : ReferencedTrait0 { } @@ -695,7 +695,7 @@ trait TraitAddBuiltinBoundAsSecondBoundFromBuiltin: Send + Copy { } -// Add 'static bounds as second bound --------------------------------------------- +// Add 'static bounds as second bound #[cfg(cfail1)] trait TraitAddStaticBoundAsSecondBound : ReferencedTrait0 { } @@ -714,7 +714,7 @@ trait TraitAddStaticBoundAsSecondBoundFromBuiltin : Send + 'static { } -// Add type parameter to trait ---------------------------------------------------- +// Add type parameter to trait #[cfg(cfail1)] trait TraitAddTypeParameterToTrait { } @@ -725,7 +725,7 @@ trait TraitAddTypeParameterToTrait<T> { } -// Add lifetime parameter to trait ------------------------------------------------ +// Add lifetime parameter to trait #[cfg(cfail1)] trait TraitAddLifetimeParameterToTrait { } @@ -736,7 +736,7 @@ trait TraitAddLifetimeParameterToTrait<'a> { } -// Add trait bound to type parameter of trait ------------------------------------- +// Add trait bound to type parameter of trait #[cfg(cfail1)] trait TraitAddTraitBoundToTypeParameterOfTrait<T> { } @@ -747,7 +747,7 @@ trait TraitAddTraitBoundToTypeParameterOfTrait<T: ReferencedTrait0> { } -// Add lifetime bound to type parameter of trait ---------------------------------- +// Add lifetime bound to type parameter of trait #[cfg(cfail1)] trait TraitAddLifetimeBoundToTypeParameterOfTrait<'a, T> { } @@ -758,7 +758,7 @@ trait TraitAddLifetimeBoundToTypeParameterOfTrait<'a, T: 'a> { } -// Add lifetime bound to lifetime parameter of trait ------------------------------ +// Add lifetime bound to lifetime parameter of trait #[cfg(cfail1)] trait TraitAddLifetimeBoundToLifetimeParameterOfTrait<'a, 'b> { } @@ -769,7 +769,7 @@ trait TraitAddLifetimeBoundToLifetimeParameterOfTrait<'a: 'b, 'b> { } -// Add builtin bound to type parameter of trait ----------------------------------- +// Add builtin bound to type parameter of trait #[cfg(cfail1)] trait TraitAddBuiltinBoundToTypeParameterOfTrait<T> { } @@ -780,7 +780,7 @@ trait TraitAddBuiltinBoundToTypeParameterOfTrait<T: Send> { } -// Add second type parameter to trait --------------------------------------------- +// Add second type parameter to trait #[cfg(cfail1)] trait TraitAddSecondTypeParameterToTrait<T> { } @@ -791,7 +791,7 @@ trait TraitAddSecondTypeParameterToTrait<T, S> { } -// Add second lifetime parameter to trait ----------------------------------------- +// Add second lifetime parameter to trait #[cfg(cfail1)] trait TraitAddSecondLifetimeParameterToTrait<'a> { } @@ -802,7 +802,7 @@ trait TraitAddSecondLifetimeParameterToTrait<'a, 'b> { } -// Add second trait bound to type parameter of trait ------------------------------ +// Add second trait bound to type parameter of trait #[cfg(cfail1)] trait TraitAddSecondTraitBoundToTypeParameterOfTrait<T: ReferencedTrait0> { } @@ -813,7 +813,7 @@ trait TraitAddSecondTraitBoundToTypeParameterOfTrait<T: ReferencedTrait0 + Refer -// Add second lifetime bound to type parameter of trait --------------------------- +// Add second lifetime bound to type parameter of trait #[cfg(cfail1)] trait TraitAddSecondLifetimeBoundToTypeParameterOfTrait<'a, 'b, T: 'a> { } @@ -824,7 +824,7 @@ trait TraitAddSecondLifetimeBoundToTypeParameterOfTrait<'a, 'b, T: 'a + 'b> { } -// Add second lifetime bound to lifetime parameter of trait------------------------ +// Add second lifetime bound to lifetime parameter of trait #[cfg(cfail1)] trait TraitAddSecondLifetimeBoundToLifetimeParameterOfTrait<'a: 'b, 'b, 'c> { } @@ -835,7 +835,7 @@ trait TraitAddSecondLifetimeBoundToLifetimeParameterOfTrait<'a: 'b + 'c, 'b, 'c> -// Add second builtin bound to type parameter of trait ---------------------------- +// Add second builtin bound to type parameter of trait #[cfg(cfail1)] trait TraitAddSecondBuiltinBoundToTypeParameterOfTrait<T: Send> { } @@ -846,13 +846,12 @@ trait TraitAddSecondBuiltinBoundToTypeParameterOfTrait<T: Send + Sync> { } -// -------------------------------------------------------------------------------- struct ReferenceType0 {} struct ReferenceType1 {} -// Add trait bound to type parameter of trait in where clause---------------------- +// Add trait bound to type parameter of trait in where clause #[cfg(cfail1)] trait TraitAddTraitBoundToTypeParameterOfTraitWhere<T> { } @@ -863,7 +862,7 @@ trait TraitAddTraitBoundToTypeParameterOfTraitWhere<T> where T: ReferencedTrait0 -// Add lifetime bound to type parameter of trait in where clause------------------- +// Add lifetime bound to type parameter of trait in where clause #[cfg(cfail1)] trait TraitAddLifetimeBoundToTypeParameterOfTraitWhere<'a, T> { } @@ -874,7 +873,7 @@ trait TraitAddLifetimeBoundToTypeParameterOfTraitWhere<'a, T> where T: 'a { } -// Add lifetime bound to lifetime parameter of trait in where clause--------------- +// Add lifetime bound to lifetime parameter of trait in where clause #[cfg(cfail1)] trait TraitAddLifetimeBoundToLifetimeParameterOfTraitWhere<'a, 'b> { } @@ -885,7 +884,7 @@ trait TraitAddLifetimeBoundToLifetimeParameterOfTraitWhere<'a, 'b> where 'a: 'b -// Add builtin bound to type parameter of trait in where clause-------------------- +// Add builtin bound to type parameter of trait in where clause #[cfg(cfail1)] trait TraitAddBuiltinBoundToTypeParameterOfTraitWhere<T> { } @@ -896,7 +895,7 @@ trait TraitAddBuiltinBoundToTypeParameterOfTraitWhere<T> where T: Send { } -// Add second trait bound to type parameter of trait in where clause--------------- +// Add second trait bound to type parameter of trait in where clause #[cfg(cfail1)] trait TraitAddSecondTraitBoundToTypeParameterOfTraitWhere<T> where T: ReferencedTrait0 { } @@ -908,7 +907,7 @@ trait TraitAddSecondTraitBoundToTypeParameterOfTraitWhere<T> -// Add second lifetime bound to type parameter of trait in where clause------------ +// Add second lifetime bound to type parameter of trait in where clause #[cfg(cfail1)] trait TraitAddSecondLifetimeBoundToTypeParameterOfTraitWhere<'a, 'b, T> where T: 'a { } @@ -919,7 +918,7 @@ trait TraitAddSecondLifetimeBoundToTypeParameterOfTraitWhere<'a, 'b, T> where T: -// Add second lifetime bound to lifetime parameter of trait in where clause-------- +// Add second lifetime bound to lifetime parameter of trait in where clause #[cfg(cfail1)] trait TraitAddSecondLifetimeBoundToLifetimeParameterOfTraitWhere<'a, 'b, 'c> where 'a: 'b { } @@ -930,7 +929,7 @@ trait TraitAddSecondLifetimeBoundToLifetimeParameterOfTraitWhere<'a, 'b, 'c> whe -// Add second builtin bound to type parameter of trait in where clause------------- +// Add second builtin bound to type parameter of trait in where clause #[cfg(cfail1)] trait TraitAddSecondBuiltinBoundToTypeParameterOfTraitWhere<T> where T: Send { } @@ -940,7 +939,7 @@ trait TraitAddSecondBuiltinBoundToTypeParameterOfTraitWhere<T> where T: Send { } trait TraitAddSecondBuiltinBoundToTypeParameterOfTraitWhere<T> where T: Send + Sync { } -// Change return type of method indirectly by modifying a use statement------------ +// Change return type of method indirectly by modifying a use statement mod change_return_type_of_method_indirectly_use { #[cfg(cfail1)] use super::ReferenceType0 as ReturnType; @@ -958,7 +957,7 @@ mod change_return_type_of_method_indirectly_use { -// Change type of method parameter indirectly by modifying a use statement--------- +// Change type of method parameter indirectly by modifying a use statement mod change_method_parameter_type_indirectly_by_use { #[cfg(cfail1)] use super::ReferenceType0 as ArgType; diff --git a/src/test/incremental/hashes/while_let_loops.rs b/src/test/incremental/hashes/while_let_loops.rs index 39b28ec1906..da3c957741f 100644 --- a/src/test/incremental/hashes/while_let_loops.rs +++ b/src/test/incremental/hashes/while_let_loops.rs @@ -14,7 +14,7 @@ #![crate_type="rlib"] -// Change loop body ------------------------------------------------------------ +// Change loop body #[cfg(cfail1)] pub fn change_loop_body() { let mut _x = 0; @@ -37,7 +37,7 @@ pub fn change_loop_body() { -// Change loop body ------------------------------------------------------------ +// Change loop body #[cfg(cfail1)] pub fn change_loop_condition() { let mut _x = 0; @@ -60,7 +60,7 @@ pub fn change_loop_condition() { -// Add break ------------------------------------------------------------------- +// Add break #[cfg(cfail1)] pub fn add_break() { let mut _x = 0; @@ -82,7 +82,7 @@ pub fn add_break() { -// Add loop label -------------------------------------------------------------- +// Add loop label #[cfg(cfail1)] pub fn add_loop_label() { let mut _x = 0; @@ -105,7 +105,7 @@ pub fn add_loop_label() { -// Add loop label to break ----------------------------------------------------- +// Add loop label to break #[cfg(cfail1)] pub fn add_loop_label_to_break() { let mut _x = 0; @@ -128,7 +128,7 @@ pub fn add_loop_label_to_break() { -// Change break label ---------------------------------------------------------- +// Change break label #[cfg(cfail1)] pub fn change_break_label() { let mut _x = 0; @@ -155,7 +155,7 @@ pub fn change_break_label() { -// Add loop label to continue -------------------------------------------------- +// Add loop label to continue #[cfg(cfail1)] pub fn add_loop_label_to_continue() { let mut _x = 0; @@ -178,7 +178,7 @@ pub fn add_loop_label_to_continue() { -// Change continue label ---------------------------------------------------------- +// Change continue label #[cfg(cfail1)] pub fn change_continue_label() { let mut _x = 0; @@ -205,7 +205,7 @@ pub fn change_continue_label() { -// Change continue to break ---------------------------------------------------- +// Change continue to break #[cfg(cfail1)] pub fn change_continue_to_break() { let mut _x = 0; diff --git a/src/test/incremental/hashes/while_loops.rs b/src/test/incremental/hashes/while_loops.rs index 06072185469..3be42e7a4ee 100644 --- a/src/test/incremental/hashes/while_loops.rs +++ b/src/test/incremental/hashes/while_loops.rs @@ -14,7 +14,7 @@ #![crate_type="rlib"] -// Change loop body ------------------------------------------------------------ +// Change loop body #[cfg(cfail1)] pub fn change_loop_body() { let mut _x = 0; @@ -37,7 +37,7 @@ pub fn change_loop_body() { -// Change loop body ------------------------------------------------------------ +// Change loop body #[cfg(cfail1)] pub fn change_loop_condition() { let mut _x = 0; @@ -60,7 +60,7 @@ pub fn change_loop_condition() { -// Add break ------------------------------------------------------------------- +// Add break #[cfg(cfail1)] pub fn add_break() { let mut _x = 0; @@ -82,7 +82,7 @@ pub fn add_break() { -// Add loop label -------------------------------------------------------------- +// Add loop label #[cfg(cfail1)] pub fn add_loop_label() { let mut _x = 0; @@ -105,7 +105,7 @@ pub fn add_loop_label() { -// Add loop label to break ----------------------------------------------------- +// Add loop label to break #[cfg(cfail1)] pub fn add_loop_label_to_break() { let mut _x = 0; @@ -128,7 +128,7 @@ pub fn add_loop_label_to_break() { -// Change break label ---------------------------------------------------------- +// Change break label #[cfg(cfail1)] pub fn change_break_label() { let mut _x = 0; @@ -155,7 +155,7 @@ pub fn change_break_label() { -// Add loop label to continue -------------------------------------------------- +// Add loop label to continue #[cfg(cfail1)] pub fn add_loop_label_to_continue() { let mut _x = 0; @@ -178,7 +178,7 @@ pub fn add_loop_label_to_continue() { -// Change continue label ---------------------------------------------------------- +// Change continue label #[cfg(cfail1)] pub fn change_continue_label() { let mut _x = 0; @@ -205,7 +205,7 @@ pub fn change_continue_label() { -// Change continue to break ---------------------------------------------------- +// Change continue to break #[cfg(cfail1)] pub fn change_continue_to_break() { let mut _x = 0; diff --git a/src/test/rustdoc/async-fn.rs b/src/test/rustdoc/async-fn.rs index 7384f7027d1..5f9708a3972 100644 --- a/src/test/rustdoc/async-fn.rs +++ b/src/test/rustdoc/async-fn.rs @@ -1,7 +1,5 @@ // edition:2018 -#![feature(async_await)] - // @has async_fn/fn.foo.html '//pre[@class="rust fn"]' 'pub async fn foo() -> Option<Foo>' pub async fn foo() -> Option<Foo> { None diff --git a/src/test/rustdoc/async-move-doctest.rs b/src/test/rustdoc/async-move-doctest.rs index 42723132782..2ba61388c9e 100644 --- a/src/test/rustdoc/async-move-doctest.rs +++ b/src/test/rustdoc/async-move-doctest.rs @@ -1,13 +1,11 @@ // compile-flags:--test // edition:2018 -// prior to setting the default edition for the doctest pre-parser, this doctest would fail due to -// a fatal parsing error +// Prior to setting the default edition for the doctest pre-parser, +// this doctest would fail due to a fatal parsing error. // see https://github.com/rust-lang/rust/issues/59313 //! ``` -//! #![feature(async_await)] -//! //! fn foo() { //! drop(async move {}); //! } diff --git a/src/test/rustdoc/edition-flag.rs b/src/test/rustdoc/edition-flag.rs index 5571245f28d..ddbc2be651d 100644 --- a/src/test/rustdoc/edition-flag.rs +++ b/src/test/rustdoc/edition-flag.rs @@ -1,10 +1,7 @@ // compile-flags:--test -Z unstable-options // edition:2018 -#![feature(async_await)] - /// ```rust -/// #![feature(async_await)] /// fn main() { /// let _ = async { }; /// } diff --git a/src/test/ui/array-break-length.rs b/src/test/ui/array-break-length.rs index 2696aea5e89..959f4a2babb 100644 --- a/src/test/ui/array-break-length.rs +++ b/src/test/ui/array-break-length.rs @@ -1,11 +1,11 @@ fn main() { loop { - |_: [_; break]| {} //~ ERROR: `break` outside of loop + |_: [_; break]| {} //~ ERROR: `break` outside of a loop //~^ ERROR mismatched types } loop { - |_: [_; continue]| {} //~ ERROR: `continue` outside of loop + |_: [_; continue]| {} //~ ERROR: `continue` outside of a loop //~^ ERROR mismatched types } } diff --git a/src/test/ui/array-break-length.stderr b/src/test/ui/array-break-length.stderr index 0e0dc8f623e..45f529bafe7 100644 --- a/src/test/ui/array-break-length.stderr +++ b/src/test/ui/array-break-length.stderr @@ -1,14 +1,14 @@ -error[E0268]: `break` outside of loop +error[E0268]: `break` outside of a loop --> $DIR/array-break-length.rs:3:17 | LL | |_: [_; break]| {} - | ^^^^^ cannot break outside of a loop + | ^^^^^ cannot `break` outside of a loop -error[E0268]: `continue` outside of loop +error[E0268]: `continue` outside of a loop --> $DIR/array-break-length.rs:8:17 | LL | |_: [_; continue]| {} - | ^^^^^^^^ cannot break outside of a loop + | ^^^^^^^^ cannot `continue` outside of a loop error[E0308]: mismatched types --> $DIR/array-break-length.rs:3:9 diff --git a/src/test/ui/async-await/argument-patterns.rs b/src/test/ui/async-await/argument-patterns.rs index 3750c2bcb70..0e42f48b835 100644 --- a/src/test/ui/async-await/argument-patterns.rs +++ b/src/test/ui/async-await/argument-patterns.rs @@ -3,7 +3,6 @@ #![allow(unused_variables)] #![deny(unused_mut)] -#![feature(async_await)] type A = Vec<u32>; diff --git a/src/test/ui/async-await/async-await.rs b/src/test/ui/async-await/async-await.rs index 8a15eb8c573..bf8bf0bcce0 100644 --- a/src/test/ui/async-await/async-await.rs +++ b/src/test/ui/async-await/async-await.rs @@ -3,8 +3,6 @@ // edition:2018 // aux-build:arc_wake.rs -#![feature(async_await)] - extern crate arc_wake; use std::pin::Pin; diff --git a/src/test/ui/async-await/async-block-control-flow-static-semantics.rs b/src/test/ui/async-await/async-block-control-flow-static-semantics.rs index 4ddcdcac822..753a4e49155 100644 --- a/src/test/ui/async-await/async-block-control-flow-static-semantics.rs +++ b/src/test/ui/async-await/async-block-control-flow-static-semantics.rs @@ -6,8 +6,6 @@ // edition:2018 // ignore-tidy-linelength -#![feature(async_await)] - fn main() {} use core::future::Future; @@ -32,14 +30,14 @@ async fn return_targets_async_block_not_async_fn() -> u8 { fn no_break_in_async_block() { async { - break 0u8; //~ ERROR `break` inside of an async block + break 0u8; //~ ERROR `break` inside of an `async` block }; } fn no_break_in_async_block_even_with_outer_loop() { loop { async { - break 0u8; //~ ERROR `break` inside of an async block + break 0u8; //~ ERROR `break` inside of an `async` block }; } } diff --git a/src/test/ui/async-await/async-block-control-flow-static-semantics.stderr b/src/test/ui/async-await/async-block-control-flow-static-semantics.stderr index a0a5ac63d84..c36caa5586f 100644 --- a/src/test/ui/async-await/async-block-control-flow-static-semantics.stderr +++ b/src/test/ui/async-await/async-block-control-flow-static-semantics.stderr @@ -1,17 +1,25 @@ -error[E0267]: `break` inside of an async block - --> $DIR/async-block-control-flow-static-semantics.rs:35:9 +error[E0267]: `break` inside of an `async` block + --> $DIR/async-block-control-flow-static-semantics.rs:33:9 | -LL | break 0u8; - | ^^^^^^^^^ cannot break inside of an async block +LL | async { + | ___________- +LL | | break 0u8; + | | ^^^^^^^^^ cannot `break` inside of an `async` block +LL | | }; + | |_____- enclosing `async` block -error[E0267]: `break` inside of an async block - --> $DIR/async-block-control-flow-static-semantics.rs:42:13 +error[E0267]: `break` inside of an `async` block + --> $DIR/async-block-control-flow-static-semantics.rs:40:13 | -LL | break 0u8; - | ^^^^^^^^^ cannot break inside of an async block +LL | async { + | _______________- +LL | | break 0u8; + | | ^^^^^^^^^ cannot `break` inside of an `async` block +LL | | }; + | |_________- enclosing `async` block error[E0308]: mismatched types - --> $DIR/async-block-control-flow-static-semantics.rs:15:43 + --> $DIR/async-block-control-flow-static-semantics.rs:13:43 | LL | fn return_targets_async_block_not_fn() -> u8 { | --------------------------------- ^^ expected u8, found () @@ -22,7 +30,7 @@ LL | fn return_targets_async_block_not_fn() -> u8 { found type `()` error[E0271]: type mismatch resolving `<impl std::future::Future as std::future::Future>::Output == ()` - --> $DIR/async-block-control-flow-static-semantics.rs:20:39 + --> $DIR/async-block-control-flow-static-semantics.rs:18:39 | LL | let _: &dyn Future<Output = ()> = █ | ^^^^^^ expected u8, found () @@ -32,7 +40,7 @@ LL | let _: &dyn Future<Output = ()> = █ = note: required for the cast to the object type `dyn std::future::Future<Output = ()>` error[E0271]: type mismatch resolving `<impl std::future::Future as std::future::Future>::Output == ()` - --> $DIR/async-block-control-flow-static-semantics.rs:29:39 + --> $DIR/async-block-control-flow-static-semantics.rs:27:39 | LL | let _: &dyn Future<Output = ()> = █ | ^^^^^^ expected u8, found () @@ -42,7 +50,7 @@ LL | let _: &dyn Future<Output = ()> = █ = note: required for the cast to the object type `dyn std::future::Future<Output = ()>` error[E0271]: type mismatch resolving `<impl std::future::Future as std::future::Future>::Output == u8` - --> $DIR/async-block-control-flow-static-semantics.rs:24:55 + --> $DIR/async-block-control-flow-static-semantics.rs:22:55 | LL | async fn return_targets_async_block_not_async_fn() -> u8 { | ^^ expected (), found u8 @@ -52,7 +60,7 @@ LL | async fn return_targets_async_block_not_async_fn() -> u8 { = note: the return type of a function must have a statically known size error[E0308]: mismatched types - --> $DIR/async-block-control-flow-static-semantics.rs:50:44 + --> $DIR/async-block-control-flow-static-semantics.rs:48:44 | LL | fn rethrow_targets_async_block_not_fn() -> Result<u8, MyErr> { | ---------------------------------- ^^^^^^^^^^^^^^^^^ expected enum `std::result::Result`, found () @@ -63,7 +71,7 @@ LL | fn rethrow_targets_async_block_not_fn() -> Result<u8, MyErr> { found type `()` error[E0308]: mismatched types - --> $DIR/async-block-control-flow-static-semantics.rs:59:50 + --> $DIR/async-block-control-flow-static-semantics.rs:57:50 | LL | fn rethrow_targets_async_block_not_async_fn() -> Result<u8, MyErr> { | ---------------------------------------- ^^^^^^^^^^^^^^^^^ expected enum `std::result::Result`, found () diff --git a/src/test/ui/async-await/async-closure-matches-expr.rs b/src/test/ui/async-await/async-closure-matches-expr.rs index 1c192a4d1d8..d82fbcdc550 100644 --- a/src/test/ui/async-await/async-closure-matches-expr.rs +++ b/src/test/ui/async-await/async-closure-matches-expr.rs @@ -1,7 +1,7 @@ // build-pass // edition:2018 -#![feature(async_await, async_closure)] +#![feature(async_closure)] macro_rules! match_expr { ($x:expr) => {} diff --git a/src/test/ui/async-await/async-closure.rs b/src/test/ui/async-await/async-closure.rs index 925b54b3985..9a24bd8c954 100644 --- a/src/test/ui/async-await/async-closure.rs +++ b/src/test/ui/async-await/async-closure.rs @@ -3,7 +3,7 @@ // edition:2018 // aux-build:arc_wake.rs -#![feature(async_await, async_closure)] +#![feature(async_closure)] extern crate arc_wake; diff --git a/src/test/ui/async-await/async-error-span.rs b/src/test/ui/async-await/async-error-span.rs index d362348a3fd..dec3ac0f685 100644 --- a/src/test/ui/async-await/async-error-span.rs +++ b/src/test/ui/async-await/async-error-span.rs @@ -1,7 +1,6 @@ // edition:2018 -#![feature(async_await)] -// Regression test for issue #62382 +// Regression test for issue #62382. use std::future::Future; diff --git a/src/test/ui/async-await/async-error-span.stderr b/src/test/ui/async-await/async-error-span.stderr index bd8966b9c7d..47441f5e4ef 100644 --- a/src/test/ui/async-await/async-error-span.stderr +++ b/src/test/ui/async-await/async-error-span.stderr @@ -1,11 +1,11 @@ error[E0698]: type inside `async` object must be known in this context - --> $DIR/async-error-span.rs:13:9 + --> $DIR/async-error-span.rs:12:9 | LL | let a; | ^ cannot infer type | note: the type is part of the `async` object because of this `await` - --> $DIR/async-error-span.rs:14:5 + --> $DIR/async-error-span.rs:13:5 | LL | get_future().await; | ^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/async-await/async-fn-elided-impl-lifetime-parameter.rs b/src/test/ui/async-await/async-fn-elided-impl-lifetime-parameter.rs index 1cbc5133a07..1c369fd7415 100644 --- a/src/test/ui/async-await/async-fn-elided-impl-lifetime-parameter.rs +++ b/src/test/ui/async-await/async-fn-elided-impl-lifetime-parameter.rs @@ -6,8 +6,6 @@ // check-pass // edition:2018 -#![feature(async_await)] - struct Foo<'a>(&'a u8); impl Foo<'_> { diff --git a/src/test/ui/async-await/async-fn-nonsend.rs b/src/test/ui/async-await/async-fn-nonsend.rs index 612c1e29d82..1f1bf4250ea 100644 --- a/src/test/ui/async-await/async-fn-nonsend.rs +++ b/src/test/ui/async-await/async-fn-nonsend.rs @@ -2,8 +2,6 @@ // edition:2018 // compile-flags: --crate-type lib -#![feature(async_await)] - use std::{ cell::RefCell, fmt::Debug, diff --git a/src/test/ui/async-await/async-fn-nonsend.stderr b/src/test/ui/async-await/async-fn-nonsend.stderr index 7776a36a28f..6b4fff2dc68 100644 --- a/src/test/ui/async-await/async-fn-nonsend.stderr +++ b/src/test/ui/async-await/async-fn-nonsend.stderr @@ -1,5 +1,5 @@ error[E0277]: `std::rc::Rc<()>` cannot be sent between threads safely - --> $DIR/async-fn-nonsend.rs:52:5 + --> $DIR/async-fn-nonsend.rs:50:5 | LL | assert_send(local_dropped_before_await()); | ^^^^^^^^^^^ `std::rc::Rc<()>` cannot be sent between threads safely @@ -7,18 +7,18 @@ LL | assert_send(local_dropped_before_await()); = help: within `impl std::future::Future`, the trait `std::marker::Send` is not implemented for `std::rc::Rc<()>` = note: required because it appears within the type `impl std::fmt::Debug` = note: required because it appears within the type `{impl std::fmt::Debug, impl std::future::Future, ()}` - = note: required because it appears within the type `[static generator@$DIR/async-fn-nonsend.rs:23:39: 28:2 {impl std::fmt::Debug, impl std::future::Future, ()}]` - = note: required because it appears within the type `std::future::GenFuture<[static generator@$DIR/async-fn-nonsend.rs:23:39: 28:2 {impl std::fmt::Debug, impl std::future::Future, ()}]>` + = note: required because it appears within the type `[static generator@$DIR/async-fn-nonsend.rs:21:39: 26:2 {impl std::fmt::Debug, impl std::future::Future, ()}]` + = note: required because it appears within the type `std::future::GenFuture<[static generator@$DIR/async-fn-nonsend.rs:21:39: 26:2 {impl std::fmt::Debug, impl std::future::Future, ()}]>` = note: required because it appears within the type `impl std::future::Future` = note: required because it appears within the type `impl std::future::Future` note: required by `assert_send` - --> $DIR/async-fn-nonsend.rs:49:1 + --> $DIR/async-fn-nonsend.rs:47:1 | LL | fn assert_send(_: impl Send) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0277]: `std::rc::Rc<()>` cannot be sent between threads safely - --> $DIR/async-fn-nonsend.rs:54:5 + --> $DIR/async-fn-nonsend.rs:52:5 | LL | assert_send(non_send_temporary_in_match()); | ^^^^^^^^^^^ `std::rc::Rc<()>` cannot be sent between threads safely @@ -26,18 +26,18 @@ LL | assert_send(non_send_temporary_in_match()); = help: within `impl std::future::Future`, the trait `std::marker::Send` is not implemented for `std::rc::Rc<()>` = note: required because it appears within the type `impl std::fmt::Debug` = note: required because it appears within the type `{fn(impl std::fmt::Debug) -> std::option::Option<impl std::fmt::Debug> {std::option::Option::<impl std::fmt::Debug>::Some}, fn() -> impl std::fmt::Debug {non_send}, impl std::fmt::Debug, std::option::Option<impl std::fmt::Debug>, impl std::future::Future, ()}` - = note: required because it appears within the type `[static generator@$DIR/async-fn-nonsend.rs:30:40: 39:2 {fn(impl std::fmt::Debug) -> std::option::Option<impl std::fmt::Debug> {std::option::Option::<impl std::fmt::Debug>::Some}, fn() -> impl std::fmt::Debug {non_send}, impl std::fmt::Debug, std::option::Option<impl std::fmt::Debug>, impl std::future::Future, ()}]` - = note: required because it appears within the type `std::future::GenFuture<[static generator@$DIR/async-fn-nonsend.rs:30:40: 39:2 {fn(impl std::fmt::Debug) -> std::option::Option<impl std::fmt::Debug> {std::option::Option::<impl std::fmt::Debug>::Some}, fn() -> impl std::fmt::Debug {non_send}, impl std::fmt::Debug, std::option::Option<impl std::fmt::Debug>, impl std::future::Future, ()}]>` + = note: required because it appears within the type `[static generator@$DIR/async-fn-nonsend.rs:28:40: 37:2 {fn(impl std::fmt::Debug) -> std::option::Option<impl std::fmt::Debug> {std::option::Option::<impl std::fmt::Debug>::Some}, fn() -> impl std::fmt::Debug {non_send}, impl std::fmt::Debug, std::option::Option<impl std::fmt::Debug>, impl std::future::Future, ()}]` + = note: required because it appears within the type `std::future::GenFuture<[static generator@$DIR/async-fn-nonsend.rs:28:40: 37:2 {fn(impl std::fmt::Debug) -> std::option::Option<impl std::fmt::Debug> {std::option::Option::<impl std::fmt::Debug>::Some}, fn() -> impl std::fmt::Debug {non_send}, impl std::fmt::Debug, std::option::Option<impl std::fmt::Debug>, impl std::future::Future, ()}]>` = note: required because it appears within the type `impl std::future::Future` = note: required because it appears within the type `impl std::future::Future` note: required by `assert_send` - --> $DIR/async-fn-nonsend.rs:49:1 + --> $DIR/async-fn-nonsend.rs:47:1 | LL | fn assert_send(_: impl Send) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0277]: `dyn std::fmt::Write` cannot be sent between threads safely - --> $DIR/async-fn-nonsend.rs:56:5 + --> $DIR/async-fn-nonsend.rs:54:5 | LL | assert_send(non_sync_with_method_call()); | ^^^^^^^^^^^ `dyn std::fmt::Write` cannot be sent between threads safely @@ -47,18 +47,18 @@ LL | assert_send(non_sync_with_method_call()); = note: required because it appears within the type `std::fmt::Formatter<'_>` = note: required because of the requirements on the impl of `std::marker::Send` for `&mut std::fmt::Formatter<'_>` = note: required because it appears within the type `for<'r, 's> {&'r mut std::fmt::Formatter<'s>, bool, impl std::future::Future, ()}` - = note: required because it appears within the type `[static generator@$DIR/async-fn-nonsend.rs:41:38: 47:2 for<'r, 's> {&'r mut std::fmt::Formatter<'s>, bool, impl std::future::Future, ()}]` - = note: required because it appears within the type `std::future::GenFuture<[static generator@$DIR/async-fn-nonsend.rs:41:38: 47:2 for<'r, 's> {&'r mut std::fmt::Formatter<'s>, bool, impl std::future::Future, ()}]>` + = note: required because it appears within the type `[static generator@$DIR/async-fn-nonsend.rs:39:38: 45:2 for<'r, 's> {&'r mut std::fmt::Formatter<'s>, bool, impl std::future::Future, ()}]` + = note: required because it appears within the type `std::future::GenFuture<[static generator@$DIR/async-fn-nonsend.rs:39:38: 45:2 for<'r, 's> {&'r mut std::fmt::Formatter<'s>, bool, impl std::future::Future, ()}]>` = note: required because it appears within the type `impl std::future::Future` = note: required because it appears within the type `impl std::future::Future` note: required by `assert_send` - --> $DIR/async-fn-nonsend.rs:49:1 + --> $DIR/async-fn-nonsend.rs:47:1 | LL | fn assert_send(_: impl Send) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0277]: `*mut (dyn std::ops::Fn() + 'static)` cannot be shared between threads safely - --> $DIR/async-fn-nonsend.rs:56:5 + --> $DIR/async-fn-nonsend.rs:54:5 | LL | assert_send(non_sync_with_method_call()); | ^^^^^^^^^^^ `*mut (dyn std::ops::Fn() + 'static)` cannot be shared between threads safely @@ -72,12 +72,12 @@ LL | assert_send(non_sync_with_method_call()); = note: required because it appears within the type `std::fmt::Formatter<'_>` = note: required because of the requirements on the impl of `std::marker::Send` for `&mut std::fmt::Formatter<'_>` = note: required because it appears within the type `for<'r, 's> {&'r mut std::fmt::Formatter<'s>, bool, impl std::future::Future, ()}` - = note: required because it appears within the type `[static generator@$DIR/async-fn-nonsend.rs:41:38: 47:2 for<'r, 's> {&'r mut std::fmt::Formatter<'s>, bool, impl std::future::Future, ()}]` - = note: required because it appears within the type `std::future::GenFuture<[static generator@$DIR/async-fn-nonsend.rs:41:38: 47:2 for<'r, 's> {&'r mut std::fmt::Formatter<'s>, bool, impl std::future::Future, ()}]>` + = note: required because it appears within the type `[static generator@$DIR/async-fn-nonsend.rs:39:38: 45:2 for<'r, 's> {&'r mut std::fmt::Formatter<'s>, bool, impl std::future::Future, ()}]` + = note: required because it appears within the type `std::future::GenFuture<[static generator@$DIR/async-fn-nonsend.rs:39:38: 45:2 for<'r, 's> {&'r mut std::fmt::Formatter<'s>, bool, impl std::future::Future, ()}]>` = note: required because it appears within the type `impl std::future::Future` = note: required because it appears within the type `impl std::future::Future` note: required by `assert_send` - --> $DIR/async-fn-nonsend.rs:49:1 + --> $DIR/async-fn-nonsend.rs:47:1 | LL | fn assert_send(_: impl Send) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/async-await/async-fn-path-elision.rs b/src/test/ui/async-await/async-fn-path-elision.rs index 447e40dddd9..3f1f51c20ca 100644 --- a/src/test/ui/async-await/async-fn-path-elision.rs +++ b/src/test/ui/async-await/async-fn-path-elision.rs @@ -1,8 +1,5 @@ // edition:2018 -#![feature(async_await)] -#![allow(dead_code)] - struct HasLifetime<'a>(&'a bool); async fn error(lt: HasLifetime) { //~ ERROR implicit elided lifetime not allowed here diff --git a/src/test/ui/async-await/async-fn-path-elision.stderr b/src/test/ui/async-await/async-fn-path-elision.stderr index 3b311baba01..9694742200e 100644 --- a/src/test/ui/async-await/async-fn-path-elision.stderr +++ b/src/test/ui/async-await/async-fn-path-elision.stderr @@ -1,5 +1,5 @@ error[E0726]: implicit elided lifetime not allowed here - --> $DIR/async-fn-path-elision.rs:8:20 + --> $DIR/async-fn-path-elision.rs:5:20 | LL | async fn error(lt: HasLifetime) { | ^^^^^^^^^^^- help: indicate the anonymous lifetime: `<'_>` diff --git a/src/test/ui/async-await/async-fn-send-uses-nonsend.rs b/src/test/ui/async-await/async-fn-send-uses-nonsend.rs index 5e1b8c6280b..35d9cb15540 100644 --- a/src/test/ui/async-await/async-fn-send-uses-nonsend.rs +++ b/src/test/ui/async-await/async-fn-send-uses-nonsend.rs @@ -2,8 +2,6 @@ // edition:2018 // compile-flags: --crate-type lib -#![feature(async_await)] - use std::{ cell::RefCell, fmt::Debug, diff --git a/src/test/ui/async-await/async-fn-size-moved-locals.rs b/src/test/ui/async-await/async-fn-size-moved-locals.rs index 30b59d037d5..3ffcbb58595 100644 --- a/src/test/ui/async-await/async-fn-size-moved-locals.rs +++ b/src/test/ui/async-await/async-fn-size-moved-locals.rs @@ -12,8 +12,6 @@ // edition:2018 -#![feature(async_await)] - use std::future::Future; use std::pin::Pin; use std::task::{Context, Poll}; diff --git a/src/test/ui/async-await/async-fn-size.rs b/src/test/ui/async-await/async-fn-size.rs index c6b2ed13b0a..b5c94ecb716 100644 --- a/src/test/ui/async-await/async-fn-size.rs +++ b/src/test/ui/async-await/async-fn-size.rs @@ -2,8 +2,6 @@ // aux-build:arc_wake.rs // edition:2018 -#![feature(async_await)] - extern crate arc_wake; use std::pin::Pin; diff --git a/src/test/ui/async-await/async-matches-expr.rs b/src/test/ui/async-await/async-matches-expr.rs index a6f0211e41f..299faa0587b 100644 --- a/src/test/ui/async-await/async-matches-expr.rs +++ b/src/test/ui/async-await/async-matches-expr.rs @@ -1,8 +1,6 @@ // build-pass (FIXME(62277): could be check-pass?) // edition:2018 -#![feature(async_await)] - macro_rules! match_expr { ($x:expr) => {} } 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 cb9156dcc6e..ccc1b8553f0 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 @@ -1,7 +1,5 @@ // edition:2018 -#![feature(async_await)] - struct S; impl S { diff --git a/src/test/ui/async-await/async-unsafe-fn-call-in-safe.stderr b/src/test/ui/async-await/async-unsafe-fn-call-in-safe.stderr index d22413beecb..c95fe173488 100644 --- a/src/test/ui/async-await/async-unsafe-fn-call-in-safe.stderr +++ b/src/test/ui/async-await/async-unsafe-fn-call-in-safe.stderr @@ -1,5 +1,5 @@ error[E0133]: call to unsafe function is unsafe and requires unsafe function or block - --> $DIR/async-unsafe-fn-call-in-safe.rs:14:5 + --> $DIR/async-unsafe-fn-call-in-safe.rs:12:5 | LL | S::f(); | ^^^^^^ call to unsafe function @@ -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:13: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:17: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:18:5 | LL | f(); | ^^^ call to unsafe function diff --git a/src/test/ui/async-await/async-with-closure.rs b/src/test/ui/async-await/async-with-closure.rs index f7dc874affd..0b225526675 100644 --- a/src/test/ui/async-await/async-with-closure.rs +++ b/src/test/ui/async-await/async-with-closure.rs @@ -1,8 +1,6 @@ // build-pass (FIXME(62277): could be check-pass?) // edition:2018 -#![feature(async_await)] - trait MyClosure { type Args; } diff --git a/src/test/ui/async-await/await-keyword/2015-edition-error-various-positions.rs b/src/test/ui/async-await/await-keyword/2015-edition-error-various-positions.rs index 422a5a6394f..a3a20cb97e1 100644 --- a/src/test/ui/async-await/await-keyword/2015-edition-error-various-positions.rs +++ b/src/test/ui/async-await/await-keyword/2015-edition-error-various-positions.rs @@ -1,4 +1,3 @@ -#![feature(async_await)] #![allow(non_camel_case_types)] #![deny(keyword_idents)] diff --git a/src/test/ui/async-await/await-keyword/2015-edition-error-various-positions.stderr b/src/test/ui/async-await/await-keyword/2015-edition-error-various-positions.stderr index 8af0110169e..f1a22cda51b 100644 --- a/src/test/ui/async-await/await-keyword/2015-edition-error-various-positions.stderr +++ b/src/test/ui/async-await/await-keyword/2015-edition-error-various-positions.stderr @@ -1,11 +1,11 @@ error: `await` is a keyword in the 2018 edition - --> $DIR/2015-edition-error-various-positions.rs:6:13 + --> $DIR/2015-edition-error-various-positions.rs:5:13 | LL | pub mod await { | ^^^^^ help: you can use a raw identifier to stay compatible: `r#await` | note: lint level defined here - --> $DIR/2015-edition-error-various-positions.rs:3:9 + --> $DIR/2015-edition-error-various-positions.rs:2:9 | LL | #![deny(keyword_idents)] | ^^^^^^^^^^^^^^ @@ -13,7 +13,7 @@ LL | #![deny(keyword_idents)] = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716> error: `await` is a keyword in the 2018 edition - --> $DIR/2015-edition-error-various-positions.rs:8:20 + --> $DIR/2015-edition-error-various-positions.rs:7:20 | LL | pub struct await; | ^^^^^ help: you can use a raw identifier to stay compatible: `r#await` @@ -22,7 +22,7 @@ LL | pub struct await; = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716> error: `await` is a keyword in the 2018 edition - --> $DIR/2015-edition-error-various-positions.rs:12:16 + --> $DIR/2015-edition-error-various-positions.rs:11:16 | LL | use outer_mod::await::await; | ^^^^^ help: you can use a raw identifier to stay compatible: `r#await` @@ -31,7 +31,7 @@ LL | use outer_mod::await::await; = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716> error: `await` is a keyword in the 2018 edition - --> $DIR/2015-edition-error-various-positions.rs:12:23 + --> $DIR/2015-edition-error-various-positions.rs:11:23 | LL | use outer_mod::await::await; | ^^^^^ help: you can use a raw identifier to stay compatible: `r#await` @@ -40,7 +40,7 @@ LL | use outer_mod::await::await; = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716> error: `await` is a keyword in the 2018 edition - --> $DIR/2015-edition-error-various-positions.rs:17:14 + --> $DIR/2015-edition-error-various-positions.rs:16:14 | LL | struct Foo { await: () } | ^^^^^ help: you can use a raw identifier to stay compatible: `r#await` @@ -49,7 +49,7 @@ LL | struct Foo { await: () } = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716> error: `await` is a keyword in the 2018 edition - --> $DIR/2015-edition-error-various-positions.rs:21:15 + --> $DIR/2015-edition-error-various-positions.rs:20:15 | LL | impl Foo { fn await() {} } | ^^^^^ help: you can use a raw identifier to stay compatible: `r#await` @@ -58,7 +58,7 @@ LL | impl Foo { fn await() {} } = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716> error: `await` is a keyword in the 2018 edition - --> $DIR/2015-edition-error-various-positions.rs:25:14 + --> $DIR/2015-edition-error-various-positions.rs:24:14 | LL | macro_rules! await { | ^^^^^ help: you can use a raw identifier to stay compatible: `r#await` @@ -67,7 +67,7 @@ LL | macro_rules! await { = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716> error: `await` is a keyword in the 2018 edition - --> $DIR/2015-edition-error-various-positions.rs:32:5 + --> $DIR/2015-edition-error-various-positions.rs:31:5 | LL | await!(); | ^^^^^ help: you can use a raw identifier to stay compatible: `r#await` @@ -76,7 +76,7 @@ LL | await!(); = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716> error: `await` is a keyword in the 2018 edition - --> $DIR/2015-edition-error-various-positions.rs:35:11 + --> $DIR/2015-edition-error-various-positions.rs:34:11 | LL | match await { await => {} } | ^^^^^ help: you can use a raw identifier to stay compatible: `r#await` @@ -85,7 +85,7 @@ LL | match await { await => {} } = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716> error: `await` is a keyword in the 2018 edition - --> $DIR/2015-edition-error-various-positions.rs:35:19 + --> $DIR/2015-edition-error-various-positions.rs:34:19 | LL | match await { await => {} } | ^^^^^ help: you can use a raw identifier to stay compatible: `r#await` diff --git a/src/test/ui/async-await/await-keyword/2018-edition-error-in-non-macro-position.rs b/src/test/ui/async-await/await-keyword/2018-edition-error-in-non-macro-position.rs index 92f3210ac89..5d85b0a243e 100644 --- a/src/test/ui/async-await/await-keyword/2018-edition-error-in-non-macro-position.rs +++ b/src/test/ui/async-await/await-keyword/2018-edition-error-in-non-macro-position.rs @@ -1,7 +1,6 @@ // edition:2018 #![allow(non_camel_case_types)] -#![feature(async_await)] mod outer_mod { pub mod await { //~ ERROR expected identifier, found reserved keyword `await` diff --git a/src/test/ui/async-await/await-keyword/2018-edition-error-in-non-macro-position.stderr b/src/test/ui/async-await/await-keyword/2018-edition-error-in-non-macro-position.stderr index c4b82b29f02..05f28d0a5b2 100644 --- a/src/test/ui/async-await/await-keyword/2018-edition-error-in-non-macro-position.stderr +++ b/src/test/ui/async-await/await-keyword/2018-edition-error-in-non-macro-position.stderr @@ -1,5 +1,5 @@ error: expected identifier, found reserved keyword `await` - --> $DIR/2018-edition-error-in-non-macro-position.rs:7:13 + --> $DIR/2018-edition-error-in-non-macro-position.rs:6:13 | LL | pub mod await { | ^^^^^ expected identifier, found reserved keyword @@ -9,7 +9,7 @@ LL | pub mod r#await { | ^^^^^^^ error: expected identifier, found reserved keyword `await` - --> $DIR/2018-edition-error-in-non-macro-position.rs:8:20 + --> $DIR/2018-edition-error-in-non-macro-position.rs:7:20 | LL | pub struct await; | ^^^^^ expected identifier, found reserved keyword @@ -19,7 +19,7 @@ LL | pub struct r#await; | ^^^^^^^ error: expected identifier, found reserved keyword `await` - --> $DIR/2018-edition-error-in-non-macro-position.rs:11:22 + --> $DIR/2018-edition-error-in-non-macro-position.rs:10:22 | LL | use self::outer_mod::await::await; | ^^^^^ expected identifier, found reserved keyword @@ -29,7 +29,7 @@ LL | use self::outer_mod::r#await::await; | ^^^^^^^ error: expected identifier, found reserved keyword `await` - --> $DIR/2018-edition-error-in-non-macro-position.rs:11:29 + --> $DIR/2018-edition-error-in-non-macro-position.rs:10:29 | LL | use self::outer_mod::await::await; | ^^^^^ expected identifier, found reserved keyword @@ -39,7 +39,7 @@ LL | use self::outer_mod::await::r#await; | ^^^^^^^ error: expected identifier, found reserved keyword `await` - --> $DIR/2018-edition-error-in-non-macro-position.rs:14:14 + --> $DIR/2018-edition-error-in-non-macro-position.rs:13:14 | LL | struct Foo { await: () } | ^^^^^ expected identifier, found reserved keyword @@ -49,7 +49,7 @@ LL | struct Foo { r#await: () } | ^^^^^^^ error: expected identifier, found reserved keyword `await` - --> $DIR/2018-edition-error-in-non-macro-position.rs:17:15 + --> $DIR/2018-edition-error-in-non-macro-position.rs:16:15 | LL | impl Foo { fn await() {} } | ^^^^^ expected identifier, found reserved keyword @@ -59,7 +59,7 @@ LL | impl Foo { fn r#await() {} } | ^^^^^^^ error: expected identifier, found reserved keyword `await` - --> $DIR/2018-edition-error-in-non-macro-position.rs:20:14 + --> $DIR/2018-edition-error-in-non-macro-position.rs:19:14 | LL | macro_rules! await { | ^^^^^ expected identifier, found reserved keyword diff --git a/src/test/ui/async-await/await-keyword/incorrect-syntax-suggestions.rs b/src/test/ui/async-await/await-keyword/incorrect-syntax-suggestions.rs index 25da337c587..22bcbb1064d 100644 --- a/src/test/ui/async-await/await-keyword/incorrect-syntax-suggestions.rs +++ b/src/test/ui/async-await/await-keyword/incorrect-syntax-suggestions.rs @@ -1,7 +1,5 @@ // edition:2018 -#![feature(async_await)] - async fn bar() -> Result<(), ()> { Ok(()) } diff --git a/src/test/ui/async-await/await-keyword/incorrect-syntax-suggestions.stderr b/src/test/ui/async-await/await-keyword/incorrect-syntax-suggestions.stderr index db86d3d5d03..7caa9f26bc2 100644 --- a/src/test/ui/async-await/await-keyword/incorrect-syntax-suggestions.stderr +++ b/src/test/ui/async-await/await-keyword/incorrect-syntax-suggestions.stderr @@ -1,119 +1,119 @@ error: incorrect use of `await` - --> $DIR/incorrect-syntax-suggestions.rs:10:13 + --> $DIR/incorrect-syntax-suggestions.rs:8:13 | LL | let _ = await bar(); | ^^^^^^^^^^^ help: `await` is a postfix operation: `bar().await` error: incorrect use of `await` - --> $DIR/incorrect-syntax-suggestions.rs:14:13 + --> $DIR/incorrect-syntax-suggestions.rs:12:13 | LL | let _ = await? bar(); | ^^^^^^^^^^^^ help: `await` is a postfix operation: `bar().await?` error: incorrect use of `await` - --> $DIR/incorrect-syntax-suggestions.rs:18:13 + --> $DIR/incorrect-syntax-suggestions.rs:16:13 | LL | let _ = await bar()?; | ^^^^^^^^^^^^ help: `await` is a postfix operation: `bar()?.await` error: incorrect use of `await` - --> $DIR/incorrect-syntax-suggestions.rs:23:13 + --> $DIR/incorrect-syntax-suggestions.rs:21:13 | LL | let _ = await { bar() }; | ^^^^^^^^^^^^^^^ help: `await` is a postfix operation: `{ bar() }.await` error: incorrect use of `await` - --> $DIR/incorrect-syntax-suggestions.rs:27:13 + --> $DIR/incorrect-syntax-suggestions.rs:25:13 | LL | let _ = await(bar()); | ^^^^^^^^^^^^ help: `await` is a postfix operation: `(bar()).await` error: incorrect use of `await` - --> $DIR/incorrect-syntax-suggestions.rs:31:13 + --> $DIR/incorrect-syntax-suggestions.rs:29:13 | LL | let _ = await { bar() }?; | ^^^^^^^^^^^^^^^ help: `await` is a postfix operation: `{ bar() }.await` error: incorrect use of `await` - --> $DIR/incorrect-syntax-suggestions.rs:35:14 + --> $DIR/incorrect-syntax-suggestions.rs:33:14 | LL | let _ = (await bar())?; | ^^^^^^^^^^^ help: `await` is a postfix operation: `bar().await` error: incorrect use of `await` - --> $DIR/incorrect-syntax-suggestions.rs:39:24 + --> $DIR/incorrect-syntax-suggestions.rs:37:24 | LL | let _ = bar().await(); | ^^ help: `await` is not a method call, remove the parentheses error: incorrect use of `await` - --> $DIR/incorrect-syntax-suggestions.rs:43:24 + --> $DIR/incorrect-syntax-suggestions.rs:41:24 | LL | let _ = bar().await()?; | ^^ help: `await` is not a method call, remove the parentheses error: incorrect use of `await` - --> $DIR/incorrect-syntax-suggestions.rs:55:13 + --> $DIR/incorrect-syntax-suggestions.rs:53:13 | LL | let _ = await bar(); | ^^^^^^^^^^^ help: `await` is a postfix operation: `bar().await` error: incorrect use of `await` - --> $DIR/incorrect-syntax-suggestions.rs:60:13 + --> $DIR/incorrect-syntax-suggestions.rs:58:13 | LL | let _ = await? bar(); | ^^^^^^^^^^^^ help: `await` is a postfix operation: `bar().await?` error: incorrect use of `await` - --> $DIR/incorrect-syntax-suggestions.rs:65:13 + --> $DIR/incorrect-syntax-suggestions.rs:63:13 | LL | let _ = await bar()?; | ^^^^^^^^^^^^ help: `await` is a postfix operation: `bar()?.await` error: incorrect use of `await` - --> $DIR/incorrect-syntax-suggestions.rs:70:14 + --> $DIR/incorrect-syntax-suggestions.rs:68:14 | LL | let _ = (await bar())?; | ^^^^^^^^^^^ help: `await` is a postfix operation: `bar().await` error: incorrect use of `await` - --> $DIR/incorrect-syntax-suggestions.rs:75:24 + --> $DIR/incorrect-syntax-suggestions.rs:73:24 | LL | let _ = bar().await(); | ^^ help: `await` is not a method call, remove the parentheses error: incorrect use of `await` - --> $DIR/incorrect-syntax-suggestions.rs:80:24 + --> $DIR/incorrect-syntax-suggestions.rs:78:24 | LL | let _ = bar().await()?; | ^^ help: `await` is not a method call, remove the parentheses error: incorrect use of `await` - --> $DIR/incorrect-syntax-suggestions.rs:108:13 + --> $DIR/incorrect-syntax-suggestions.rs:106:13 | LL | let _ = await!(bar()); | ^^^^^^^^^^^^^ help: `await` is a postfix operation: `bar().await` error: incorrect use of `await` - --> $DIR/incorrect-syntax-suggestions.rs:112:13 + --> $DIR/incorrect-syntax-suggestions.rs:110:13 | LL | let _ = await!(bar())?; | ^^^^^^^^^^^^^ help: `await` is a postfix operation: `bar().await` error: incorrect use of `await` - --> $DIR/incorrect-syntax-suggestions.rs:117:17 + --> $DIR/incorrect-syntax-suggestions.rs:115:17 | LL | let _ = await!(bar())?; | ^^^^^^^^^^^^^ help: `await` is a postfix operation: `bar().await` error: incorrect use of `await` - --> $DIR/incorrect-syntax-suggestions.rs:125:17 + --> $DIR/incorrect-syntax-suggestions.rs:123:17 | LL | let _ = await!(bar())?; | ^^^^^^^^^^^^^ help: `await` is a postfix operation: `bar().await` error: expected expression, found `=>` - --> $DIR/incorrect-syntax-suggestions.rs:133:25 + --> $DIR/incorrect-syntax-suggestions.rs:131:25 | LL | match await { await => () } | ----- ^^ expected expression @@ -121,13 +121,13 @@ LL | match await { await => () } | while parsing this incorrect await expression error: incorrect use of `await` - --> $DIR/incorrect-syntax-suggestions.rs:133:11 + --> $DIR/incorrect-syntax-suggestions.rs:131:11 | LL | match await { await => () } | ^^^^^^^^^^^^^^^^^^^^^ help: `await` is a postfix operation: `{ await => () }.await` error: expected one of `.`, `?`, `{`, or an operator, found `}` - --> $DIR/incorrect-syntax-suggestions.rs:136:1 + --> $DIR/incorrect-syntax-suggestions.rs:134:1 | LL | match await { await => () } | ----- - expected one of `.`, `?`, `{`, or an operator here @@ -138,7 +138,7 @@ LL | } | ^ unexpected token error[E0728]: `await` is only allowed inside `async` functions and blocks - --> $DIR/incorrect-syntax-suggestions.rs:55:13 + --> $DIR/incorrect-syntax-suggestions.rs:53:13 | LL | fn foo9() -> Result<(), ()> { | ---- this is not `async` @@ -146,7 +146,7 @@ LL | let _ = await bar(); | ^^^^^^^^^^^ only allowed inside `async` functions and blocks error[E0728]: `await` is only allowed inside `async` functions and blocks - --> $DIR/incorrect-syntax-suggestions.rs:60:13 + --> $DIR/incorrect-syntax-suggestions.rs:58:13 | LL | fn foo10() -> Result<(), ()> { | ----- this is not `async` @@ -154,7 +154,7 @@ LL | let _ = await? bar(); | ^^^^^^^^^^^^ only allowed inside `async` functions and blocks error[E0728]: `await` is only allowed inside `async` functions and blocks - --> $DIR/incorrect-syntax-suggestions.rs:65:13 + --> $DIR/incorrect-syntax-suggestions.rs:63:13 | LL | fn foo11() -> Result<(), ()> { | ----- this is not `async` @@ -162,7 +162,7 @@ LL | let _ = await bar()?; | ^^^^^^^^^^^^ only allowed inside `async` functions and blocks error[E0728]: `await` is only allowed inside `async` functions and blocks - --> $DIR/incorrect-syntax-suggestions.rs:70:14 + --> $DIR/incorrect-syntax-suggestions.rs:68:14 | LL | fn foo12() -> Result<(), ()> { | ----- this is not `async` @@ -170,7 +170,7 @@ LL | let _ = (await bar())?; | ^^^^^^^^^^^ only allowed inside `async` functions and blocks error[E0728]: `await` is only allowed inside `async` functions and blocks - --> $DIR/incorrect-syntax-suggestions.rs:75:13 + --> $DIR/incorrect-syntax-suggestions.rs:73:13 | LL | fn foo13() -> Result<(), ()> { | ----- this is not `async` @@ -178,7 +178,7 @@ LL | let _ = bar().await(); | ^^^^^^^^^^^ only allowed inside `async` functions and blocks error[E0728]: `await` is only allowed inside `async` functions and blocks - --> $DIR/incorrect-syntax-suggestions.rs:80:13 + --> $DIR/incorrect-syntax-suggestions.rs:78:13 | LL | fn foo14() -> Result<(), ()> { | ----- this is not `async` @@ -186,7 +186,7 @@ LL | let _ = bar().await()?; | ^^^^^^^^^^^ only allowed inside `async` functions and blocks error[E0728]: `await` is only allowed inside `async` functions and blocks - --> $DIR/incorrect-syntax-suggestions.rs:85:13 + --> $DIR/incorrect-syntax-suggestions.rs:83:13 | LL | fn foo15() -> Result<(), ()> { | ----- this is not `async` @@ -194,7 +194,7 @@ LL | let _ = bar().await; | ^^^^^^^^^^^ only allowed inside `async` functions and blocks error[E0728]: `await` is only allowed inside `async` functions and blocks - --> $DIR/incorrect-syntax-suggestions.rs:89:13 + --> $DIR/incorrect-syntax-suggestions.rs:87:13 | LL | fn foo16() -> Result<(), ()> { | ----- this is not `async` @@ -202,7 +202,7 @@ LL | let _ = bar().await?; | ^^^^^^^^^^^ only allowed inside `async` functions and blocks error[E0728]: `await` is only allowed inside `async` functions and blocks - --> $DIR/incorrect-syntax-suggestions.rs:94:17 + --> $DIR/incorrect-syntax-suggestions.rs:92:17 | LL | fn foo() -> Result<(), ()> { | --- this is not `async` @@ -210,7 +210,7 @@ LL | let _ = bar().await?; | ^^^^^^^^^^^ only allowed inside `async` functions and blocks error[E0728]: `await` is only allowed inside `async` functions and blocks - --> $DIR/incorrect-syntax-suggestions.rs:101:17 + --> $DIR/incorrect-syntax-suggestions.rs:99:17 | LL | let foo = || { | -- this is not `async` @@ -218,7 +218,7 @@ LL | let _ = bar().await?; | ^^^^^^^^^^^ only allowed inside `async` functions and blocks error[E0728]: `await` is only allowed inside `async` functions and blocks - --> $DIR/incorrect-syntax-suggestions.rs:117:17 + --> $DIR/incorrect-syntax-suggestions.rs:115:17 | LL | fn foo() -> Result<(), ()> { | --- this is not `async` @@ -226,7 +226,7 @@ LL | let _ = await!(bar())?; | ^^^^^^^^^^^^^ only allowed inside `async` functions and blocks error[E0728]: `await` is only allowed inside `async` functions and blocks - --> $DIR/incorrect-syntax-suggestions.rs:125:17 + --> $DIR/incorrect-syntax-suggestions.rs:123:17 | LL | let foo = || { | -- this is not `async` @@ -234,7 +234,7 @@ LL | let _ = await!(bar())?; | ^^^^^^^^^^^^^ only allowed inside `async` functions and blocks error[E0277]: the `?` operator can only be applied to values that implement `std::ops::Try` - --> $DIR/incorrect-syntax-suggestions.rs:18:19 + --> $DIR/incorrect-syntax-suggestions.rs:16:19 | LL | let _ = await bar()?; | ^^^^^^ the `?` operator cannot be applied to type `impl std::future::Future` diff --git a/src/test/ui/async-await/await-unsize.rs b/src/test/ui/async-await/await-unsize.rs index d5e21257f4f..aa09d4bdf08 100644 --- a/src/test/ui/async-await/await-unsize.rs +++ b/src/test/ui/async-await/await-unsize.rs @@ -3,8 +3,6 @@ // check-pass // edition:2018 -#![feature(async_await)] - async fn make_boxed_object() -> Box<dyn Send> { Box::new(()) as _ } diff --git a/src/test/ui/async-await/bound-normalization.rs b/src/test/ui/async-await/bound-normalization.rs index 8026350aaf2..5d260682f1d 100644 --- a/src/test/ui/async-await/bound-normalization.rs +++ b/src/test/ui/async-await/bound-normalization.rs @@ -1,8 +1,6 @@ // check-pass // edition:2018 -#![feature(async_await)] - // See issue 60414 trait Trait { diff --git a/src/test/ui/async-await/conditional-and-guaranteed-initialization.rs b/src/test/ui/async-await/conditional-and-guaranteed-initialization.rs index a5947e7f718..56f4cbbd190 100644 --- a/src/test/ui/async-await/conditional-and-guaranteed-initialization.rs +++ b/src/test/ui/async-await/conditional-and-guaranteed-initialization.rs @@ -2,8 +2,6 @@ // edition:2018 // compile-flags: --crate-type lib -#![feature(async_await)] - async fn conditional_and_guaranteed_initialization(x: usize) -> usize { let y; if x > 5 { diff --git a/src/test/ui/async-await/dont-print-desugared-async.rs b/src/test/ui/async-await/dont-print-desugared-async.rs index 8150a260866..68341a24c4e 100644 --- a/src/test/ui/async-await/dont-print-desugared-async.rs +++ b/src/test/ui/async-await/dont-print-desugared-async.rs @@ -1,7 +1,6 @@ // Test that we don't show variables with from async fn desugaring // edition:2018 -#![feature(async_await)] async fn async_fn(&ref mut s: &[i32]) {} //~^ ERROR cannot borrow data in a `&` reference as mutable [E0596] diff --git a/src/test/ui/async-await/dont-print-desugared-async.stderr b/src/test/ui/async-await/dont-print-desugared-async.stderr index 47726ba65df..2bf1e77f09b 100644 --- a/src/test/ui/async-await/dont-print-desugared-async.stderr +++ b/src/test/ui/async-await/dont-print-desugared-async.stderr @@ -1,5 +1,5 @@ error[E0596]: cannot borrow data in a `&` reference as mutable - --> $DIR/dont-print-desugared-async.rs:6:20 + --> $DIR/dont-print-desugared-async.rs:5:20 | LL | async fn async_fn(&ref mut s: &[i32]) {} | -^^^^^^^^^ diff --git a/src/test/ui/async-await/dont-suggest-missing-await.rs b/src/test/ui/async-await/dont-suggest-missing-await.rs index d551ef57985..a8e5b38ec1d 100644 --- a/src/test/ui/async-await/dont-suggest-missing-await.rs +++ b/src/test/ui/async-await/dont-suggest-missing-await.rs @@ -2,8 +2,6 @@ // This test ensures we don't make the suggestion in bodies that aren't `async`. -#![feature(async_await)] - fn take_u32(x: u32) {} async fn make_u32() -> u32 { diff --git a/src/test/ui/async-await/dont-suggest-missing-await.stderr b/src/test/ui/async-await/dont-suggest-missing-await.stderr index c60b0d1f30e..c87e0bc221d 100644 --- a/src/test/ui/async-await/dont-suggest-missing-await.stderr +++ b/src/test/ui/async-await/dont-suggest-missing-await.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/dont-suggest-missing-await.rs:16:18 + --> $DIR/dont-suggest-missing-await.rs:14:18 | LL | take_u32(x) | ^ expected u32, found opaque type diff --git a/src/test/ui/async-await/drop-order/drop-order-for-async-fn-parameters-by-ref-binding.rs b/src/test/ui/async-await/drop-order/drop-order-for-async-fn-parameters-by-ref-binding.rs index dfd8b2e361e..9817d377a78 100644 --- a/src/test/ui/async-await/drop-order/drop-order-for-async-fn-parameters-by-ref-binding.rs +++ b/src/test/ui/async-await/drop-order/drop-order-for-async-fn-parameters-by-ref-binding.rs @@ -3,7 +3,6 @@ // run-pass #![allow(unused_variables)] -#![feature(async_await)] // Test that the drop order for parameters in a fn and async fn matches up. Also test that // parameters (used or unused) are not dropped until the async fn completes execution. diff --git a/src/test/ui/async-await/drop-order/drop-order-for-async-fn-parameters.rs b/src/test/ui/async-await/drop-order/drop-order-for-async-fn-parameters.rs index 2a74485afb4..00072786a50 100644 --- a/src/test/ui/async-await/drop-order/drop-order-for-async-fn-parameters.rs +++ b/src/test/ui/async-await/drop-order/drop-order-for-async-fn-parameters.rs @@ -3,7 +3,6 @@ // run-pass #![allow(unused_variables)] -#![feature(async_await)] // Test that the drop order for parameters in a fn and async fn matches up. Also test that // parameters (used or unused) are not dropped until the async fn completes execution. diff --git a/src/test/ui/async-await/drop-order/drop-order-for-locals-when-cancelled.rs b/src/test/ui/async-await/drop-order/drop-order-for-locals-when-cancelled.rs index db396d3957e..5d020c9a526 100644 --- a/src/test/ui/async-await/drop-order/drop-order-for-locals-when-cancelled.rs +++ b/src/test/ui/async-await/drop-order/drop-order-for-locals-when-cancelled.rs @@ -2,9 +2,7 @@ // edition:2018 // run-pass -#![allow(unused_variables)] #![deny(dead_code)] -#![feature(async_await)] // Test that the drop order for locals in a fn and async fn matches up. extern crate arc_wake; diff --git a/src/test/ui/async-await/drop-order/drop-order-locals-are-hidden.rs b/src/test/ui/async-await/drop-order/drop-order-locals-are-hidden.rs index bcdb8878eb5..79dedb1ba28 100644 --- a/src/test/ui/async-await/drop-order/drop-order-locals-are-hidden.rs +++ b/src/test/ui/async-await/drop-order/drop-order-locals-are-hidden.rs @@ -1,8 +1,5 @@ // edition:2018 -#![allow(unused_variables)] -#![feature(async_await)] - async fn foobar_async(x: u32, (a, _, _c): (u32, u32, u32), _: u32, _y: u32) { assert_eq!(__arg1, (1, 2, 3)); //~ ERROR cannot find value `__arg1` in this scope [E0425] assert_eq!(__arg2, 4); //~ ERROR cannot find value `__arg2` in this scope [E0425] diff --git a/src/test/ui/async-await/drop-order/drop-order-locals-are-hidden.stderr b/src/test/ui/async-await/drop-order/drop-order-locals-are-hidden.stderr index 484e1f4f426..aa04a613f47 100644 --- a/src/test/ui/async-await/drop-order/drop-order-locals-are-hidden.stderr +++ b/src/test/ui/async-await/drop-order/drop-order-locals-are-hidden.stderr @@ -1,23 +1,23 @@ error[E0425]: cannot find value `__arg1` in this scope - --> $DIR/drop-order-locals-are-hidden.rs:7:16 + --> $DIR/drop-order-locals-are-hidden.rs:4:16 | LL | assert_eq!(__arg1, (1, 2, 3)); | ^^^^^^ not found in this scope error[E0425]: cannot find value `__arg2` in this scope - --> $DIR/drop-order-locals-are-hidden.rs:8:16 + --> $DIR/drop-order-locals-are-hidden.rs:5:16 | LL | assert_eq!(__arg2, 4); | ^^^^^^ not found in this scope error[E0425]: cannot find value `__arg0` in this scope - --> $DIR/drop-order-locals-are-hidden.rs:12:16 + --> $DIR/drop-order-locals-are-hidden.rs:9:16 | LL | assert_eq!(__arg0, 1); | ^^^^^^ not found in this scope error[E0425]: cannot find value `__arg1` in this scope - --> $DIR/drop-order-locals-are-hidden.rs:13:16 + --> $DIR/drop-order-locals-are-hidden.rs:10:16 | LL | assert_eq!(__arg1, 2); | ^^^^^^ not found in this scope diff --git a/src/test/ui/async-await/drop-order/drop-order-when-cancelled.rs b/src/test/ui/async-await/drop-order/drop-order-when-cancelled.rs index 410a623681d..84fe79348c6 100644 --- a/src/test/ui/async-await/drop-order/drop-order-when-cancelled.rs +++ b/src/test/ui/async-await/drop-order/drop-order-when-cancelled.rs @@ -2,9 +2,6 @@ // edition:2018 // run-pass -#![allow(unused_variables)] -#![feature(async_await)] - // Test that the drop order for parameters in a fn and async fn matches up. Also test that // parameters (used or unused) are not dropped until the async fn is cancelled. // This file is mostly copy-pasted from drop-order-for-async-fn-parameters.rs diff --git a/src/test/ui/async-await/edition-deny-async-fns-2015.rs b/src/test/ui/async-await/edition-deny-async-fns-2015.rs index a5bc1810154..c85896150c2 100644 --- a/src/test/ui/async-await/edition-deny-async-fns-2015.rs +++ b/src/test/ui/async-await/edition-deny-async-fns-2015.rs @@ -1,7 +1,5 @@ // edition:2015 -#![feature(async_await)] - async fn foo() {} //~ ERROR `async fn` is not permitted in the 2015 edition fn baz() { async fn foo() {} } //~ ERROR `async fn` is not permitted in the 2015 edition diff --git a/src/test/ui/async-await/edition-deny-async-fns-2015.stderr b/src/test/ui/async-await/edition-deny-async-fns-2015.stderr index efb4462095d..d3f88af09d1 100644 --- a/src/test/ui/async-await/edition-deny-async-fns-2015.stderr +++ b/src/test/ui/async-await/edition-deny-async-fns-2015.stderr @@ -1,59 +1,59 @@ error[E0670]: `async fn` is not permitted in the 2015 edition - --> $DIR/edition-deny-async-fns-2015.rs:5:1 + --> $DIR/edition-deny-async-fns-2015.rs:3:1 | LL | async fn foo() {} | ^^^^^ error[E0670]: `async fn` is not permitted in the 2015 edition - --> $DIR/edition-deny-async-fns-2015.rs:7:12 + --> $DIR/edition-deny-async-fns-2015.rs:5:12 | LL | fn baz() { async fn foo() {} } | ^^^^^ error[E0670]: `async fn` is not permitted in the 2015 edition - --> $DIR/edition-deny-async-fns-2015.rs:10:5 + --> $DIR/edition-deny-async-fns-2015.rs:8:5 | LL | async fn bar() {} | ^^^^^ error[E0670]: `async fn` is not permitted in the 2015 edition - --> $DIR/edition-deny-async-fns-2015.rs:9:1 + --> $DIR/edition-deny-async-fns-2015.rs:7:1 | LL | async fn async_baz() { | ^^^^^ error[E0670]: `async fn` is not permitted in the 2015 edition - --> $DIR/edition-deny-async-fns-2015.rs:16:5 + --> $DIR/edition-deny-async-fns-2015.rs:14:5 | LL | async fn foo() {} | ^^^^^ error[E0670]: `async fn` is not permitted in the 2015 edition - --> $DIR/edition-deny-async-fns-2015.rs:20:5 + --> $DIR/edition-deny-async-fns-2015.rs:18:5 | LL | async fn foo() {} | ^^^^^ error[E0670]: `async fn` is not permitted in the 2015 edition - --> $DIR/edition-deny-async-fns-2015.rs:38:9 + --> $DIR/edition-deny-async-fns-2015.rs:36:9 | LL | async fn bar() {} | ^^^^^ error[E0670]: `async fn` is not permitted in the 2015 edition - --> $DIR/edition-deny-async-fns-2015.rs:28:9 + --> $DIR/edition-deny-async-fns-2015.rs:26:9 | LL | async fn foo() {} | ^^^^^ error[E0670]: `async fn` is not permitted in the 2015 edition - --> $DIR/edition-deny-async-fns-2015.rs:33:13 + --> $DIR/edition-deny-async-fns-2015.rs:31:13 | LL | async fn bar() {} | ^^^^^ error[E0706]: trait fns cannot be declared `async` - --> $DIR/edition-deny-async-fns-2015.rs:20:5 + --> $DIR/edition-deny-async-fns-2015.rs:18:5 | LL | async fn foo() {} | ^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/async-await/generics-and-bounds.rs b/src/test/ui/async-await/generics-and-bounds.rs index 8b60f2f82f1..963b19b34a6 100644 --- a/src/test/ui/async-await/generics-and-bounds.rs +++ b/src/test/ui/async-await/generics-and-bounds.rs @@ -2,8 +2,6 @@ // edition:2018 // compile-flags: --crate-type lib -#![feature(async_await)] - use std::future::Future; pub async fn simple_generic<T>() {} diff --git a/src/test/ui/async-await/issue-60709.rs b/src/test/ui/async-await/issue-60709.rs index ad0b49fa4a2..9ee419c4a56 100644 --- a/src/test/ui/async-await/issue-60709.rs +++ b/src/test/ui/async-await/issue-60709.rs @@ -4,9 +4,6 @@ // run-pass -#![feature(async_await)] -#![allow(unused)] - use std::future::Future; use std::task::Poll; use std::task::Context; diff --git a/src/test/ui/async-await/issue-61452.rs b/src/test/ui/async-await/issue-61452.rs index 20b9b645dae..9381251ad69 100644 --- a/src/test/ui/async-await/issue-61452.rs +++ b/src/test/ui/async-await/issue-61452.rs @@ -1,5 +1,4 @@ // edition:2018 -#![feature(async_await)] pub async fn f(x: Option<usize>) { x.take(); diff --git a/src/test/ui/async-await/issue-61452.stderr b/src/test/ui/async-await/issue-61452.stderr index 742490d8de4..5eb4b548717 100644 --- a/src/test/ui/async-await/issue-61452.stderr +++ b/src/test/ui/async-await/issue-61452.stderr @@ -1,5 +1,5 @@ error[E0596]: cannot borrow `x` as mutable, as it is not declared as mutable - --> $DIR/issue-61452.rs:5:5 + --> $DIR/issue-61452.rs:4:5 | LL | pub async fn f(x: Option<usize>) { | - help: consider changing this to be mutable: `mut x` @@ -7,7 +7,7 @@ LL | x.take(); | ^ cannot borrow as mutable error[E0384]: cannot assign twice to immutable variable `x` - --> $DIR/issue-61452.rs:10:5 + --> $DIR/issue-61452.rs:9:5 | LL | pub async fn g(x: usize) { | - diff --git a/src/test/ui/async-await/issue-61793.rs b/src/test/ui/async-await/issue-61793.rs index a18fad8bb91..f6084be9167 100644 --- a/src/test/ui/async-await/issue-61793.rs +++ b/src/test/ui/async-await/issue-61793.rs @@ -6,9 +6,6 @@ // build-pass (FIXME(62277): could be check-pass?) // edition:2018 -#![feature(async_await)] -#![allow(unused)] - async fn foo<F>(_: &(), _: F) {} fn main() { diff --git a/src/test/ui/async-await/issue-61949-self-return-type.rs b/src/test/ui/async-await/issue-61949-self-return-type.rs index c5a66d5d4a3..6a28c69193d 100644 --- a/src/test/ui/async-await/issue-61949-self-return-type.rs +++ b/src/test/ui/async-await/issue-61949-self-return-type.rs @@ -1,6 +1,5 @@ // ignore-tidy-linelength // edition:2018 -#![feature(async_await)] // This test checks that `Self` is prohibited as a return type. See #61949 for context. diff --git a/src/test/ui/async-await/issue-61949-self-return-type.stderr b/src/test/ui/async-await/issue-61949-self-return-type.stderr index a9ae544502d..12fb77d8dd6 100644 --- a/src/test/ui/async-await/issue-61949-self-return-type.stderr +++ b/src/test/ui/async-await/issue-61949-self-return-type.stderr @@ -1,5 +1,5 @@ error: `async fn` return type cannot contain a projection or `Self` that references lifetimes from a parent scope - --> $DIR/issue-61949-self-return-type.rs:12:40 + --> $DIR/issue-61949-self-return-type.rs:11:40 | LL | pub async fn new(_bar: &'a i32) -> Self { | ^^^^ diff --git a/src/test/ui/async-await/issue-62658.rs b/src/test/ui/async-await/issue-62658.rs index 90fbb47bffd..d0af01e0c00 100644 --- a/src/test/ui/async-await/issue-62658.rs +++ b/src/test/ui/async-await/issue-62658.rs @@ -4,8 +4,6 @@ // build-pass // edition:2018 -#![feature(async_await)] - async fn noop() {} async fn foo() { diff --git a/src/test/ui/async-await/issues/issue-51719.rs b/src/test/ui/async-await/issues/issue-51719.rs index 361a49c2774..09241f982aa 100644 --- a/src/test/ui/async-await/issues/issue-51719.rs +++ b/src/test/ui/async-await/issues/issue-51719.rs @@ -2,8 +2,6 @@ // // Tests that the .await syntax can't be used to make a generator -#![feature(async_await)] - async fn foo() {} fn make_generator() { diff --git a/src/test/ui/async-await/issues/issue-51719.stderr b/src/test/ui/async-await/issues/issue-51719.stderr index 2a9fb6cf0df..6c3c8889da7 100644 --- a/src/test/ui/async-await/issues/issue-51719.stderr +++ b/src/test/ui/async-await/issues/issue-51719.stderr @@ -1,5 +1,5 @@ error[E0728]: `await` is only allowed inside `async` functions and blocks - --> $DIR/issue-51719.rs:10:19 + --> $DIR/issue-51719.rs:8:19 | LL | let _gen = || foo().await; | -- ^^^^^^^^^^^ only allowed inside `async` functions and blocks diff --git a/src/test/ui/async-await/issues/issue-51751.rs b/src/test/ui/async-await/issues/issue-51751.rs index 7afd7ecc826..bc85a96cea9 100644 --- a/src/test/ui/async-await/issues/issue-51751.rs +++ b/src/test/ui/async-await/issues/issue-51751.rs @@ -1,7 +1,5 @@ // edition:2018 -#![feature(async_await)] - async fn inc(limit: i64) -> i64 { limit + 1 } diff --git a/src/test/ui/async-await/issues/issue-51751.stderr b/src/test/ui/async-await/issues/issue-51751.stderr index 97b63d1590e..e50c78534f8 100644 --- a/src/test/ui/async-await/issues/issue-51751.stderr +++ b/src/test/ui/async-await/issues/issue-51751.stderr @@ -1,5 +1,5 @@ error[E0728]: `await` is only allowed inside `async` functions and blocks - --> $DIR/issue-51751.rs:11:20 + --> $DIR/issue-51751.rs:9:20 | LL | fn main() { | ---- this is not `async` diff --git a/src/test/ui/async-await/issues/issue-53249.rs b/src/test/ui/async-await/issues/issue-53249.rs index c57dc6b0ef6..5cae0704444 100644 --- a/src/test/ui/async-await/issues/issue-53249.rs +++ b/src/test/ui/async-await/issues/issue-53249.rs @@ -1,7 +1,7 @@ // build-pass (FIXME(62277): could be check-pass?) // edition:2018 -#![feature(arbitrary_self_types, async_await)] +#![feature(arbitrary_self_types)] use std::task::{self, Poll}; use std::future::Future; diff --git a/src/test/ui/async-await/issues/issue-54752-async-block.rs b/src/test/ui/async-await/issues/issue-54752-async-block.rs index 0036de90b25..64f260cfe01 100644 --- a/src/test/ui/async-await/issues/issue-54752-async-block.rs +++ b/src/test/ui/async-await/issues/issue-54752-async-block.rs @@ -3,7 +3,4 @@ // edition:2018 // pp-exact -#![feature(async_await)] -#![allow(unused_parens)] - fn main() { let _a = (async { }); } diff --git a/src/test/ui/async-await/issues/issue-54974.rs b/src/test/ui/async-await/issues/issue-54974.rs index 040989b33fc..9adc0a82323 100644 --- a/src/test/ui/async-await/issues/issue-54974.rs +++ b/src/test/ui/async-await/issues/issue-54974.rs @@ -1,8 +1,6 @@ // build-pass (FIXME(62277): could be check-pass?) // edition:2018 -#![feature(async_await)] - use std::sync::Arc; trait SomeTrait: Send + Sync + 'static { diff --git a/src/test/ui/async-await/issues/issue-55324.rs b/src/test/ui/async-await/issues/issue-55324.rs index 4f383a51a88..1d77d420127 100644 --- a/src/test/ui/async-await/issues/issue-55324.rs +++ b/src/test/ui/async-await/issues/issue-55324.rs @@ -1,11 +1,8 @@ // build-pass (FIXME(62277): could be check-pass?) // edition:2018 -#![feature(async_await)] - use std::future::Future; -#[allow(unused)] async fn foo<F: Future<Output = i32>>(x: &i32, future: F) -> i32 { let y = future.await; *x + y diff --git a/src/test/ui/async-await/issues/issue-55809.rs b/src/test/ui/async-await/issues/issue-55809.rs index b7e60b773b4..3b271775a38 100644 --- a/src/test/ui/async-await/issues/issue-55809.rs +++ b/src/test/ui/async-await/issues/issue-55809.rs @@ -1,8 +1,6 @@ // edition:2018 // run-pass -#![feature(async_await)] - trait Foo { } impl Foo for () { } diff --git a/src/test/ui/async-await/issues/issue-58885.rs b/src/test/ui/async-await/issues/issue-58885.rs index 47744aeea60..72a45b5007d 100644 --- a/src/test/ui/async-await/issues/issue-58885.rs +++ b/src/test/ui/async-await/issues/issue-58885.rs @@ -1,8 +1,6 @@ // build-pass (FIXME(62277): could be check-pass?) // edition:2018 -#![feature(async_await)] - struct Xyz { a: u64, } diff --git a/src/test/ui/async-await/issues/issue-59001.rs b/src/test/ui/async-await/issues/issue-59001.rs index 9334ddb0af5..ea780d9f622 100644 --- a/src/test/ui/async-await/issues/issue-59001.rs +++ b/src/test/ui/async-await/issues/issue-59001.rs @@ -1,11 +1,8 @@ // build-pass (FIXME(62277): could be check-pass?) // edition:2018 -#![feature(async_await)] - use std::future::Future; -#[allow(unused)] async fn enter<'a, F, R>(mut callback: F) where F: FnMut(&'a mut i32) -> R, diff --git a/src/test/ui/async-await/issues/issue-59972.rs b/src/test/ui/async-await/issues/issue-59972.rs index 8f4254b10ce..154226e8bb8 100644 --- a/src/test/ui/async-await/issues/issue-59972.rs +++ b/src/test/ui/async-await/issues/issue-59972.rs @@ -6,8 +6,6 @@ // compile-flags: --edition=2018 -#![feature(async_await)] - pub enum Uninhabited { } fn uninhabited_async() -> Uninhabited { @@ -16,14 +14,12 @@ fn uninhabited_async() -> Uninhabited { async fn noop() { } -#[allow(unused)] async fn contains_never() { let error = uninhabited_async(); noop().await; let error2 = error; } -#[allow(unused)] async fn overlap_never() { let error1 = uninhabited_async(); noop().await; @@ -35,6 +31,4 @@ async fn overlap_never() { #[allow(unused_must_use)] fn main() { - contains_never(); - overlap_never(); } diff --git a/src/test/ui/async-await/issues/issue-60518.rs b/src/test/ui/async-await/issues/issue-60518.rs index e4bdc96511e..1ca05160751 100644 --- a/src/test/ui/async-await/issues/issue-60518.rs +++ b/src/test/ui/async-await/issues/issue-60518.rs @@ -1,8 +1,6 @@ // build-pass (FIXME(62277): could be check-pass?) // edition:2018 -#![feature(async_await)] - // This is a regression test to ensure that simple bindings (where replacement arguments aren't // created during async fn lowering) that have their DefId used during HIR lowering (such as impl // trait) are visited during def collection and thus have a DefId. diff --git a/src/test/ui/async-await/issues/issue-60655-latebound-regions.rs b/src/test/ui/async-await/issues/issue-60655-latebound-regions.rs index 99213e64d16..0d015e54f8b 100644 --- a/src/test/ui/async-await/issues/issue-60655-latebound-regions.rs +++ b/src/test/ui/async-await/issues/issue-60655-latebound-regions.rs @@ -3,7 +3,6 @@ // build-pass (FIXME(62277): could be check-pass?) // edition:2018 -#![feature(async_await)] #![feature(type_alias_impl_trait)] use std::future::Future; diff --git a/src/test/ui/async-await/issues/issue-60674.rs b/src/test/ui/async-await/issues/issue-60674.rs index 99cdcbafc76..c0e34a8df77 100644 --- a/src/test/ui/async-await/issues/issue-60674.rs +++ b/src/test/ui/async-await/issues/issue-60674.rs @@ -1,7 +1,6 @@ // aux-build:issue-60674.rs // build-pass (FIXME(62277): could be check-pass?) // edition:2018 -#![feature(async_await)] // This is a regression test that ensures that `mut` patterns are not lost when provided as input // to a proc macro. diff --git a/src/test/ui/async-await/issues/issue-61187.rs b/src/test/ui/async-await/issues/issue-61187.rs index 8b939b43b8b..8585a425111 100644 --- a/src/test/ui/async-await/issues/issue-61187.rs +++ b/src/test/ui/async-await/issues/issue-61187.rs @@ -1,8 +1,6 @@ // edition:2018 -#![feature(async_await)] -fn main() { -} +fn main() {} async fn response(data: Vec<u8>) { data.reverse(); //~ ERROR E0596 diff --git a/src/test/ui/async-await/issues/issue-61187.stderr b/src/test/ui/async-await/issues/issue-61187.stderr index a0314226320..4d361c824dd 100644 --- a/src/test/ui/async-await/issues/issue-61187.stderr +++ b/src/test/ui/async-await/issues/issue-61187.stderr @@ -1,5 +1,5 @@ error[E0596]: cannot borrow `data` as mutable, as it is not declared as mutable - --> $DIR/issue-61187.rs:8:5 + --> $DIR/issue-61187.rs:6:5 | LL | async fn response(data: Vec<u8>) { | ---- help: consider changing this to be mutable: `mut data` diff --git a/src/test/ui/async-await/issues/issue-61986.rs b/src/test/ui/async-await/issues/issue-61986.rs index 77ecc47dfef..879bc6912fc 100644 --- a/src/test/ui/async-await/issues/issue-61986.rs +++ b/src/test/ui/async-await/issues/issue-61986.rs @@ -4,8 +4,6 @@ // Tests that we properly handle StorageDead/StorageLives for temporaries // created in async loop bodies. -#![feature(async_await)] - async fn bar() -> Option<()> { Some(()) } diff --git a/src/test/ui/async-await/issues/issue-62009-1.rs b/src/test/ui/async-await/issues/issue-62009-1.rs index ac6605bceff..3ee7ab2e9d1 100644 --- a/src/test/ui/async-await/issues/issue-62009-1.rs +++ b/src/test/ui/async-await/issues/issue-62009-1.rs @@ -1,7 +1,5 @@ // edition:2018 -#![feature(async_await)] - async fn print_dur() {} fn main() { diff --git a/src/test/ui/async-await/issues/issue-62009-1.stderr b/src/test/ui/async-await/issues/issue-62009-1.stderr index 2bbb6d079ea..cd155f0fc32 100644 --- a/src/test/ui/async-await/issues/issue-62009-1.stderr +++ b/src/test/ui/async-await/issues/issue-62009-1.stderr @@ -1,5 +1,5 @@ error[E0728]: `await` is only allowed inside `async` functions and blocks - --> $DIR/issue-62009-1.rs:8:5 + --> $DIR/issue-62009-1.rs:6:5 | LL | fn main() { | ---- this is not `async` @@ -7,7 +7,7 @@ LL | async { let (); }.await; | ^^^^^^^^^^^^^^^^^^^^^^^ only allowed inside `async` functions and blocks error[E0728]: `await` is only allowed inside `async` functions and blocks - --> $DIR/issue-62009-1.rs:10:5 + --> $DIR/issue-62009-1.rs:8:5 | LL | fn main() { | ---- this is not `async` @@ -19,7 +19,7 @@ LL | | }.await; | |___________^ only allowed inside `async` functions and blocks error[E0728]: `await` is only allowed inside `async` functions and blocks - --> $DIR/issue-62009-1.rs:14:5 + --> $DIR/issue-62009-1.rs:12:5 | LL | fn main() { | ---- this is not `async` @@ -27,11 +27,11 @@ LL | fn main() { LL | (|_| 2333).await; | ^^^^^^^^^^^^^^^^ only allowed inside `async` functions and blocks -error[E0277]: the trait bound `[closure@$DIR/issue-62009-1.rs:14:5: 14:15]: std::future::Future` is not satisfied - --> $DIR/issue-62009-1.rs:14:5 +error[E0277]: the trait bound `[closure@$DIR/issue-62009-1.rs:12:5: 12:15]: std::future::Future` is not satisfied + --> $DIR/issue-62009-1.rs:12:5 | LL | (|_| 2333).await; - | ^^^^^^^^^^^^^^^^ the trait `std::future::Future` is not implemented for `[closure@$DIR/issue-62009-1.rs:14:5: 14:15]` + | ^^^^^^^^^^^^^^^^ the trait `std::future::Future` is not implemented for `[closure@$DIR/issue-62009-1.rs:12:5: 12:15]` | = note: required by `std::future::poll_with_tls_context` diff --git a/src/test/ui/async-await/issues/issue-62009-2.rs b/src/test/ui/async-await/issues/issue-62009-2.rs index 52b62eaa9e0..cb7336e6134 100644 --- a/src/test/ui/async-await/issues/issue-62009-2.rs +++ b/src/test/ui/async-await/issues/issue-62009-2.rs @@ -1,6 +1,6 @@ // edition:2018 -#![feature(async_await, async_closure)] +#![feature(async_closure)] async fn print_dur() {} diff --git a/src/test/ui/async-await/issues/issue-62517-1.rs b/src/test/ui/async-await/issues/issue-62517-1.rs index 5955d9751af..4689ce36a78 100644 --- a/src/test/ui/async-await/issues/issue-62517-1.rs +++ b/src/test/ui/async-await/issues/issue-62517-1.rs @@ -5,8 +5,6 @@ // edition:2018 // check-pass -#![feature(async_await)] - trait FirstTrait {} trait SecondTrait { type Item: ?Sized; diff --git a/src/test/ui/async-await/issues/issue-62517-2.rs b/src/test/ui/async-await/issues/issue-62517-2.rs index 17fac408151..aaf28d6c132 100644 --- a/src/test/ui/async-await/issues/issue-62517-2.rs +++ b/src/test/ui/async-await/issues/issue-62517-2.rs @@ -5,8 +5,6 @@ // edition:2018 // check-pass -#![feature(async_await)] - trait Object {} trait Alpha<Param: ?Sized> {} diff --git a/src/test/ui/async-await/issues/issue-63388-1.nll.stderr b/src/test/ui/async-await/issues/issue-63388-1.nll.stderr index 64fd1a4a78d..22610fe54a4 100644 --- a/src/test/ui/async-await/issues/issue-63388-1.nll.stderr +++ b/src/test/ui/async-await/issues/issue-63388-1.nll.stderr @@ -1,5 +1,5 @@ error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds - --> $DIR/issue-63388-1.rs:14:10 + --> $DIR/issue-63388-1.rs:12:10 | LL | ) -> &dyn Foo | ^^^^^^^^ @@ -7,7 +7,7 @@ LL | ) -> &dyn Foo = note: hidden type `impl std::future::Future` captures lifetime '_#22r error: lifetime may not live long enough - --> $DIR/issue-63388-1.rs:15:5 + --> $DIR/issue-63388-1.rs:13:5 | LL | async fn do_sth<'a>( | -- lifetime `'a` defined here diff --git a/src/test/ui/async-await/issues/issue-63388-1.rs b/src/test/ui/async-await/issues/issue-63388-1.rs index 80003b0d701..3cde5de2198 100644 --- a/src/test/ui/async-await/issues/issue-63388-1.rs +++ b/src/test/ui/async-await/issues/issue-63388-1.rs @@ -1,7 +1,5 @@ // edition:2018 -#![feature(async_await)] - struct Xyz { a: u64, } diff --git a/src/test/ui/async-await/issues/issue-63388-1.stderr b/src/test/ui/async-await/issues/issue-63388-1.stderr index 5302adce5a0..a54cadb0cd2 100644 --- a/src/test/ui/async-await/issues/issue-63388-1.stderr +++ b/src/test/ui/async-await/issues/issue-63388-1.stderr @@ -1,5 +1,5 @@ error[E0623]: lifetime mismatch - --> $DIR/issue-63388-1.rs:14:10 + --> $DIR/issue-63388-1.rs:12:10 | LL | &'a self, foo: &dyn Foo | -------- this parameter and the return type are declared with different lifetimes... diff --git a/src/test/ui/async-await/issues/issue-63388-2.nll.stderr b/src/test/ui/async-await/issues/issue-63388-2.nll.stderr index b91cdc1b770..7781af89dea 100644 --- a/src/test/ui/async-await/issues/issue-63388-2.nll.stderr +++ b/src/test/ui/async-await/issues/issue-63388-2.nll.stderr @@ -1,5 +1,5 @@ error[E0106]: missing lifetime specifier - --> $DIR/issue-63388-2.rs:14:10 + --> $DIR/issue-63388-2.rs:12:10 | LL | ) -> &dyn Foo | ^ help: consider using the named lifetime: `&'a` diff --git a/src/test/ui/async-await/issues/issue-63388-2.rs b/src/test/ui/async-await/issues/issue-63388-2.rs index ca9bbef0d50..73e7f25f97d 100644 --- a/src/test/ui/async-await/issues/issue-63388-2.rs +++ b/src/test/ui/async-await/issues/issue-63388-2.rs @@ -1,7 +1,5 @@ // edition:2018 -#![feature(async_await)] - struct Xyz { a: u64, } diff --git a/src/test/ui/async-await/issues/issue-63388-2.stderr b/src/test/ui/async-await/issues/issue-63388-2.stderr index 1810138dc80..1edeb3d5493 100644 --- a/src/test/ui/async-await/issues/issue-63388-2.stderr +++ b/src/test/ui/async-await/issues/issue-63388-2.stderr @@ -1,5 +1,5 @@ error[E0106]: missing lifetime specifier - --> $DIR/issue-63388-2.rs:14:10 + --> $DIR/issue-63388-2.rs:12:10 | LL | ) -> &dyn Foo | ^ help: consider using the named lifetime: `&'a` @@ -7,19 +7,19 @@ LL | ) -> &dyn Foo = help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from `foo` or `bar` error: cannot infer an appropriate lifetime - --> $DIR/issue-63388-2.rs:13:9 + --> $DIR/issue-63388-2.rs:11:9 | LL | foo: &dyn Foo, bar: &'a dyn Foo | ^^^ ...but this borrow... LL | ) -> &dyn Foo | -------- this return type evaluates to the `'static` lifetime... | -note: ...can't outlive the lifetime '_ as defined on the method body at 13:14 - --> $DIR/issue-63388-2.rs:13:14 +note: ...can't outlive the lifetime '_ as defined on the method body at 11:14 + --> $DIR/issue-63388-2.rs:11:14 | LL | foo: &dyn Foo, bar: &'a dyn Foo | ^ -help: you can add a constraint to the return type to make it last less than `'static` and match the lifetime '_ as defined on the method body at 13:14 +help: you can add a constraint to the return type to make it last less than `'static` and match the lifetime '_ as defined on the method body at 11:14 | LL | ) -> &dyn Foo + '_ | ^^^^^^^^^^^^^ diff --git a/src/test/ui/async-await/issues/issue-63388-3.rs b/src/test/ui/async-await/issues/issue-63388-3.rs index 05f23f95965..1a9822e02fa 100644 --- a/src/test/ui/async-await/issues/issue-63388-3.rs +++ b/src/test/ui/async-await/issues/issue-63388-3.rs @@ -1,8 +1,6 @@ // edition:2018 // check-pass -#![feature(async_await)] - struct Xyz { a: u64, } diff --git a/src/test/ui/async-await/issues/issue-63388-4.rs b/src/test/ui/async-await/issues/issue-63388-4.rs index 0939242d7fc..58f9dacb3bc 100644 --- a/src/test/ui/async-await/issues/issue-63388-4.rs +++ b/src/test/ui/async-await/issues/issue-63388-4.rs @@ -1,8 +1,6 @@ // check-pass // edition:2018 -#![feature(async_await)] - struct A; impl A { diff --git a/src/test/ui/async-await/issues/non-async-enclosing-span.rs b/src/test/ui/async-await/issues/non-async-enclosing-span.rs index 838911d9b6e..d47c2137725 100644 --- a/src/test/ui/async-await/issues/non-async-enclosing-span.rs +++ b/src/test/ui/async-await/issues/non-async-enclosing-span.rs @@ -1,5 +1,4 @@ // edition:2018 -#![feature(async_await)] async fn do_the_thing() -> u8 { 8 diff --git a/src/test/ui/async-await/issues/non-async-enclosing-span.stderr b/src/test/ui/async-await/issues/non-async-enclosing-span.stderr index f492c1a8045..49ebf414c55 100644 --- a/src/test/ui/async-await/issues/non-async-enclosing-span.stderr +++ b/src/test/ui/async-await/issues/non-async-enclosing-span.stderr @@ -1,5 +1,5 @@ error[E0728]: `await` is only allowed inside `async` functions and blocks - --> $DIR/non-async-enclosing-span.rs:10:13 + --> $DIR/non-async-enclosing-span.rs:9:13 | LL | fn main() { | ---- this is not `async` diff --git a/src/test/ui/async-await/move-part-await-return-rest-struct.rs b/src/test/ui/async-await/move-part-await-return-rest-struct.rs index 9bd7a515cbd..39ea2aae563 100644 --- a/src/test/ui/async-await/move-part-await-return-rest-struct.rs +++ b/src/test/ui/async-await/move-part-await-return-rest-struct.rs @@ -2,8 +2,6 @@ // edition:2018 // compile-flags: --crate-type lib -#![feature(async_await)] - struct Small { x: Vec<usize>, y: Vec<usize>, diff --git a/src/test/ui/async-await/move-part-await-return-rest-tuple.rs b/src/test/ui/async-await/move-part-await-return-rest-tuple.rs index 69eee855e75..7b958b98b41 100644 --- a/src/test/ui/async-await/move-part-await-return-rest-tuple.rs +++ b/src/test/ui/async-await/move-part-await-return-rest-tuple.rs @@ -2,8 +2,6 @@ // edition:2018 // compile-flags: --crate-type lib -#![feature(async_await)] - async fn move_part_await_return_rest_tuple() -> Vec<usize> { let x = (vec![3], vec![4, 4]); drop(x.1); diff --git a/src/test/ui/async-await/multiple-lifetimes/elided.rs b/src/test/ui/async-await/multiple-lifetimes/elided.rs index 45f3170d4c3..8258e2eff52 100644 --- a/src/test/ui/async-await/multiple-lifetimes/elided.rs +++ b/src/test/ui/async-await/multiple-lifetimes/elided.rs @@ -3,8 +3,6 @@ // Test that we can use async fns with multiple arbitrary lifetimes. -#![feature(async_await)] - async fn multiple_elided_lifetimes(_: &u8, _: &u8) {} fn main() { diff --git a/src/test/ui/async-await/multiple-lifetimes/fn-ptr.rs b/src/test/ui/async-await/multiple-lifetimes/fn-ptr.rs index a7254cee755..3912b854747 100644 --- a/src/test/ui/async-await/multiple-lifetimes/fn-ptr.rs +++ b/src/test/ui/async-await/multiple-lifetimes/fn-ptr.rs @@ -3,8 +3,6 @@ // Test that we can use async fns with multiple arbitrary lifetimes. -#![feature(async_await)] - async fn multiple_named_lifetimes<'a, 'b>(_: &'a u8, _: &'b u8, _: fn(&u8)) {} fn gimme(_: &u8) { } diff --git a/src/test/ui/async-await/multiple-lifetimes/hrtb.rs b/src/test/ui/async-await/multiple-lifetimes/hrtb.rs index 589e260d084..31d0736ba63 100644 --- a/src/test/ui/async-await/multiple-lifetimes/hrtb.rs +++ b/src/test/ui/async-await/multiple-lifetimes/hrtb.rs @@ -3,9 +3,6 @@ // Test that we can use async fns with multiple arbitrary lifetimes. -#![feature(async_await)] -#![allow(dead_code)] - use std::ops::Add; async fn multiple_hrtb_and_single_named_lifetime_ok<'c>( diff --git a/src/test/ui/async-await/multiple-lifetimes/named.rs b/src/test/ui/async-await/multiple-lifetimes/named.rs index cd479e256b4..e8eb98102f4 100644 --- a/src/test/ui/async-await/multiple-lifetimes/named.rs +++ b/src/test/ui/async-await/multiple-lifetimes/named.rs @@ -3,8 +3,6 @@ // Test that we can use async fns with multiple arbitrary lifetimes. -#![feature(async_await)] - async fn multiple_named_lifetimes<'a, 'b>(_: &'a u8, _: &'b u8) {} fn main() { diff --git a/src/test/ui/async-await/multiple-lifetimes/partial-relation.rs b/src/test/ui/async-await/multiple-lifetimes/partial-relation.rs index 903c43950a5..02b105999f5 100644 --- a/src/test/ui/async-await/multiple-lifetimes/partial-relation.rs +++ b/src/test/ui/async-await/multiple-lifetimes/partial-relation.rs @@ -1,8 +1,6 @@ // edition:2018 // run-pass -#![feature(async_await)] - async fn lotsa_lifetimes<'a, 'b, 'c>(a: &'a u32, b: &'b u32, c: &'c u32) -> (&'a u32, &'b u32) where 'b: 'a { diff --git a/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-fg.rs b/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-fg.rs index 08622311f7b..b901b61aa18 100644 --- a/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-fg.rs +++ b/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-fg.rs @@ -4,7 +4,7 @@ // Test that a feature gate is needed to use `impl Trait` as the // return type of an async. -#![feature(async_await, member_constraints)] +#![feature(member_constraints)] trait Trait<'a, 'b> { } impl<T> Trait<'_, '_> for T { } diff --git a/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-no-fg.rs b/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-no-fg.rs index 08ecea4cc85..2c7a5cd378f 100644 --- a/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-no-fg.rs +++ b/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-no-fg.rs @@ -3,8 +3,6 @@ // Test that a feature gate is needed to use `impl Trait` as the // return type of an async. -#![feature(async_await)] - trait Trait<'a, 'b> { } impl<T> Trait<'_, '_> for T { } diff --git a/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-no-fg.stderr b/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-no-fg.stderr index de2c85d772a..59d7728d41c 100644 --- a/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-no-fg.stderr +++ b/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-no-fg.stderr @@ -1,5 +1,5 @@ error: ambiguous lifetime bound in `impl Trait` - --> $DIR/ret-impl-trait-no-fg.rs:11:64 + --> $DIR/ret-impl-trait-no-fg.rs:9:64 | LL | async fn async_ret_impl_trait<'a, 'b>(a: &'a u8, b: &'b u8) -> impl Trait<'a, 'b> { | ^^^^^^^^^^^^^^^^^^ neither `'a` nor `'b` outlives the other diff --git a/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.rs b/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.rs index e1b71465273..babc90a5e96 100644 --- a/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.rs +++ b/src/test/ui/async-await/multiple-lifetimes/ret-impl-trait-one.rs @@ -3,7 +3,7 @@ // Test that a feature gate is needed to use `impl Trait` as the // return type of an async. -#![feature(async_await, member_constraints)] +#![feature(member_constraints)] trait Trait<'a> { } impl<T> Trait<'_> for T { } diff --git a/src/test/ui/async-await/multiple-lifetimes/ret-ref.rs b/src/test/ui/async-await/multiple-lifetimes/ret-ref.rs index 98da90161e5..149c020f9cb 100644 --- a/src/test/ui/async-await/multiple-lifetimes/ret-ref.rs +++ b/src/test/ui/async-await/multiple-lifetimes/ret-ref.rs @@ -4,8 +4,6 @@ // function (which takes multiple lifetimes) only returns data from // one of them. -#![feature(async_await)] - async fn multiple_named_lifetimes<'a, 'b>(a: &'a u8, _: &'b u8) -> &'a u8 { a } diff --git a/src/test/ui/async-await/multiple-lifetimes/ret-ref.stderr b/src/test/ui/async-await/multiple-lifetimes/ret-ref.stderr index fe70d35942c..d86e84033b8 100644 --- a/src/test/ui/async-await/multiple-lifetimes/ret-ref.stderr +++ b/src/test/ui/async-await/multiple-lifetimes/ret-ref.stderr @@ -1,5 +1,5 @@ error[E0506]: cannot assign to `a` because it is borrowed - --> $DIR/ret-ref.rs:18:5 + --> $DIR/ret-ref.rs:16:5 | LL | let future = multiple_named_lifetimes(&a, &b); | -- borrow of `a` occurs here @@ -10,7 +10,7 @@ LL | let p = future.await; | ------ borrow later used here error[E0506]: cannot assign to `b` because it is borrowed - --> $DIR/ret-ref.rs:19:5 + --> $DIR/ret-ref.rs:17:5 | LL | let future = multiple_named_lifetimes(&a, &b); | -- borrow of `b` occurs here @@ -21,7 +21,7 @@ LL | let p = future.await; | ------ borrow later used here error[E0506]: cannot assign to `a` because it is borrowed - --> $DIR/ret-ref.rs:30:5 + --> $DIR/ret-ref.rs:28:5 | LL | let future = multiple_named_lifetimes(&a, &b); | -- borrow of `a` occurs here diff --git a/src/test/ui/async-await/multiple-lifetimes/variance.rs b/src/test/ui/async-await/multiple-lifetimes/variance.rs index b52ad17d563..6ed8bef956a 100644 --- a/src/test/ui/async-await/multiple-lifetimes/variance.rs +++ b/src/test/ui/async-await/multiple-lifetimes/variance.rs @@ -4,9 +4,6 @@ // Test for async fn where the parameters have distinct lifetime // parameters that appear in all possible variances. -#![feature(async_await)] - -#[allow(dead_code)] async fn lotsa_lifetimes<'a, 'b, 'c>(_: fn(&'a u8), _: fn(&'b u8) -> &'b u8, _: fn() -> &'c u8) { } fn take_any(_: &u8) { } diff --git a/src/test/ui/async-await/nested-in-impl.rs b/src/test/ui/async-await/nested-in-impl.rs index 3c82160595f..76ed827d597 100644 --- a/src/test/ui/async-await/nested-in-impl.rs +++ b/src/test/ui/async-await/nested-in-impl.rs @@ -4,8 +4,6 @@ // check-pass // edition:2018 -#![feature(async_await)] - struct Foo<'a>(&'a ()); impl<'a> Foo<'a> { diff --git a/src/test/ui/async-await/no-args-non-move-async-closure.rs b/src/test/ui/async-await/no-args-non-move-async-closure.rs index 62d4b3fb6f2..0ca50807f26 100644 --- a/src/test/ui/async-await/no-args-non-move-async-closure.rs +++ b/src/test/ui/async-await/no-args-non-move-async-closure.rs @@ -1,6 +1,6 @@ // edition:2018 -#![feature(async_await, async_closure)] +#![feature(async_closure)] fn main() { let _ = async |x: u8| {}; diff --git a/src/test/ui/async-await/no-async-const.rs b/src/test/ui/async-await/no-async-const.rs index 1db314a5aa2..7a6eb498b2e 100644 --- a/src/test/ui/async-await/no-async-const.rs +++ b/src/test/ui/async-await/no-async-const.rs @@ -2,7 +2,5 @@ // edition:2018 // compile-flags: --crate-type lib -#![feature(async_await)] - pub async const fn x() {} //~^ ERROR expected one of `fn` or `unsafe`, found `const` diff --git a/src/test/ui/async-await/no-async-const.stderr b/src/test/ui/async-await/no-async-const.stderr index cdb1c6e2d7b..edbdfb56522 100644 --- a/src/test/ui/async-await/no-async-const.stderr +++ b/src/test/ui/async-await/no-async-const.stderr @@ -1,5 +1,5 @@ error: expected one of `fn` or `unsafe`, found `const` - --> $DIR/no-async-const.rs:7:11 + --> $DIR/no-async-const.rs:5:11 | LL | pub async const fn x() {} | ^^^^^ expected one of `fn` or `unsafe` here diff --git a/src/test/ui/async-await/no-const-async.rs b/src/test/ui/async-await/no-const-async.rs index 9f09d2188c7..bd78a18a40e 100644 --- a/src/test/ui/async-await/no-const-async.rs +++ b/src/test/ui/async-await/no-const-async.rs @@ -2,8 +2,6 @@ // edition:2018 // compile-flags: --crate-type lib -#![feature(async_await)] - pub const async fn x() {} //~^ ERROR expected identifier, found reserved keyword `async` //~^^ expected `:`, found keyword `fn` diff --git a/src/test/ui/async-await/no-const-async.stderr b/src/test/ui/async-await/no-const-async.stderr index 693fbf186f9..6d7df57e7b6 100644 --- a/src/test/ui/async-await/no-const-async.stderr +++ b/src/test/ui/async-await/no-const-async.stderr @@ -1,5 +1,5 @@ error: expected identifier, found reserved keyword `async` - --> $DIR/no-const-async.rs:7:11 + --> $DIR/no-const-async.rs:5:11 | LL | pub const async fn x() {} | ^^^^^ expected identifier, found reserved keyword @@ -9,7 +9,7 @@ LL | pub const r#async fn x() {} | ^^^^^^^ error: expected `:`, found keyword `fn` - --> $DIR/no-const-async.rs:7:17 + --> $DIR/no-const-async.rs:5:17 | LL | pub const async fn x() {} | ^^ expected `:` diff --git a/src/test/ui/async-await/no-move-across-await-struct.rs b/src/test/ui/async-await/no-move-across-await-struct.rs index 58e09470897..bef477bd256 100644 --- a/src/test/ui/async-await/no-move-across-await-struct.rs +++ b/src/test/ui/async-await/no-move-across-await-struct.rs @@ -2,8 +2,6 @@ // edition:2018 // compile-flags: --crate-type lib -#![feature(async_await)] - async fn no_move_across_await_struct() -> Vec<usize> { let s = Small { x: vec![31], y: vec![19, 1441] }; needs_vec(s.x).await; diff --git a/src/test/ui/async-await/no-move-across-await-struct.stderr b/src/test/ui/async-await/no-move-across-await-struct.stderr index 121c7791bd9..88f147b8d9d 100644 --- a/src/test/ui/async-await/no-move-across-await-struct.stderr +++ b/src/test/ui/async-await/no-move-across-await-struct.stderr @@ -1,5 +1,5 @@ error[E0382]: use of moved value: `s.x` - --> $DIR/no-move-across-await-struct.rs:10:5 + --> $DIR/no-move-across-await-struct.rs:8:5 | LL | needs_vec(s.x).await; | --- value moved here diff --git a/src/test/ui/async-await/no-move-across-await-tuple.rs b/src/test/ui/async-await/no-move-across-await-tuple.rs index 5d3ed3da1e3..565cbd7d5f4 100644 --- a/src/test/ui/async-await/no-move-across-await-tuple.rs +++ b/src/test/ui/async-await/no-move-across-await-tuple.rs @@ -2,8 +2,6 @@ // edition:2018 // compile-flags: --crate-type lib -#![feature(async_await)] - async fn no_move_across_await_tuple() -> Vec<usize> { let x = (vec![3], vec![4, 4]); drop(x.1); diff --git a/src/test/ui/async-await/no-move-across-await-tuple.stderr b/src/test/ui/async-await/no-move-across-await-tuple.stderr index 5da037ea5c0..fe98ecd599a 100644 --- a/src/test/ui/async-await/no-move-across-await-tuple.stderr +++ b/src/test/ui/async-await/no-move-across-await-tuple.stderr @@ -1,5 +1,5 @@ error[E0382]: use of moved value: `x.1` - --> $DIR/no-move-across-await-tuple.rs:11:5 + --> $DIR/no-move-across-await-tuple.rs:9:5 | LL | drop(x.1); | --- value moved here diff --git a/src/test/ui/async-await/no-non-guaranteed-initialization.rs b/src/test/ui/async-await/no-non-guaranteed-initialization.rs index a916afb6b09..0afbf4cee1d 100644 --- a/src/test/ui/async-await/no-non-guaranteed-initialization.rs +++ b/src/test/ui/async-await/no-non-guaranteed-initialization.rs @@ -2,8 +2,6 @@ // edition:2018 // compile-flags: --crate-type lib -#![feature(async_await)] - async fn no_non_guaranteed_initialization(x: usize) -> usize { let y; if x > 5 { diff --git a/src/test/ui/async-await/no-non-guaranteed-initialization.stderr b/src/test/ui/async-await/no-non-guaranteed-initialization.stderr index fb94522cac0..91d7994654f 100644 --- a/src/test/ui/async-await/no-non-guaranteed-initialization.stderr +++ b/src/test/ui/async-await/no-non-guaranteed-initialization.stderr @@ -1,5 +1,5 @@ error[E0381]: use of possibly uninitialized variable: `y` - --> $DIR/no-non-guaranteed-initialization.rs:12:5 + --> $DIR/no-non-guaranteed-initialization.rs:10:5 | LL | y | ^ use of possibly uninitialized `y` diff --git a/src/test/ui/async-await/partial-initialization-across-await.rs b/src/test/ui/async-await/partial-initialization-across-await.rs index 40f9f5202e7..1785fb7f299 100644 --- a/src/test/ui/async-await/partial-initialization-across-await.rs +++ b/src/test/ui/async-await/partial-initialization-across-await.rs @@ -3,8 +3,6 @@ // edition:2018 -#![feature(async_await)] - struct S { x: i32, y: i32 } struct T(i32, i32); diff --git a/src/test/ui/async-await/partial-initialization-across-await.stderr b/src/test/ui/async-await/partial-initialization-across-await.stderr index fe79eb08bef..d9a2db985e5 100644 --- a/src/test/ui/async-await/partial-initialization-across-await.stderr +++ b/src/test/ui/async-await/partial-initialization-across-await.stderr @@ -1,17 +1,17 @@ error[E0381]: assign to part of possibly uninitialized variable: `t` - --> $DIR/partial-initialization-across-await.rs:15:5 + --> $DIR/partial-initialization-across-await.rs:13:5 | LL | t.0 = 42; | ^^^^^^^^ use of possibly uninitialized `t` error[E0381]: assign to part of possibly uninitialized variable: `t` - --> $DIR/partial-initialization-across-await.rs:24:5 + --> $DIR/partial-initialization-across-await.rs:22:5 | LL | t.0 = 42; | ^^^^^^^^ use of possibly uninitialized `t` error[E0381]: assign to part of possibly uninitialized variable: `t` - --> $DIR/partial-initialization-across-await.rs:33:5 + --> $DIR/partial-initialization-across-await.rs:31:5 | LL | t.x = 42; | ^^^^^^^^ use of possibly uninitialized `t` diff --git a/src/test/ui/async-await/recursive-async-impl-trait-type.rs b/src/test/ui/async-await/recursive-async-impl-trait-type.rs index 54f3339870b..aa773319458 100644 --- a/src/test/ui/async-await/recursive-async-impl-trait-type.rs +++ b/src/test/ui/async-await/recursive-async-impl-trait-type.rs @@ -2,8 +2,6 @@ // Test that impl trait does not allow creating recursive types that are // otherwise forbidden when using `async` and `await`. -#![feature(async_await)] - async fn recursive_async_function() -> () { //~ ERROR recursive_async_function().await; } diff --git a/src/test/ui/async-await/recursive-async-impl-trait-type.stderr b/src/test/ui/async-await/recursive-async-impl-trait-type.stderr index 64f6eccd547..8781a9c444d 100644 --- a/src/test/ui/async-await/recursive-async-impl-trait-type.stderr +++ b/src/test/ui/async-await/recursive-async-impl-trait-type.stderr @@ -1,5 +1,5 @@ error[E0733]: recursion in an `async fn` requires boxing - --> $DIR/recursive-async-impl-trait-type.rs:7:40 + --> $DIR/recursive-async-impl-trait-type.rs:5:40 | LL | async fn recursive_async_function() -> () { | ^^ an `async fn` cannot invoke itself directly diff --git a/src/test/ui/async-await/suggest-missing-await-closure.fixed b/src/test/ui/async-await/suggest-missing-await-closure.fixed index 60c9a8581ac..37b30ffe680 100644 --- a/src/test/ui/async-await/suggest-missing-await-closure.fixed +++ b/src/test/ui/async-await/suggest-missing-await-closure.fixed @@ -1,7 +1,7 @@ // edition:2018 // run-rustfix -#![feature(async_await, async_closure)] +#![feature(async_closure)] fn take_u32(_x: u32) {} diff --git a/src/test/ui/async-await/suggest-missing-await-closure.rs b/src/test/ui/async-await/suggest-missing-await-closure.rs index cb992a27bc1..18076a15161 100644 --- a/src/test/ui/async-await/suggest-missing-await-closure.rs +++ b/src/test/ui/async-await/suggest-missing-await-closure.rs @@ -1,7 +1,7 @@ // edition:2018 // run-rustfix -#![feature(async_await, async_closure)] +#![feature(async_closure)] fn take_u32(_x: u32) {} diff --git a/src/test/ui/async-await/suggest-missing-await.fixed b/src/test/ui/async-await/suggest-missing-await.fixed index aa032682be8..7c02a907ce7 100644 --- a/src/test/ui/async-await/suggest-missing-await.fixed +++ b/src/test/ui/async-await/suggest-missing-await.fixed @@ -1,8 +1,6 @@ // edition:2018 // run-rustfix -#![feature(async_await)] - fn take_u32(_x: u32) {} async fn make_u32() -> u32 { diff --git a/src/test/ui/async-await/suggest-missing-await.rs b/src/test/ui/async-await/suggest-missing-await.rs index 2ca814fbb22..91abd44e65c 100644 --- a/src/test/ui/async-await/suggest-missing-await.rs +++ b/src/test/ui/async-await/suggest-missing-await.rs @@ -1,8 +1,6 @@ // edition:2018 // run-rustfix -#![feature(async_await)] - fn take_u32(_x: u32) {} async fn make_u32() -> u32 { diff --git a/src/test/ui/async-await/suggest-missing-await.stderr b/src/test/ui/async-await/suggest-missing-await.stderr index 9bae7150276..ccca97ec204 100644 --- a/src/test/ui/async-await/suggest-missing-await.stderr +++ b/src/test/ui/async-await/suggest-missing-await.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> $DIR/suggest-missing-await.rs:15:14 + --> $DIR/suggest-missing-await.rs:13:14 | LL | take_u32(x) | ^ diff --git a/src/test/ui/async-await/unresolved_type_param.rs b/src/test/ui/async-await/unresolved_type_param.rs index 578d41fe0df..d8ea87d2775 100644 --- a/src/test/ui/async-await/unresolved_type_param.rs +++ b/src/test/ui/async-await/unresolved_type_param.rs @@ -2,7 +2,7 @@ // Error message should pinpoint the type parameter T as needing to be bound // (rather than give a general error message) // edition:2018 -#![feature(async_await)] + async fn bar<T>() -> () {} async fn foo() { diff --git a/src/test/ui/break-outside-loop.rs b/src/test/ui/break-outside-loop.rs index fef298f7c39..c424c25c646 100644 --- a/src/test/ui/break-outside-loop.rs +++ b/src/test/ui/break-outside-loop.rs @@ -7,8 +7,8 @@ fn cond() -> bool { true } fn foo<F>(_: F) where F: FnOnce() {} fn main() { - let pth = break; //~ ERROR: `break` outside of loop - if cond() { continue } //~ ERROR: `continue` outside of loop + let pth = break; //~ ERROR: `break` outside of a loop + if cond() { continue } //~ ERROR: `continue` outside of a loop while cond() { if cond() { break } @@ -21,5 +21,5 @@ fn main() { let rs: Foo = Foo{t: pth}; - let unconstrained = break; //~ ERROR: `break` outside of loop + let unconstrained = break; //~ ERROR: `break` outside of a loop } diff --git a/src/test/ui/break-outside-loop.stderr b/src/test/ui/break-outside-loop.stderr index 8f4656ab394..8b686356055 100644 --- a/src/test/ui/break-outside-loop.stderr +++ b/src/test/ui/break-outside-loop.stderr @@ -1,32 +1,37 @@ -error[E0268]: `break` outside of loop +error[E0268]: `break` outside of a loop --> $DIR/break-outside-loop.rs:10:15 | LL | let pth = break; - | ^^^^^ cannot break outside of a loop + | ^^^^^ cannot `break` outside of a loop -error[E0268]: `continue` outside of loop +error[E0268]: `continue` outside of a loop --> $DIR/break-outside-loop.rs:11:17 | LL | if cond() { continue } - | ^^^^^^^^ cannot break outside of a loop + | ^^^^^^^^ cannot `continue` outside of a loop error[E0267]: `break` inside of a closure --> $DIR/break-outside-loop.rs:17:25 | +LL | foo(|| { + | -- enclosing closure LL | if cond() { break } - | ^^^^^ cannot break inside of a closure + | ^^^^^ cannot `break` inside of a closure error[E0267]: `continue` inside of a closure --> $DIR/break-outside-loop.rs:18:25 | +LL | foo(|| { + | -- enclosing closure +LL | if cond() { break } LL | if cond() { continue } - | ^^^^^^^^ cannot break inside of a closure + | ^^^^^^^^ cannot `continue` inside of a closure -error[E0268]: `break` outside of loop +error[E0268]: `break` outside of a loop --> $DIR/break-outside-loop.rs:24:25 | LL | let unconstrained = break; - | ^^^^^ cannot break outside of a loop + | ^^^^^ cannot `break` outside of a loop error: aborting due to 5 previous errors diff --git a/src/test/ui/closures/closure-array-break-length.rs b/src/test/ui/closures/closure-array-break-length.rs index a7f16d70ba8..f3567db1fac 100644 --- a/src/test/ui/closures/closure-array-break-length.rs +++ b/src/test/ui/closures/closure-array-break-length.rs @@ -1,9 +1,9 @@ fn main() { - |_: [_; continue]| {}; //~ ERROR: `continue` outside of loop + |_: [_; continue]| {}; //~ ERROR: `continue` outside of a loop - while |_: [_; continue]| {} {} //~ ERROR: `continue` outside of loop + while |_: [_; continue]| {} {} //~ ERROR: `continue` outside of a loop //~^ ERROR mismatched types - while |_: [_; break]| {} {} //~ ERROR: `break` outside of loop + while |_: [_; break]| {} {} //~ ERROR: `break` outside of a loop //~^ ERROR mismatched types } diff --git a/src/test/ui/closures/closure-array-break-length.stderr b/src/test/ui/closures/closure-array-break-length.stderr index 46fbd3e0fae..18da4a94e6f 100644 --- a/src/test/ui/closures/closure-array-break-length.stderr +++ b/src/test/ui/closures/closure-array-break-length.stderr @@ -1,20 +1,20 @@ -error[E0268]: `continue` outside of loop +error[E0268]: `continue` outside of a loop --> $DIR/closure-array-break-length.rs:2:13 | LL | |_: [_; continue]| {}; - | ^^^^^^^^ cannot break outside of a loop + | ^^^^^^^^ cannot `continue` outside of a loop -error[E0268]: `continue` outside of loop +error[E0268]: `continue` outside of a loop --> $DIR/closure-array-break-length.rs:4:19 | LL | while |_: [_; continue]| {} {} - | ^^^^^^^^ cannot break outside of a loop + | ^^^^^^^^ cannot `continue` outside of a loop -error[E0268]: `break` outside of loop +error[E0268]: `break` outside of a loop --> $DIR/closure-array-break-length.rs:7:19 | LL | while |_: [_; break]| {} {} - | ^^^^^ cannot break outside of a loop + | ^^^^^ cannot `break` outside of a loop error[E0308]: mismatched types --> $DIR/closure-array-break-length.rs:4:11 diff --git a/src/test/ui/commandline-argfile-badutf8.args b/src/test/ui/commandline-argfile-badutf8.args new file mode 100644 index 00000000000..c070b0c2400 --- /dev/null +++ b/src/test/ui/commandline-argfile-badutf8.args @@ -0,0 +1,2 @@ +--cfg +unbroken€ \ No newline at end of file diff --git a/src/test/ui/commandline-argfile-badutf8.rs b/src/test/ui/commandline-argfile-badutf8.rs new file mode 100644 index 00000000000..161715685b5 --- /dev/null +++ b/src/test/ui/commandline-argfile-badutf8.rs @@ -0,0 +1,13 @@ +// Check to see if we can get parameters from an @argsfile file +// +// build-fail +// compile-flags: --cfg cmdline_set @{{src-base}}/commandline-argfile-badutf8.args + +#[cfg(not(cmdline_set))] +compile_error!("cmdline_set not set"); + +#[cfg(not(unbroken))] +compile_error!("unbroken not set"); + +fn main() { +} diff --git a/src/test/ui/commandline-argfile-badutf8.stderr b/src/test/ui/commandline-argfile-badutf8.stderr new file mode 100644 index 00000000000..9af6fc0a518 --- /dev/null +++ b/src/test/ui/commandline-argfile-badutf8.stderr @@ -0,0 +1,2 @@ +error: Failed to load argument file: Utf8 error in $DIR/commandline-argfile-badutf8.args + diff --git a/src/test/ui/commandline-argfile-missing.rs b/src/test/ui/commandline-argfile-missing.rs new file mode 100644 index 00000000000..a29b4ab062d --- /dev/null +++ b/src/test/ui/commandline-argfile-missing.rs @@ -0,0 +1,16 @@ +// Check to see if we can get parameters from an @argsfile file +// +// ignore-tidy-linelength +// build-fail +// normalize-stderr-test: "os error \d+" -> "os error $$ERR" +// normalize-stderr-test: "commandline-argfile-missing.args:[^(]*" -> "commandline-argfile-missing.args: $$FILE_MISSING " +// compile-flags: --cfg cmdline_set @{{src-base}}/commandline-argfile-missing.args + +#[cfg(not(cmdline_set))] +compile_error!("cmdline_set not set"); + +#[cfg(not(unbroken))] +compile_error!("unbroken not set"); + +fn main() { +} diff --git a/src/test/ui/commandline-argfile-missing.stderr b/src/test/ui/commandline-argfile-missing.stderr new file mode 100644 index 00000000000..179ad831004 --- /dev/null +++ b/src/test/ui/commandline-argfile-missing.stderr @@ -0,0 +1,2 @@ +error: Failed to load argument file: IO Error: $DIR/commandline-argfile-missing.args: $FILE_MISSING (os error $ERR) + diff --git a/src/test/ui/commandline-argfile.args b/src/test/ui/commandline-argfile.args new file mode 100644 index 00000000000..972938bf6c8 --- /dev/null +++ b/src/test/ui/commandline-argfile.args @@ -0,0 +1,2 @@ +--cfg +unbroken \ No newline at end of file diff --git a/src/test/ui/commandline-argfile.rs b/src/test/ui/commandline-argfile.rs new file mode 100644 index 00000000000..fc1ba0c8d67 --- /dev/null +++ b/src/test/ui/commandline-argfile.rs @@ -0,0 +1,13 @@ +// Check to see if we can get parameters from an @argsfile file +// +// build-pass +// compile-flags: --cfg cmdline_set @{{src-base}}/commandline-argfile.args + +#[cfg(not(cmdline_set))] +compile_error!("cmdline_set not set"); + +#[cfg(not(unbroken))] +compile_error!("unbroken not set"); + +fn main() { +} diff --git a/src/test/ui/conditional-compilation/cfg-attr-crate-2.rs b/src/test/ui/conditional-compilation/cfg-attr-crate-2.rs index 0dceba28b6e..7dbeba53afc 100644 --- a/src/test/ui/conditional-compilation/cfg-attr-crate-2.rs +++ b/src/test/ui/conditional-compilation/cfg-attr-crate-2.rs @@ -3,6 +3,6 @@ // compile-flags: --cfg broken #![crate_type = "lib"] -#![cfg_attr(broken, no_core)] //~ ERROR no_core is experimental +#![cfg_attr(broken, no_core)] //~ ERROR the `#[no_core]` attribute is an experimental feature pub struct S {} diff --git a/src/test/ui/conditional-compilation/cfg-attr-crate-2.stderr b/src/test/ui/conditional-compilation/cfg-attr-crate-2.stderr index 5a70a5efc7f..7b77701ee19 100644 --- a/src/test/ui/conditional-compilation/cfg-attr-crate-2.stderr +++ b/src/test/ui/conditional-compilation/cfg-attr-crate-2.stderr @@ -1,4 +1,4 @@ -error[E0658]: no_core is experimental +error[E0658]: the `#[no_core]` attribute is an experimental feature --> $DIR/cfg-attr-crate-2.rs:6:21 | LL | #![cfg_attr(broken, no_core)] diff --git a/src/test/ui/conditional-compilation/cfg-attr-multi-invalid-1.rs b/src/test/ui/conditional-compilation/cfg-attr-multi-invalid-1.rs index be762c56048..42ffb71e3d7 100644 --- a/src/test/ui/conditional-compilation/cfg-attr-multi-invalid-1.rs +++ b/src/test/ui/conditional-compilation/cfg-attr-multi-invalid-1.rs @@ -1,6 +1,7 @@ // compile-flags: --cfg broken #![crate_type = "lib"] -#![cfg_attr(broken, no_core, no_std)] //~ ERROR no_core is experimental +#![cfg_attr(broken, no_core, no_std)] +//~^ ERROR the `#[no_core]` attribute is an experimental feature pub struct S {} diff --git a/src/test/ui/conditional-compilation/cfg-attr-multi-invalid-1.stderr b/src/test/ui/conditional-compilation/cfg-attr-multi-invalid-1.stderr index 5e9adf17807..ab7e1eb9603 100644 --- a/src/test/ui/conditional-compilation/cfg-attr-multi-invalid-1.stderr +++ b/src/test/ui/conditional-compilation/cfg-attr-multi-invalid-1.stderr @@ -1,4 +1,4 @@ -error[E0658]: no_core is experimental +error[E0658]: the `#[no_core]` attribute is an experimental feature --> $DIR/cfg-attr-multi-invalid-1.rs:4:21 | LL | #![cfg_attr(broken, no_core, no_std)] diff --git a/src/test/ui/conditional-compilation/cfg-attr-multi-invalid-2.rs b/src/test/ui/conditional-compilation/cfg-attr-multi-invalid-2.rs index 8a9e99d703c..29690e2848f 100644 --- a/src/test/ui/conditional-compilation/cfg-attr-multi-invalid-2.rs +++ b/src/test/ui/conditional-compilation/cfg-attr-multi-invalid-2.rs @@ -1,6 +1,7 @@ // compile-flags: --cfg broken #![crate_type = "lib"] -#![cfg_attr(broken, no_std, no_core)] //~ ERROR no_core is experimental +#![cfg_attr(broken, no_std, no_core)] +//~^ ERROR the `#[no_core]` attribute is an experimental feature pub struct S {} diff --git a/src/test/ui/conditional-compilation/cfg-attr-multi-invalid-2.stderr b/src/test/ui/conditional-compilation/cfg-attr-multi-invalid-2.stderr index 06b67156651..8126affbd36 100644 --- a/src/test/ui/conditional-compilation/cfg-attr-multi-invalid-2.stderr +++ b/src/test/ui/conditional-compilation/cfg-attr-multi-invalid-2.stderr @@ -1,4 +1,4 @@ -error[E0658]: no_core is experimental +error[E0658]: the `#[no_core]` attribute is an experimental feature --> $DIR/cfg-attr-multi-invalid-2.rs:4:29 | LL | #![cfg_attr(broken, no_std, no_core)] diff --git a/src/test/ui/consts/min_const_fn/min_const_fn_unsafe_bad.rs b/src/test/ui/consts/min_const_fn/min_const_fn_unsafe_bad.rs new file mode 100644 index 00000000000..4281874a031 --- /dev/null +++ b/src/test/ui/consts/min_const_fn/min_const_fn_unsafe_bad.rs @@ -0,0 +1,16 @@ +const fn bad_const_fn_deref_raw(x: *mut usize) -> &'static usize { unsafe { &*x } } //~ is unsafe +//~^ dereferencing raw pointers in constant functions + +const unsafe fn bad_const_unsafe_deref_raw(x: *mut usize) -> usize { *x } +//~^ dereferencing raw pointers in constant functions + +const unsafe fn bad_const_unsafe_deref_raw_ref(x: *mut usize) -> &'static usize { &*x } +//~^ dereferencing raw pointers in constant functions + +fn main() {} + +const unsafe fn no_union() { + union Foo { x: (), y: () } + Foo { x: () }.y + //~^ unions in const fn +} diff --git a/src/test/ui/consts/min_const_fn/min_const_fn_unsafe.stderr b/src/test/ui/consts/min_const_fn/min_const_fn_unsafe_bad.stderr index d3f2ece1f92..9de0e732f33 100644 --- a/src/test/ui/consts/min_const_fn/min_const_fn_unsafe.stderr +++ b/src/test/ui/consts/min_const_fn/min_const_fn_unsafe_bad.stderr @@ -1,5 +1,5 @@ error[E0658]: dereferencing raw pointers in constant functions is unstable - --> $DIR/min_const_fn_unsafe.rs:50:77 + --> $DIR/min_const_fn_unsafe_bad.rs:1:77 | LL | const fn bad_const_fn_deref_raw(x: *mut usize) -> &'static usize { unsafe { &*x } } | ^^^ @@ -8,7 +8,7 @@ LL | const fn bad_const_fn_deref_raw(x: *mut usize) -> &'static usize { unsafe { = help: add `#![feature(const_raw_ptr_deref)]` to the crate attributes to enable error[E0658]: dereferencing raw pointers in constant functions is unstable - --> $DIR/min_const_fn_unsafe.rs:53:70 + --> $DIR/min_const_fn_unsafe_bad.rs:4:70 | LL | const unsafe fn bad_const_unsafe_deref_raw(x: *mut usize) -> usize { *x } | ^^ @@ -17,7 +17,7 @@ LL | const unsafe fn bad_const_unsafe_deref_raw(x: *mut usize) -> usize { *x } = help: add `#![feature(const_raw_ptr_deref)]` to the crate attributes to enable error[E0658]: dereferencing raw pointers in constant functions is unstable - --> $DIR/min_const_fn_unsafe.rs:56:83 + --> $DIR/min_const_fn_unsafe_bad.rs:7:83 | LL | const unsafe fn bad_const_unsafe_deref_raw_ref(x: *mut usize) -> &'static usize { &*x } | ^^^ @@ -26,7 +26,7 @@ LL | const unsafe fn bad_const_unsafe_deref_raw_ref(x: *mut usize) -> &'static u = help: add `#![feature(const_raw_ptr_deref)]` to the crate attributes to enable error[E0658]: unions in const fn are unstable - --> $DIR/min_const_fn_unsafe.rs:63:5 + --> $DIR/min_const_fn_unsafe_bad.rs:14:5 | LL | Foo { x: () }.y | ^^^^^^^^^^^^^^^ @@ -35,7 +35,7 @@ LL | Foo { x: () }.y = help: add `#![feature(const_fn_union)]` to the crate attributes to enable error[E0133]: dereference of raw pointer is unsafe and requires unsafe function or block - --> $DIR/min_const_fn_unsafe.rs:50:77 + --> $DIR/min_const_fn_unsafe_bad.rs:1:77 | LL | const fn bad_const_fn_deref_raw(x: *mut usize) -> &'static usize { unsafe { &*x } } | ^^^ dereference of raw pointer diff --git a/src/test/ui/consts/min_const_fn/min_const_fn_unsafe.rs b/src/test/ui/consts/min_const_fn/min_const_fn_unsafe_ok.rs index 0152561aefc..02c7970deca 100644 --- a/src/test/ui/consts/min_const_fn/min_const_fn_unsafe.rs +++ b/src/test/ui/consts/min_const_fn/min_const_fn_unsafe_ok.rs @@ -1,6 +1,4 @@ -//------------------------------------------------------------------------------ -// OK -//------------------------------------------------------------------------------ +// check-pass const unsafe fn ret_i32_no_unsafe() -> i32 { 42 } const unsafe fn ret_null_ptr_no_unsafe<T>() -> *const T { std::ptr::null() } @@ -43,23 +41,4 @@ const unsafe fn call_unsafe_generic_cell_const_unsafe_fn_immediate() ret_null_mut_ptr_no_unsafe::<Vec<std::cell::Cell<u32>>>() } -//------------------------------------------------------------------------------ -// NOT OK -//------------------------------------------------------------------------------ - -const fn bad_const_fn_deref_raw(x: *mut usize) -> &'static usize { unsafe { &*x } } //~ is unsafe -//~^ dereferencing raw pointers in constant functions - -const unsafe fn bad_const_unsafe_deref_raw(x: *mut usize) -> usize { *x } -//~^ dereferencing raw pointers in constant functions - -const unsafe fn bad_const_unsafe_deref_raw_ref(x: *mut usize) -> &'static usize { &*x } -//~^ dereferencing raw pointers in constant functions - fn main() {} - -const unsafe fn no_union() { - union Foo { x: (), y: () } - Foo { x: () }.y - //~^ unions in const fn -} diff --git a/src/test/ui/drop/dynamic-drop-async.rs b/src/test/ui/drop/dynamic-drop-async.rs index f3f5c382275..79d09d18176 100644 --- a/src/test/ui/drop/dynamic-drop-async.rs +++ b/src/test/ui/drop/dynamic-drop-async.rs @@ -7,10 +7,7 @@ // edition:2018 // ignore-wasm32-bare compiled with panic=abort by default -#![allow(unused_assignments)] -#![allow(unused_variables)] #![feature(slice_patterns)] -#![feature(async_await)] use std::{ cell::{Cell, RefCell}, diff --git a/src/test/ui/error-codes/E0267.stderr b/src/test/ui/error-codes/E0267.stderr index b14cfd1a52d..1f8657373ef 100644 --- a/src/test/ui/error-codes/E0267.stderr +++ b/src/test/ui/error-codes/E0267.stderr @@ -2,7 +2,9 @@ error[E0267]: `break` inside of a closure --> $DIR/E0267.rs:2:18 | LL | let w = || { break; }; - | ^^^^^ cannot break inside of a closure + | -- ^^^^^ cannot `break` inside of a closure + | | + | enclosing closure error: aborting due to previous error diff --git a/src/test/ui/error-codes/E0268.stderr b/src/test/ui/error-codes/E0268.stderr index 3c77e7f3df2..c926f9e4874 100644 --- a/src/test/ui/error-codes/E0268.stderr +++ b/src/test/ui/error-codes/E0268.stderr @@ -1,8 +1,8 @@ -error[E0268]: `break` outside of loop +error[E0268]: `break` outside of a loop --> $DIR/E0268.rs:2:5 | LL | break; - | ^^^^^ cannot break outside of a loop + | ^^^^^ cannot `break` outside of a loop error: aborting due to previous error diff --git a/src/test/ui/feature-gate-optimize_attribute.rs b/src/test/ui/feature-gate-optimize_attribute.rs index 7fc0fdde6fb..15aa3a6af4c 100644 --- a/src/test/ui/feature-gate-optimize_attribute.rs +++ b/src/test/ui/feature-gate-optimize_attribute.rs @@ -1,17 +1,17 @@ #![crate_type="rlib"] -#![optimize(speed)] //~ ERROR `#[optimize]` attribute is an unstable feature +#![optimize(speed)] //~ ERROR the `#[optimize]` attribute is an experimental feature -#[optimize(size)] //~ ERROR `#[optimize]` attribute is an unstable feature +#[optimize(size)] //~ ERROR the `#[optimize]` attribute is an experimental feature mod module { -#[optimize(size)] //~ ERROR `#[optimize]` attribute is an unstable feature +#[optimize(size)] //~ ERROR the `#[optimize]` attribute is an experimental feature fn size() {} -#[optimize(speed)] //~ ERROR `#[optimize]` attribute is an unstable feature +#[optimize(speed)] //~ ERROR the `#[optimize]` attribute is an experimental feature fn speed() {} #[optimize(banana)] -//~^ ERROR `#[optimize]` attribute is an unstable feature +//~^ ERROR the `#[optimize]` attribute is an experimental feature //~| ERROR E0722 fn not_known() {} diff --git a/src/test/ui/feature-gate-optimize_attribute.stderr b/src/test/ui/feature-gate-optimize_attribute.stderr index 4ec512eaf39..3e3ad71c344 100644 --- a/src/test/ui/feature-gate-optimize_attribute.stderr +++ b/src/test/ui/feature-gate-optimize_attribute.stderr @@ -1,4 +1,4 @@ -error[E0658]: `#[optimize]` attribute is an unstable feature +error[E0658]: the `#[optimize]` attribute is an experimental feature --> $DIR/feature-gate-optimize_attribute.rs:7:1 | LL | #[optimize(size)] @@ -7,7 +7,7 @@ LL | #[optimize(size)] = note: for more information, see https://github.com/rust-lang/rust/issues/54882 = help: add `#![feature(optimize_attribute)]` to the crate attributes to enable -error[E0658]: `#[optimize]` attribute is an unstable feature +error[E0658]: the `#[optimize]` attribute is an experimental feature --> $DIR/feature-gate-optimize_attribute.rs:10:1 | LL | #[optimize(speed)] @@ -16,7 +16,7 @@ LL | #[optimize(speed)] = note: for more information, see https://github.com/rust-lang/rust/issues/54882 = help: add `#![feature(optimize_attribute)]` to the crate attributes to enable -error[E0658]: `#[optimize]` attribute is an unstable feature +error[E0658]: the `#[optimize]` attribute is an experimental feature --> $DIR/feature-gate-optimize_attribute.rs:13:1 | LL | #[optimize(banana)] @@ -25,7 +25,7 @@ LL | #[optimize(banana)] = note: for more information, see https://github.com/rust-lang/rust/issues/54882 = help: add `#![feature(optimize_attribute)]` to the crate attributes to enable -error[E0658]: `#[optimize]` attribute is an unstable feature +error[E0658]: the `#[optimize]` attribute is an experimental feature --> $DIR/feature-gate-optimize_attribute.rs:4:1 | LL | #[optimize(size)] @@ -34,7 +34,7 @@ LL | #[optimize(size)] = note: for more information, see https://github.com/rust-lang/rust/issues/54882 = help: add `#![feature(optimize_attribute)]` to the crate attributes to enable -error[E0658]: `#[optimize]` attribute is an unstable feature +error[E0658]: the `#[optimize]` attribute is an experimental feature --> $DIR/feature-gate-optimize_attribute.rs:2:1 | LL | #![optimize(speed)] diff --git a/src/test/ui/feature-gates/feature-gate-alloc-error-handler.rs b/src/test/ui/feature-gates/feature-gate-alloc-error-handler.rs index 17b4f775ad4..ad890961830 100644 --- a/src/test/ui/feature-gates/feature-gate-alloc-error-handler.rs +++ b/src/test/ui/feature-gates/feature-gate-alloc-error-handler.rs @@ -5,7 +5,7 @@ use core::alloc::Layout; -#[alloc_error_handler] //~ ERROR `#[alloc_error_handler]` is an unstable feature +#[alloc_error_handler] //~ ERROR the `#[alloc_error_handler]` attribute is an experimental feature fn oom(info: Layout) -> ! { loop {} } diff --git a/src/test/ui/feature-gates/feature-gate-alloc-error-handler.stderr b/src/test/ui/feature-gates/feature-gate-alloc-error-handler.stderr index d18cc09ffe7..79e44bf0d8e 100644 --- a/src/test/ui/feature-gates/feature-gate-alloc-error-handler.stderr +++ b/src/test/ui/feature-gates/feature-gate-alloc-error-handler.stderr @@ -1,4 +1,4 @@ -error[E0658]: `#[alloc_error_handler]` is an unstable feature +error[E0658]: the `#[alloc_error_handler]` attribute is an experimental feature --> $DIR/feature-gate-alloc-error-handler.rs:8:1 | LL | #[alloc_error_handler] diff --git a/src/test/ui/feature-gates/feature-gate-allow_fail.rs b/src/test/ui/feature-gates/feature-gate-allow_fail.rs index f9ad4855141..287d4ccf180 100644 --- a/src/test/ui/feature-gates/feature-gate-allow_fail.rs +++ b/src/test/ui/feature-gates/feature-gate-allow_fail.rs @@ -1,6 +1,6 @@ // check that #[allow_fail] is feature-gated -#[allow_fail] //~ ERROR allow_fail attribute is currently unstable +#[allow_fail] //~ ERROR the `#[allow_fail]` attribute is an experimental feature fn ok_to_fail() { assert!(false); } diff --git a/src/test/ui/feature-gates/feature-gate-allow_fail.stderr b/src/test/ui/feature-gates/feature-gate-allow_fail.stderr index 37bf3a262aa..0f60a2de3a4 100644 --- a/src/test/ui/feature-gates/feature-gate-allow_fail.stderr +++ b/src/test/ui/feature-gates/feature-gate-allow_fail.stderr @@ -1,4 +1,4 @@ -error[E0658]: allow_fail attribute is currently unstable +error[E0658]: the `#[allow_fail]` attribute is an experimental feature --> $DIR/feature-gate-allow_fail.rs:3:1 | LL | #[allow_fail] diff --git a/src/test/ui/feature-gates/feature-gate-async-await-2015-edition.rs b/src/test/ui/feature-gates/feature-gate-async-await-2015-edition.rs deleted file mode 100644 index 801aeb82aa2..00000000000 --- a/src/test/ui/feature-gates/feature-gate-async-await-2015-edition.rs +++ /dev/null @@ -1,9 +0,0 @@ -// edition:2015 - -async fn foo() {} //~ ERROR `async fn` is not permitted in the 2015 edition - //~^ ERROR async fn is unstable - -fn main() { - let _ = async {}; //~ ERROR cannot find struct, variant or union type `async` - let _ = async || { true }; //~ ERROR cannot find value `async` in this scope -} diff --git a/src/test/ui/feature-gates/feature-gate-async-await-2015-edition.stderr b/src/test/ui/feature-gates/feature-gate-async-await-2015-edition.stderr deleted file mode 100644 index 0157ed55344..00000000000 --- a/src/test/ui/feature-gates/feature-gate-async-await-2015-edition.stderr +++ /dev/null @@ -1,31 +0,0 @@ -error[E0670]: `async fn` is not permitted in the 2015 edition - --> $DIR/feature-gate-async-await-2015-edition.rs:3:1 - | -LL | async fn foo() {} - | ^^^^^ - -error[E0422]: cannot find struct, variant or union type `async` in this scope - --> $DIR/feature-gate-async-await-2015-edition.rs:7:13 - | -LL | let _ = async {}; - | ^^^^^ not found in this scope - -error[E0425]: cannot find value `async` in this scope - --> $DIR/feature-gate-async-await-2015-edition.rs:8:13 - | -LL | let _ = async || { true }; - | ^^^^^ not found in this scope - -error[E0658]: async fn is unstable - --> $DIR/feature-gate-async-await-2015-edition.rs:3:1 - | -LL | async fn foo() {} - | ^^^^^^^^^^^^^^^^^ - | - = note: for more information, see https://github.com/rust-lang/rust/issues/50547 - = help: add `#![feature(async_await)]` to the crate attributes to enable - -error: aborting due to 4 previous errors - -Some errors have detailed explanations: E0422, E0425, E0658, E0670. -For more information about an error, try `rustc --explain E0422`. diff --git a/src/test/ui/feature-gates/feature-gate-async-await.rs b/src/test/ui/feature-gates/feature-gate-async-await.rs deleted file mode 100644 index 78391c0e104..00000000000 --- a/src/test/ui/feature-gates/feature-gate-async-await.rs +++ /dev/null @@ -1,18 +0,0 @@ -// edition:2018 - -struct S; - -impl S { - async fn foo() {} //~ ERROR async fn is unstable -} - -trait T { - async fn foo(); //~ ERROR trait fns cannot be declared `async` - //~^ ERROR async fn is unstable -} - -async fn foo() {} //~ ERROR async fn is unstable - -fn main() { - let _ = async {}; //~ ERROR async blocks are unstable -} diff --git a/src/test/ui/feature-gates/feature-gate-async-await.stderr b/src/test/ui/feature-gates/feature-gate-async-await.stderr deleted file mode 100644 index 9f4a90157a4..00000000000 --- a/src/test/ui/feature-gates/feature-gate-async-await.stderr +++ /dev/null @@ -1,45 +0,0 @@ -error[E0706]: trait fns cannot be declared `async` - --> $DIR/feature-gate-async-await.rs:10:5 - | -LL | async fn foo(); - | ^^^^^^^^^^^^^^^ - -error[E0658]: async fn is unstable - --> $DIR/feature-gate-async-await.rs:6:5 - | -LL | async fn foo() {} - | ^^^^^^^^^^^^^^^^^ - | - = note: for more information, see https://github.com/rust-lang/rust/issues/50547 - = help: add `#![feature(async_await)]` to the crate attributes to enable - -error[E0658]: async fn is unstable - --> $DIR/feature-gate-async-await.rs:10:5 - | -LL | async fn foo(); - | ^^^^^^^^^^^^^^^ - | - = note: for more information, see https://github.com/rust-lang/rust/issues/50547 - = help: add `#![feature(async_await)]` to the crate attributes to enable - -error[E0658]: async fn is unstable - --> $DIR/feature-gate-async-await.rs:14:1 - | -LL | async fn foo() {} - | ^^^^^^^^^^^^^^^^^ - | - = note: for more information, see https://github.com/rust-lang/rust/issues/50547 - = help: add `#![feature(async_await)]` to the crate attributes to enable - -error[E0658]: async blocks are unstable - --> $DIR/feature-gate-async-await.rs:17:13 - | -LL | let _ = async {}; - | ^^^^^^^^ - | - = note: for more information, see https://github.com/rust-lang/rust/issues/50547 - = help: add `#![feature(async_await)]` to the crate attributes to enable - -error: aborting due to 5 previous errors - -For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/feature-gates/feature-gate-marker_trait_attr.rs b/src/test/ui/feature-gates/feature-gate-marker_trait_attr.rs index ea06c775b1a..5050c4792b0 100644 --- a/src/test/ui/feature-gates/feature-gate-marker_trait_attr.rs +++ b/src/test/ui/feature-gates/feature-gate-marker_trait_attr.rs @@ -1,7 +1,7 @@ use std::fmt::{Debug, Display}; #[marker] trait ExplicitMarker {} -//~^ ERROR marker traits is an experimental feature +//~^ ERROR the `#[marker]` attribute is an experimental feature impl<T: Display> ExplicitMarker for T {} impl<T: Debug> ExplicitMarker for T {} diff --git a/src/test/ui/feature-gates/feature-gate-marker_trait_attr.stderr b/src/test/ui/feature-gates/feature-gate-marker_trait_attr.stderr index 94dfaf9206d..304c081c5aa 100644 --- a/src/test/ui/feature-gates/feature-gate-marker_trait_attr.stderr +++ b/src/test/ui/feature-gates/feature-gate-marker_trait_attr.stderr @@ -1,4 +1,4 @@ -error[E0658]: marker traits is an experimental feature +error[E0658]: the `#[marker]` attribute is an experimental feature --> $DIR/feature-gate-marker_trait_attr.rs:3:1 | LL | #[marker] trait ExplicitMarker {} diff --git a/src/test/ui/feature-gates/feature-gate-no_core.rs b/src/test/ui/feature-gates/feature-gate-no_core.rs index 40178edd74b..706efd78672 100644 --- a/src/test/ui/feature-gates/feature-gate-no_core.rs +++ b/src/test/ui/feature-gates/feature-gate-no_core.rs @@ -1,5 +1,5 @@ #![crate_type = "rlib"] -#![no_core] //~ ERROR no_core is experimental +#![no_core] //~ ERROR the `#[no_core]` attribute is an experimental feature pub struct S {} diff --git a/src/test/ui/feature-gates/feature-gate-no_core.stderr b/src/test/ui/feature-gates/feature-gate-no_core.stderr index 4d4ca96544e..a80b3cbba25 100644 --- a/src/test/ui/feature-gates/feature-gate-no_core.stderr +++ b/src/test/ui/feature-gates/feature-gate-no_core.stderr @@ -1,4 +1,4 @@ -error[E0658]: no_core is experimental +error[E0658]: the `#[no_core]` attribute is an experimental feature --> $DIR/feature-gate-no_core.rs:3:1 | LL | #![no_core] diff --git a/src/test/ui/feature-gates/feature-gate-non_exhaustive.rs b/src/test/ui/feature-gates/feature-gate-non_exhaustive.rs index aca214d1935..950f170f4fd 100644 --- a/src/test/ui/feature-gates/feature-gate-non_exhaustive.rs +++ b/src/test/ui/feature-gates/feature-gate-non_exhaustive.rs @@ -1,6 +1,6 @@ //#![feature(non_exhaustive)] -#[non_exhaustive] //~ERROR non exhaustive is an experimental feature +#[non_exhaustive] //~ERROR the `#[non_exhaustive]` attribute is an experimental feature pub enum NonExhaustiveEnum { Unit, Tuple(u32), diff --git a/src/test/ui/feature-gates/feature-gate-non_exhaustive.stderr b/src/test/ui/feature-gates/feature-gate-non_exhaustive.stderr index 8a01aa9eb6a..482332b8d70 100644 --- a/src/test/ui/feature-gates/feature-gate-non_exhaustive.stderr +++ b/src/test/ui/feature-gates/feature-gate-non_exhaustive.stderr @@ -1,4 +1,4 @@ -error[E0658]: non exhaustive is an experimental feature +error[E0658]: the `#[non_exhaustive]` attribute is an experimental feature --> $DIR/feature-gate-non_exhaustive.rs:3:1 | LL | #[non_exhaustive] diff --git a/src/test/ui/feature-gates/feature-gate-rustc-attrs.rs b/src/test/ui/feature-gates/feature-gate-rustc-attrs.rs index 13983726c78..4044fd2b895 100644 --- a/src/test/ui/feature-gates/feature-gate-rustc-attrs.rs +++ b/src/test/ui/feature-gates/feature-gate-rustc-attrs.rs @@ -16,7 +16,7 @@ fn f() {} fn g() {} #[rustc_dummy] -//~^ ERROR used by the test suite +//~^ ERROR the `#[rustc_dummy]` attribute is just used for rustc unit tests #[rustc_unknown] //~^ ERROR attributes starting with `rustc` are reserved for use by the `rustc` compiler //~| ERROR cannot find attribute macro `rustc_unknown` in this scope diff --git a/src/test/ui/feature-gates/feature-gate-rustc-attrs.stderr b/src/test/ui/feature-gates/feature-gate-rustc-attrs.stderr index 23cf936ee83..c1063027fa4 100644 --- a/src/test/ui/feature-gates/feature-gate-rustc-attrs.stderr +++ b/src/test/ui/feature-gates/feature-gate-rustc-attrs.stderr @@ -43,7 +43,7 @@ error: cannot find attribute macro `rustc_unknown` in this scope LL | #[rustc_unknown] | ^^^^^^^^^^^^^ -error[E0658]: used by the test suite +error[E0658]: the `#[rustc_dummy]` attribute is just used for rustc unit tests and will never be stable --> $DIR/feature-gate-rustc-attrs.rs:18:1 | LL | #[rustc_dummy] diff --git a/src/test/ui/feature-gates/feature-gate-unwind-attributes.rs b/src/test/ui/feature-gates/feature-gate-unwind-attributes.rs index 08e8ec9a56e..6d8ac7e8f29 100644 --- a/src/test/ui/feature-gates/feature-gate-unwind-attributes.rs +++ b/src/test/ui/feature-gates/feature-gate-unwind-attributes.rs @@ -8,7 +8,7 @@ extern { fn extern_fn(); // CHECK-NOT: Function Attrs: nounwind // CHECK: declare void @unwinding_extern_fn - #[unwind(allowed)] //~ ERROR `#[unwind]` is experimental + #[unwind(allowed)] //~ ERROR the `#[unwind]` attribute is an experimental feature fn unwinding_extern_fn(); } diff --git a/src/test/ui/feature-gates/feature-gate-unwind-attributes.stderr b/src/test/ui/feature-gates/feature-gate-unwind-attributes.stderr index 639b87e0162..10cc4942135 100644 --- a/src/test/ui/feature-gates/feature-gate-unwind-attributes.stderr +++ b/src/test/ui/feature-gates/feature-gate-unwind-attributes.stderr @@ -1,4 +1,4 @@ -error[E0658]: `#[unwind]` is experimental +error[E0658]: the `#[unwind]` attribute is an experimental feature --> $DIR/feature-gate-unwind-attributes.rs:11:5 | LL | #[unwind(allowed)] diff --git a/src/test/ui/generator/issue-61442-stmt-expr-with-drop.rs b/src/test/ui/generator/issue-61442-stmt-expr-with-drop.rs index ce4642020f0..e3d19029348 100644 --- a/src/test/ui/generator/issue-61442-stmt-expr-with-drop.rs +++ b/src/test/ui/generator/issue-61442-stmt-expr-with-drop.rs @@ -4,7 +4,7 @@ // check-pass // edition:2018 -#![feature(async_await, generators, generator_trait)] +#![feature(generators, generator_trait)] use std::ops::Generator; diff --git a/src/test/ui/generator/issue-62506-two_awaits.rs b/src/test/ui/generator/issue-62506-two_awaits.rs index 774019b6a5b..672e16b780d 100644 --- a/src/test/ui/generator/issue-62506-two_awaits.rs +++ b/src/test/ui/generator/issue-62506-two_awaits.rs @@ -4,7 +4,6 @@ // check-pass // edition:2018 -#![feature(async_await)] use std::future::Future; pub trait T { diff --git a/src/test/ui/hygiene/eager-from-opaque-2.rs b/src/test/ui/hygiene/eager-from-opaque-2.rs new file mode 100644 index 00000000000..220e5526745 --- /dev/null +++ b/src/test/ui/hygiene/eager-from-opaque-2.rs @@ -0,0 +1,22 @@ +// Regression test for the issue #63460. + +// check-pass + +#[macro_export] +macro_rules! separator { + () => { "/" }; +} + +#[macro_export] +macro_rules! concat_separator { + ( $e:literal, $($other:literal),+ ) => { + concat!($e, $crate::separator!(), $crate::concat_separator!($($other),+)) + }; + ( $e:literal ) => { + $e + } +} + +fn main() { + println!("{}", concat_separator!(2, 3, 4)) +} diff --git a/src/test/ui/hygiene/eager-from-opaque.rs b/src/test/ui/hygiene/eager-from-opaque.rs new file mode 100644 index 00000000000..6f3215dd697 --- /dev/null +++ b/src/test/ui/hygiene/eager-from-opaque.rs @@ -0,0 +1,20 @@ +// Opaque macro can eagerly expand its input without breaking its resolution. +// Regression test for issue #63685. + +// check-pass + +macro_rules! foo { + () => { + "foo" + }; +} + +macro_rules! bar { + () => { + foo!() + }; +} + +fn main() { + format_args!(bar!()); +} diff --git a/src/test/ui/impl-trait/bound-normalization-fail.rs b/src/test/ui/impl-trait/bound-normalization-fail.rs index ce1550568c1..235c1f80ef6 100644 --- a/src/test/ui/impl-trait/bound-normalization-fail.rs +++ b/src/test/ui/impl-trait/bound-normalization-fail.rs @@ -2,7 +2,6 @@ // ignore-tidy-linelength // edition:2018 -#![feature(async_await)] #![feature(impl_trait_in_bindings)] //~^ WARNING the feature `impl_trait_in_bindings` is incomplete diff --git a/src/test/ui/impl-trait/bound-normalization-fail.stderr b/src/test/ui/impl-trait/bound-normalization-fail.stderr index 4811b1e0ff3..2c4c61a0957 100644 --- a/src/test/ui/impl-trait/bound-normalization-fail.stderr +++ b/src/test/ui/impl-trait/bound-normalization-fail.stderr @@ -1,5 +1,5 @@ warning: the feature `impl_trait_in_bindings` is incomplete and may cause the compiler to crash - --> $DIR/bound-normalization-fail.rs:6:12 + --> $DIR/bound-normalization-fail.rs:5:12 | LL | #![feature(impl_trait_in_bindings)] | ^^^^^^^^^^^^^^^^^^^^^^ @@ -7,7 +7,7 @@ LL | #![feature(impl_trait_in_bindings)] = note: `#[warn(incomplete_features)]` on by default error[E0271]: type mismatch resolving `<Foo<()> as FooLike>::Output == <T as impl_trait::Trait>::Assoc` - --> $DIR/bound-normalization-fail.rs:29:32 + --> $DIR/bound-normalization-fail.rs:28:32 | LL | fn foo_fail<T: Trait>() -> impl FooLike<Output=T::Assoc> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected (), found associated type @@ -17,13 +17,13 @@ LL | fn foo_fail<T: Trait>() -> impl FooLike<Output=T::Assoc> { = note: the return type of a function must have a statically known size error: `impl Trait` return type cannot contain a projection or `Self` that references lifetimes from a parent scope - --> $DIR/bound-normalization-fail.rs:45:41 + --> $DIR/bound-normalization-fail.rs:44: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:45:41 + --> $DIR/bound-normalization-fail.rs:44:41 | LL | fn foo2_fail<'a, T: Trait<'a>>() -> impl FooLike<Output=T::Assoc> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected (), found associated type diff --git a/src/test/ui/impl-trait/bound-normalization-pass.rs b/src/test/ui/impl-trait/bound-normalization-pass.rs index b0ed4be54b8..fff17667fda 100644 --- a/src/test/ui/impl-trait/bound-normalization-pass.rs +++ b/src/test/ui/impl-trait/bound-normalization-pass.rs @@ -1,7 +1,6 @@ // check-pass // edition:2018 -#![feature(async_await)] #![feature(type_alias_impl_trait)] #![feature(impl_trait_in_bindings)] //~^ WARNING the feature `impl_trait_in_bindings` is incomplete diff --git a/src/test/ui/impl-trait/bound-normalization-pass.stderr b/src/test/ui/impl-trait/bound-normalization-pass.stderr index 229acdb2b14..d048da7f60b 100644 --- a/src/test/ui/impl-trait/bound-normalization-pass.stderr +++ b/src/test/ui/impl-trait/bound-normalization-pass.stderr @@ -1,5 +1,5 @@ warning: the feature `impl_trait_in_bindings` is incomplete and may cause the compiler to crash - --> $DIR/bound-normalization-pass.rs:6:12 + --> $DIR/bound-normalization-pass.rs:5:12 | LL | #![feature(impl_trait_in_bindings)] | ^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/impl-trait/issue-55872-2.rs b/src/test/ui/impl-trait/issue-55872-2.rs index dfee20ca649..1ca2e3d9065 100644 --- a/src/test/ui/impl-trait/issue-55872-2.rs +++ b/src/test/ui/impl-trait/issue-55872-2.rs @@ -1,6 +1,7 @@ // edition:2018 // ignore-tidy-linelength -#![feature(async_await, type_alias_impl_trait)] + +#![feature(type_alias_impl_trait)] pub trait Bar { type E: Copy; diff --git a/src/test/ui/impl-trait/issue-55872-2.stderr b/src/test/ui/impl-trait/issue-55872-2.stderr index 676c3fe3d4c..01371b4d5c6 100644 --- a/src/test/ui/impl-trait/issue-55872-2.stderr +++ b/src/test/ui/impl-trait/issue-55872-2.stderr @@ -1,5 +1,5 @@ error[E0277]: the trait bound `impl std::future::Future: std::marker::Copy` is not satisfied - --> $DIR/issue-55872-2.rs:12:5 + --> $DIR/issue-55872-2.rs:13:5 | LL | type E = impl Copy; | ^^^^^^^^^^^^^^^^^^^ the trait `std::marker::Copy` is not implemented for `impl std::future::Future` @@ -7,7 +7,7 @@ LL | type E = impl Copy; = note: the return type of a function must have a statically known size error: type parameter `T` is part of concrete type but not used in parameter list for the `impl Trait` type alias - --> $DIR/issue-55872-2.rs:14:28 + --> $DIR/issue-55872-2.rs:15:28 | LL | fn foo<T>() -> Self::E { | ____________________________^ diff --git a/src/test/ui/inference/cannot-infer-async-enabled-impl-trait-bindings.rs b/src/test/ui/inference/cannot-infer-async-enabled-impl-trait-bindings.rs index 30ed5050433..7d75f254bfe 100644 --- a/src/test/ui/inference/cannot-infer-async-enabled-impl-trait-bindings.rs +++ b/src/test/ui/inference/cannot-infer-async-enabled-impl-trait-bindings.rs @@ -1,5 +1,4 @@ // edition:2018 -#![feature(async_await)] #![feature(impl_trait_in_bindings)] //~^ WARN the feature `impl_trait_in_bindings` is incomplete and may cause the compiler to crash diff --git a/src/test/ui/inference/cannot-infer-async-enabled-impl-trait-bindings.stderr b/src/test/ui/inference/cannot-infer-async-enabled-impl-trait-bindings.stderr index 67a834a2e95..f67e45b01d2 100644 --- a/src/test/ui/inference/cannot-infer-async-enabled-impl-trait-bindings.stderr +++ b/src/test/ui/inference/cannot-infer-async-enabled-impl-trait-bindings.stderr @@ -1,5 +1,5 @@ warning: the feature `impl_trait_in_bindings` is incomplete and may cause the compiler to crash - --> $DIR/cannot-infer-async-enabled-impl-trait-bindings.rs:3:12 + --> $DIR/cannot-infer-async-enabled-impl-trait-bindings.rs:2:12 | LL | #![feature(impl_trait_in_bindings)] | ^^^^^^^^^^^^^^^^^^^^^^ @@ -7,7 +7,7 @@ LL | #![feature(impl_trait_in_bindings)] = note: `#[warn(incomplete_features)]` on by default error[E0282]: type annotations needed for `impl std::future::Future` - --> $DIR/cannot-infer-async-enabled-impl-trait-bindings.rs:14:9 + --> $DIR/cannot-infer-async-enabled-impl-trait-bindings.rs:13:9 | LL | let fut = async { | --- consider giving `fut` the explicit type `impl std::future::Future`, with the type parameters specified diff --git a/src/test/ui/inference/cannot-infer-async.rs b/src/test/ui/inference/cannot-infer-async.rs index edc64276e7c..05f62f3d8cb 100644 --- a/src/test/ui/inference/cannot-infer-async.rs +++ b/src/test/ui/inference/cannot-infer-async.rs @@ -1,5 +1,4 @@ // edition:2018 -#![feature(async_await)] use std::io::Error; diff --git a/src/test/ui/inference/cannot-infer-async.stderr b/src/test/ui/inference/cannot-infer-async.stderr index 36608a11bb7..bf31fb85cf6 100644 --- a/src/test/ui/inference/cannot-infer-async.stderr +++ b/src/test/ui/inference/cannot-infer-async.stderr @@ -1,5 +1,5 @@ error[E0282]: type annotations needed - --> $DIR/cannot-infer-async.rs:12:9 + --> $DIR/cannot-infer-async.rs:11:9 | LL | let fut = async { | --- consider giving `fut` a type diff --git a/src/test/ui/issues/issue-28105.rs b/src/test/ui/issues/issue-28105.rs index 6026cbb82ae..1e8d2d6ccf1 100644 --- a/src/test/ui/issues/issue-28105.rs +++ b/src/test/ui/issues/issue-28105.rs @@ -1,8 +1,8 @@ // Make sure that a continue span actually contains the keyword. fn main() { - continue //~ ERROR `continue` outside of loop + continue //~ ERROR `continue` outside of a loop ; - break //~ ERROR `break` outside of loop + break //~ ERROR `break` outside of a loop ; } diff --git a/src/test/ui/issues/issue-28105.stderr b/src/test/ui/issues/issue-28105.stderr index 0e1b90e6520..42ed838d7c0 100644 --- a/src/test/ui/issues/issue-28105.stderr +++ b/src/test/ui/issues/issue-28105.stderr @@ -1,14 +1,14 @@ -error[E0268]: `continue` outside of loop +error[E0268]: `continue` outside of a loop --> $DIR/issue-28105.rs:4:5 | LL | continue - | ^^^^^^^^ cannot break outside of a loop + | ^^^^^^^^ cannot `continue` outside of a loop -error[E0268]: `break` outside of loop +error[E0268]: `break` outside of a loop --> $DIR/issue-28105.rs:6:5 | LL | break - | ^^^^^ cannot break outside of a loop + | ^^^^^ cannot `break` outside of a loop error: aborting due to 2 previous errors diff --git a/src/test/ui/issues/issue-31776.rs b/src/test/ui/issues/issue-31776.rs index c0d2c91e577..c86623ce289 100644 --- a/src/test/ui/issues/issue-31776.rs +++ b/src/test/ui/issues/issue-31776.rs @@ -13,7 +13,7 @@ mod m { } } -// ------------------------------------------------------ +// Scenario 1 pub trait Tr { type A; @@ -28,7 +28,7 @@ fn f() { } } -// ------------------------------------------------------ +// Scenario 2 trait Tr1 { type A; @@ -49,8 +49,6 @@ mod m1 { } } -// ------------------------------------------------------ - fn main() { S.s(); // Privacy error, unless `fn s` is pub let a = S2.pull().field; // Privacy error unless `field: u8` is pub diff --git a/src/test/ui/issues/issue-43162.stderr b/src/test/ui/issues/issue-43162.stderr index 6d3e8b5ba23..c729c05ff22 100644 --- a/src/test/ui/issues/issue-43162.stderr +++ b/src/test/ui/issues/issue-43162.stderr @@ -1,14 +1,14 @@ -error[E0268]: `break` outside of loop +error[E0268]: `break` outside of a loop --> $DIR/issue-43162.rs:3:5 | LL | break true; - | ^^^^^^^^^^ cannot break outside of a loop + | ^^^^^^^^^^ cannot `break` outside of a loop -error[E0268]: `break` outside of loop +error[E0268]: `break` outside of a loop --> $DIR/issue-43162.rs:7:5 | LL | break {}; - | ^^^^^^^^ cannot break outside of a loop + | ^^^^^^^^ cannot `break` outside of a loop error[E0308]: mismatched types --> $DIR/issue-43162.rs:1:13 diff --git a/src/test/ui/issues/issue-50415.rs b/src/test/ui/issues/issue-50415.rs index 20c7be772f9..151b9fe442c 100644 --- a/src/test/ui/issues/issue-50415.rs +++ b/src/test/ui/issues/issue-50415.rs @@ -1,11 +1,9 @@ // run-pass fn main() { - // -------- Simplified test case -------- - + // Simplified test case let _ = || 0..=1; - // -------- Original test case -------- - + // Original test case let full_length = 1024; let range = { // do some stuff, omit here diff --git a/src/test/ui/issues/issue-50576.stderr b/src/test/ui/issues/issue-50576.stderr index 95619eeed9a..9fea1411080 100644 --- a/src/test/ui/issues/issue-50576.stderr +++ b/src/test/ui/issues/issue-50576.stderr @@ -4,17 +4,17 @@ error[E0426]: use of undeclared label `'L` LL | |bool: [u8; break 'L]| 0; | ^^ undeclared label `'L` -error[E0268]: `break` outside of loop +error[E0268]: `break` outside of a loop --> $DIR/issue-50576.rs:2:17 | LL | |bool: [u8; break 'L]| 0; - | ^^^^^^^^ cannot break outside of a loop + | ^^^^^^^^ cannot `break` outside of a loop -error[E0268]: `break` outside of loop +error[E0268]: `break` outside of a loop --> $DIR/issue-50576.rs:5:16 | LL | Vec::<[u8; break]>::new(); - | ^^^^^ cannot break outside of a loop + | ^^^^^ cannot `break` outside of a loop error: aborting due to 3 previous errors diff --git a/src/test/ui/issues/issue-50581.stderr b/src/test/ui/issues/issue-50581.stderr index 01a5f9b3c44..35d6fc49ced 100644 --- a/src/test/ui/issues/issue-50581.stderr +++ b/src/test/ui/issues/issue-50581.stderr @@ -1,8 +1,8 @@ -error[E0268]: `break` outside of loop +error[E0268]: `break` outside of a loop --> $DIR/issue-50581.rs:2:14 | LL | |_: [u8; break]| (); - | ^^^^^ cannot break outside of a loop + | ^^^^^ cannot `break` outside of a loop error: aborting due to previous error diff --git a/src/test/ui/issues/issue-5067.rs b/src/test/ui/issues/issue-5067.rs index 616fd09907a..5857a081596 100644 --- a/src/test/ui/issues/issue-5067.rs +++ b/src/test/ui/issues/issue-5067.rs @@ -54,7 +54,7 @@ macro_rules! foo { //~^ ERROR repetition matches empty token tree } -// --- Original Issue --- // +// Original Issue macro_rules! make_vec { (a $e1:expr $($(, a $e2:expr)*)*) => ([$e1 $($(, $e2)*)*]); @@ -65,7 +65,7 @@ fn main() { let _ = make_vec![a 1, a 2, a 3]; } -// --- Minified Issue --- // +// Minified Issue macro_rules! m { ( $()* ) => {}; diff --git a/src/test/ui/lint/lint-unused-mut-variables.rs b/src/test/ui/lint/lint-unused-mut-variables.rs index 2957f931110..f140546b048 100644 --- a/src/test/ui/lint/lint-unused-mut-variables.rs +++ b/src/test/ui/lint/lint-unused-mut-variables.rs @@ -3,7 +3,7 @@ // Exercise the unused_mut attribute in some positive and negative cases #![deny(unused_mut)] -#![feature(async_await, async_closure, param_attrs)] +#![feature(async_closure, param_attrs)] async fn baz_async( mut a: i32, diff --git a/src/test/ui/lint/lint-unused-variables.rs b/src/test/ui/lint/lint-unused-variables.rs index a1660d23511..06b818636f9 100644 --- a/src/test/ui/lint/lint-unused-variables.rs +++ b/src/test/ui/lint/lint-unused-variables.rs @@ -1,7 +1,7 @@ // compile-flags: --cfg something // edition:2018 -#![feature(async_await, async_closure, param_attrs)] +#![feature(async_closure, param_attrs)] #![deny(unused_variables)] async fn foo_async( diff --git a/src/test/ui/macros/derive-in-eager-expansion-hang.stderr b/src/test/ui/macros/derive-in-eager-expansion-hang.stderr index 1ef9427666b..5ca4088e585 100644 --- a/src/test/ui/macros/derive-in-eager-expansion-hang.stderr +++ b/src/test/ui/macros/derive-in-eager-expansion-hang.stderr @@ -8,6 +8,9 @@ LL | | LL | | "" LL | | } | |_____^ +... +LL | format_args!(hang!()); + | ------- in this macro invocation help: you might be missing a string literal to format with | LL | format_args!("{}", hang!()); diff --git a/src/test/ui/macros/macro-in-fn.rs b/src/test/ui/macros/macro-in-fn.rs new file mode 100644 index 00000000000..d354fe4a7db --- /dev/null +++ b/src/test/ui/macros/macro-in-fn.rs @@ -0,0 +1,8 @@ +// run-pass +#![feature(decl_macro)] + +pub fn moo() { + pub macro ABC() {{}} +} + +fn main() {} diff --git a/src/test/ui/macros/restricted-shadowing-modern.rs b/src/test/ui/macros/restricted-shadowing-modern.rs index a8818507d75..1151a829eba 100644 --- a/src/test/ui/macros/restricted-shadowing-modern.rs +++ b/src/test/ui/macros/restricted-shadowing-modern.rs @@ -95,8 +95,6 @@ macro include() { m!() } - // ----------------------------------------------------------- - fn check1() { macro m() {} { diff --git a/src/test/ui/macros/restricted-shadowing-modern.stderr b/src/test/ui/macros/restricted-shadowing-modern.stderr index d147debeb51..12075d42b9a 100644 --- a/src/test/ui/macros/restricted-shadowing-modern.stderr +++ b/src/test/ui/macros/restricted-shadowing-modern.stderr @@ -1,5 +1,5 @@ error[E0659]: `m` is ambiguous (macro-expanded name vs less macro-expanded name from outer scope during import/macro resolution) - --> $DIR/restricted-shadowing-modern.rs:106:17 + --> $DIR/restricted-shadowing-modern.rs:104:17 | LL | m!(); | ^ ambiguous name @@ -16,7 +16,7 @@ LL | macro m() { Right } LL | include!(); | ----------- in this macro invocation note: `m` could also refer to the macro defined here - --> $DIR/restricted-shadowing-modern.rs:101:9 + --> $DIR/restricted-shadowing-modern.rs:99:9 | LL | macro m() {} | ^^^^^^^^^^^^ @@ -25,7 +25,7 @@ LL | include!(); | ----------- in this macro invocation error[E0659]: `m` is ambiguous (macro-expanded name vs less macro-expanded name from outer scope during import/macro resolution) - --> $DIR/restricted-shadowing-modern.rs:149:33 + --> $DIR/restricted-shadowing-modern.rs:147:33 | LL | macro gen_invoc() { m!() } | ^ ambiguous name @@ -42,7 +42,7 @@ LL | macro m() { Right } LL | include!(); | ----------- in this macro invocation note: `m` could also refer to the macro defined here - --> $DIR/restricted-shadowing-modern.rs:145:9 + --> $DIR/restricted-shadowing-modern.rs:143:9 | LL | macro m() {} | ^^^^^^^^^^^^ @@ -51,7 +51,7 @@ LL | include!(); | ----------- in this macro invocation error[E0659]: `m` is ambiguous (macro-expanded name vs less macro-expanded name from outer scope during import/macro resolution) - --> $DIR/restricted-shadowing-modern.rs:158:13 + --> $DIR/restricted-shadowing-modern.rs:156:13 | LL | m!(); | ^ ambiguous name @@ -68,7 +68,7 @@ LL | macro m() { Right } LL | include!(); | ----------- in this macro invocation note: `m` could also refer to the macro defined here - --> $DIR/restricted-shadowing-modern.rs:155:9 + --> $DIR/restricted-shadowing-modern.rs:153:9 | LL | macro m() {} | ^^^^^^^^^^^^ @@ -77,7 +77,7 @@ LL | include!(); | ----------- in this macro invocation error[E0659]: `m` is ambiguous (macro-expanded name vs less macro-expanded name from outer scope during import/macro resolution) - --> $DIR/restricted-shadowing-modern.rs:174:13 + --> $DIR/restricted-shadowing-modern.rs:172:13 | LL | m!(); | ^ ambiguous name @@ -103,7 +103,7 @@ LL | include!(); | ----------- in this macro invocation error[E0659]: `m` is ambiguous (macro-expanded name vs less macro-expanded name from outer scope during import/macro resolution) - --> $DIR/restricted-shadowing-modern.rs:192:17 + --> $DIR/restricted-shadowing-modern.rs:190:17 | LL | m!(); | ^ ambiguous name @@ -129,7 +129,7 @@ LL | include!(); | ----------- in this macro invocation error[E0659]: `m` is ambiguous (macro-expanded name vs less macro-expanded name from outer scope during import/macro resolution) - --> $DIR/restricted-shadowing-modern.rs:235:33 + --> $DIR/restricted-shadowing-modern.rs:233:33 | LL | macro gen_invoc() { m!() } | ^ ambiguous name diff --git a/src/test/ui/malformed/malformed-regressions.stderr b/src/test/ui/malformed/malformed-regressions.stderr index eebb6f0623f..164668f562c 100644 --- a/src/test/ui/malformed/malformed-regressions.stderr +++ b/src/test/ui/malformed/malformed-regressions.stderr @@ -26,8 +26,7 @@ LL | #[inline = ""] = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #57571 <https://github.com/rust-lang/rust/issues/57571> -warning: attribute must be of the form `#[link(name = "...", /*opt*/ kind = "dylib|static|...", - /*opt*/ cfg = "...")]` +warning: attribute must be of the form `#[link(name = "...", /*opt*/ kind = "dylib|static|...", /*opt*/ cfg = "...")]` --> $DIR/malformed-regressions.rs:6:1 | LL | #[link] @@ -36,8 +35,7 @@ LL | #[link] = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #57571 <https://github.com/rust-lang/rust/issues/57571> -warning: attribute must be of the form `#[link(name = "...", /*opt*/ kind = "dylib|static|...", - /*opt*/ cfg = "...")]` +warning: attribute must be of the form `#[link(name = "...", /*opt*/ kind = "dylib|static|...", /*opt*/ cfg = "...")]` --> $DIR/malformed-regressions.rs:7:1 | LL | #[link = ""] diff --git a/src/test/ui/non-interger-atomic.rs b/src/test/ui/non-integer-atomic.rs index 00d07b7fe48..00d07b7fe48 100644 --- a/src/test/ui/non-interger-atomic.rs +++ b/src/test/ui/non-integer-atomic.rs diff --git a/src/test/ui/non-interger-atomic.stderr b/src/test/ui/non-integer-atomic.stderr index 7d1130d238e..b3cf788d834 100644 --- a/src/test/ui/non-interger-atomic.stderr +++ b/src/test/ui/non-integer-atomic.stderr @@ -1,95 +1,95 @@ error[E0511]: invalid monomorphization of `atomic_load` intrinsic: expected basic integer type, found `bool` - --> $DIR/non-interger-atomic.rs:13:5 + --> $DIR/non-integer-atomic.rs:13:5 | LL | intrinsics::atomic_load(p); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `atomic_store` intrinsic: expected basic integer type, found `bool` - --> $DIR/non-interger-atomic.rs:18:5 + --> $DIR/non-integer-atomic.rs:18:5 | LL | intrinsics::atomic_store(p, v); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `atomic_xchg` intrinsic: expected basic integer type, found `bool` - --> $DIR/non-interger-atomic.rs:23:5 + --> $DIR/non-integer-atomic.rs:23:5 | LL | intrinsics::atomic_xchg(p, v); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `atomic_cxchg` intrinsic: expected basic integer type, found `bool` - --> $DIR/non-interger-atomic.rs:28:5 + --> $DIR/non-integer-atomic.rs:28:5 | LL | intrinsics::atomic_cxchg(p, v, v); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `atomic_load` intrinsic: expected basic integer type, found `Foo` - --> $DIR/non-interger-atomic.rs:33:5 + --> $DIR/non-integer-atomic.rs:33:5 | LL | intrinsics::atomic_load(p); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `atomic_store` intrinsic: expected basic integer type, found `Foo` - --> $DIR/non-interger-atomic.rs:38:5 + --> $DIR/non-integer-atomic.rs:38:5 | LL | intrinsics::atomic_store(p, v); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `atomic_xchg` intrinsic: expected basic integer type, found `Foo` - --> $DIR/non-interger-atomic.rs:43:5 + --> $DIR/non-integer-atomic.rs:43:5 | LL | intrinsics::atomic_xchg(p, v); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `atomic_cxchg` intrinsic: expected basic integer type, found `Foo` - --> $DIR/non-interger-atomic.rs:48:5 + --> $DIR/non-integer-atomic.rs:48:5 | LL | intrinsics::atomic_cxchg(p, v, v); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `atomic_load` intrinsic: expected basic integer type, found `&dyn std::ops::Fn()` - --> $DIR/non-interger-atomic.rs:53:5 + --> $DIR/non-integer-atomic.rs:53:5 | LL | intrinsics::atomic_load(p); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `atomic_store` intrinsic: expected basic integer type, found `&dyn std::ops::Fn()` - --> $DIR/non-interger-atomic.rs:58:5 + --> $DIR/non-integer-atomic.rs:58:5 | LL | intrinsics::atomic_store(p, v); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `atomic_xchg` intrinsic: expected basic integer type, found `&dyn std::ops::Fn()` - --> $DIR/non-interger-atomic.rs:63:5 + --> $DIR/non-integer-atomic.rs:63:5 | LL | intrinsics::atomic_xchg(p, v); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `atomic_cxchg` intrinsic: expected basic integer type, found `&dyn std::ops::Fn()` - --> $DIR/non-interger-atomic.rs:68:5 + --> $DIR/non-integer-atomic.rs:68:5 | LL | intrinsics::atomic_cxchg(p, v, v); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `atomic_load` intrinsic: expected basic integer type, found `[u8; 100]` - --> $DIR/non-interger-atomic.rs:73:5 + --> $DIR/non-integer-atomic.rs:73:5 | LL | intrinsics::atomic_load(p); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `atomic_store` intrinsic: expected basic integer type, found `[u8; 100]` - --> $DIR/non-interger-atomic.rs:78:5 + --> $DIR/non-integer-atomic.rs:78:5 | LL | intrinsics::atomic_store(p, v); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `atomic_xchg` intrinsic: expected basic integer type, found `[u8; 100]` - --> $DIR/non-interger-atomic.rs:83:5 + --> $DIR/non-integer-atomic.rs:83:5 | LL | intrinsics::atomic_xchg(p, v); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0511]: invalid monomorphization of `atomic_cxchg` intrinsic: expected basic integer type, found `[u8; 100]` - --> $DIR/non-interger-atomic.rs:88:5 + --> $DIR/non-integer-atomic.rs:88:5 | LL | intrinsics::atomic_cxchg(p, v, v); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/regions/regions-assoc-type-in-supertrait-outlives-container.migrate.nll.stderr b/src/test/ui/regions/regions-assoc-type-in-supertrait-outlives-container.migrate.nll.stderr index 867eafe2529..4944f2649b7 100644 --- a/src/test/ui/regions/regions-assoc-type-in-supertrait-outlives-container.migrate.nll.stderr +++ b/src/test/ui/regions/regions-assoc-type-in-supertrait-outlives-container.migrate.nll.stderr @@ -1,5 +1,5 @@ error: lifetime may not live long enough - --> $DIR/regions-assoc-type-in-supertrait-outlives-container.rs:43:12 + --> $DIR/regions-assoc-type-in-supertrait-outlives-container.rs:39:12 | LL | fn with_assoc<'a,'b>() { | -- -- lifetime `'b` defined here diff --git a/src/test/ui/regions/regions-assoc-type-in-supertrait-outlives-container.migrate.stderr b/src/test/ui/regions/regions-assoc-type-in-supertrait-outlives-container.migrate.stderr index f31f25bf00b..61be0778c99 100644 --- a/src/test/ui/regions/regions-assoc-type-in-supertrait-outlives-container.migrate.stderr +++ b/src/test/ui/regions/regions-assoc-type-in-supertrait-outlives-container.migrate.stderr @@ -1,16 +1,16 @@ error[E0491]: in type `&'a WithAssoc<TheType<'b>>`, reference has a longer lifetime than the data it references - --> $DIR/regions-assoc-type-in-supertrait-outlives-container.rs:43:12 + --> $DIR/regions-assoc-type-in-supertrait-outlives-container.rs:39:12 | LL | let _: &'a WithAssoc<TheType<'b>> = loop { }; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | -note: the pointer is valid for the lifetime 'a as defined on the function body at 37:15 - --> $DIR/regions-assoc-type-in-supertrait-outlives-container.rs:37:15 +note: the pointer is valid for the lifetime 'a as defined on the function body at 33:15 + --> $DIR/regions-assoc-type-in-supertrait-outlives-container.rs:33:15 | LL | fn with_assoc<'a,'b>() { | ^^ -note: but the referenced data is only valid for the lifetime 'b as defined on the function body at 37:18 - --> $DIR/regions-assoc-type-in-supertrait-outlives-container.rs:37:18 +note: but the referenced data is only valid for the lifetime 'b as defined on the function body at 33:18 + --> $DIR/regions-assoc-type-in-supertrait-outlives-container.rs:33:18 | LL | fn with_assoc<'a,'b>() { | ^^ diff --git a/src/test/ui/regions/regions-assoc-type-in-supertrait-outlives-container.nll.stderr b/src/test/ui/regions/regions-assoc-type-in-supertrait-outlives-container.nll.stderr index 867eafe2529..4944f2649b7 100644 --- a/src/test/ui/regions/regions-assoc-type-in-supertrait-outlives-container.nll.stderr +++ b/src/test/ui/regions/regions-assoc-type-in-supertrait-outlives-container.nll.stderr @@ -1,5 +1,5 @@ error: lifetime may not live long enough - --> $DIR/regions-assoc-type-in-supertrait-outlives-container.rs:43:12 + --> $DIR/regions-assoc-type-in-supertrait-outlives-container.rs:39:12 | LL | fn with_assoc<'a,'b>() { | -- -- lifetime `'b` defined here diff --git a/src/test/ui/regions/regions-assoc-type-in-supertrait-outlives-container.rs b/src/test/ui/regions/regions-assoc-type-in-supertrait-outlives-container.rs index 97c55593600..046d010002e 100644 --- a/src/test/ui/regions/regions-assoc-type-in-supertrait-outlives-container.rs +++ b/src/test/ui/regions/regions-assoc-type-in-supertrait-outlives-container.rs @@ -8,8 +8,6 @@ #![allow(dead_code)] -/////////////////////////////////////////////////////////////////////////// - pub trait TheTrait { type TheAssocType; } @@ -28,8 +26,6 @@ impl<'b> TheTrait for TheType<'b> { impl<'b> TheSubTrait for TheType<'b> { } -/////////////////////////////////////////////////////////////////////////// - pub struct WithAssoc<T:TheSubTrait> { m: [T; 0] } diff --git a/src/test/ui/rfc-2565-param-attrs/param-attrs-cfg.rs b/src/test/ui/rfc-2565-param-attrs/param-attrs-cfg.rs index 069332ffa25..5ad6e23cf2a 100644 --- a/src/test/ui/rfc-2565-param-attrs/param-attrs-cfg.rs +++ b/src/test/ui/rfc-2565-param-attrs/param-attrs-cfg.rs @@ -1,7 +1,7 @@ // compile-flags: --cfg something // edition:2018 -#![feature(async_await, async_closure, param_attrs)] +#![feature(async_closure, param_attrs)] #![deny(unused_variables)] extern "C" { diff --git a/src/test/ui/self/arbitrary_self_types_pin_lifetime-async.rs b/src/test/ui/self/arbitrary_self_types_pin_lifetime-async.rs index b853f88a96d..f3474bc1f9f 100644 --- a/src/test/ui/self/arbitrary_self_types_pin_lifetime-async.rs +++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime-async.rs @@ -1,8 +1,6 @@ // check-pass // edition:2018 -#![feature(async_await)] - use std::pin::Pin; use std::task::{Context, Poll}; diff --git a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.nll.stderr b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.nll.stderr index 2421632c664..a585b4fdbe6 100644 --- a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.nll.stderr +++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.nll.stderr @@ -1,5 +1,5 @@ error: lifetime may not live long enough - --> $DIR/arbitrary_self_types_pin_lifetime_impl_trait-async.rs:10:48 + --> $DIR/arbitrary_self_types_pin_lifetime_impl_trait-async.rs:8:48 | LL | async fn f(self: Pin<&Self>) -> impl Clone { self } | - ^^^^^^^^ returning this value requires that `'_` must outlive `'static` diff --git a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.rs b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.rs index aecb82325c1..0afe631f1e3 100644 --- a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.rs +++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.rs @@ -1,7 +1,5 @@ // edition:2018 -#![feature(async_await)] - use std::pin::Pin; struct Foo; diff --git a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.stderr b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.stderr index f0032449db1..2fb152475a1 100644 --- a/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.stderr +++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime_impl_trait-async.stderr @@ -1,17 +1,17 @@ error: cannot infer an appropriate lifetime - --> $DIR/arbitrary_self_types_pin_lifetime_impl_trait-async.rs:10:16 + --> $DIR/arbitrary_self_types_pin_lifetime_impl_trait-async.rs:8:16 | LL | async fn f(self: Pin<&Self>) -> impl Clone { self } | ^^^^ ---------- this return type evaluates to the `'static` lifetime... | | | ...but this borrow... | -note: ...can't outlive the lifetime '_ as defined on the method body at 10:26 - --> $DIR/arbitrary_self_types_pin_lifetime_impl_trait-async.rs:10:26 +note: ...can't outlive the lifetime '_ as defined on the method body at 8:26 + --> $DIR/arbitrary_self_types_pin_lifetime_impl_trait-async.rs:8:26 | LL | async fn f(self: Pin<&Self>) -> impl Clone { self } | ^ -help: you can add a constraint to the return type to make it last less than `'static` and match the lifetime '_ as defined on the method body at 10:26 +help: you can add a constraint to the return type to make it last less than `'static` and match the lifetime '_ as defined on the method body at 8:26 | LL | async fn f(self: Pin<&Self>) -> impl Clone + '_ { self } | ^^^^^^^^^^^^^^^ diff --git a/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.nll.stderr b/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.nll.stderr index e33001b9244..e53d91c3604 100644 --- a/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.nll.stderr +++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.nll.stderr @@ -1,5 +1,5 @@ error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds - --> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:10:45 + --> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:8:45 | LL | async fn a(self: Pin<&Foo>, f: &Foo) -> &Foo { f } | ^^^^ @@ -7,7 +7,7 @@ LL | async fn a(self: Pin<&Foo>, f: &Foo) -> &Foo { f } = note: hidden type `impl std::future::Future` captures lifetime '_#15r error: lifetime may not live long enough - --> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:10:50 + --> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:8:50 | LL | async fn a(self: Pin<&Foo>, f: &Foo) -> &Foo { f } | - ^^^^^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_` @@ -16,7 +16,7 @@ LL | async fn a(self: Pin<&Foo>, f: &Foo) -> &Foo { f } | lifetime `'_` defined here error: lifetime may not live long enough - --> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:13:73 + --> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:11:73 | LL | async fn c(self: Pin<&Self>, f: &Foo, g: &Foo) -> (Pin<&Foo>, &Foo) { (self, f) } | - ^^^^^^^^^^^^^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_` @@ -25,7 +25,7 @@ LL | async fn c(self: Pin<&Self>, f: &Foo, g: &Foo) -> (Pin<&Foo>, &Foo) { ( | lifetime `'_` defined here error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds - --> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:19:58 + --> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:17:58 | LL | async fn bar<'a>(self: Alias<&Self>, arg: &'a ()) -> &() { arg } | ^^^ @@ -33,7 +33,7 @@ LL | async fn bar<'a>(self: Alias<&Self>, arg: &'a ()) -> &() { arg } = note: hidden type `impl std::future::Future` captures lifetime '_#15r error: lifetime may not live long enough - --> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:19:62 + --> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:17:62 | LL | async fn bar<'a>(self: Alias<&Self>, arg: &'a ()) -> &() { arg } | -- - ^^^^^^^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'a` diff --git a/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.rs b/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.rs index 53ab75ee16b..f42337d5340 100644 --- a/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.rs +++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.rs @@ -1,7 +1,5 @@ // edition:2018 -#![feature(async_await)] - use std::pin::Pin; struct Foo; diff --git a/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.stderr b/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.stderr index 74fc4741349..57ad026bdcf 100644 --- a/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.stderr +++ b/src/test/ui/self/arbitrary_self_types_pin_lifetime_mismatch-async.stderr @@ -1,5 +1,5 @@ error[E0623]: lifetime mismatch - --> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:10:45 + --> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:8:45 | LL | async fn a(self: Pin<&Foo>, f: &Foo) -> &Foo { f } | ---- ^^^^ @@ -8,7 +8,7 @@ LL | async fn a(self: Pin<&Foo>, f: &Foo) -> &Foo { f } | this parameter and the return type are declared with different lifetimes... error[E0623]: lifetime mismatch - --> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:13:55 + --> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:11:55 | LL | async fn c(self: Pin<&Self>, f: &Foo, g: &Foo) -> (Pin<&Foo>, &Foo) { (self, f) } | ----- ^^^^^^^^^^^^^^^^^ @@ -17,7 +17,7 @@ LL | async fn c(self: Pin<&Self>, f: &Foo, g: &Foo) -> (Pin<&Foo>, &Foo) { ( | this parameter and the return type are declared with different lifetimes... error[E0623]: lifetime mismatch - --> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:19:58 + --> $DIR/arbitrary_self_types_pin_lifetime_mismatch-async.rs:17:58 | LL | async fn bar<'a>(self: Alias<&Self>, arg: &'a ()) -> &() { arg } | ----- ^^^ diff --git a/src/test/ui/self/elision/alias-async.rs b/src/test/ui/self/elision/alias-async.rs index 3d5b24a8946..9743c139096 100644 --- a/src/test/ui/self/elision/alias-async.rs +++ b/src/test/ui/self/elision/alias-async.rs @@ -1,8 +1,6 @@ // check-pass // edition:2018 -#![feature(async_await)] - #![feature(arbitrary_self_types)] #![allow(non_snake_case)] diff --git a/src/test/ui/self/elision/assoc-async.rs b/src/test/ui/self/elision/assoc-async.rs index 0f33f288772..fa5968de5ac 100644 --- a/src/test/ui/self/elision/assoc-async.rs +++ b/src/test/ui/self/elision/assoc-async.rs @@ -1,8 +1,6 @@ // check-pass // edition:2018 -#![feature(async_await)] - #![feature(arbitrary_self_types)] #![allow(non_snake_case)] diff --git a/src/test/ui/self/elision/lt-alias-async.rs b/src/test/ui/self/elision/lt-alias-async.rs index 5a8989f078e..cc5badaaa6e 100644 --- a/src/test/ui/self/elision/lt-alias-async.rs +++ b/src/test/ui/self/elision/lt-alias-async.rs @@ -1,8 +1,6 @@ // check-pass // edition:2018 -#![feature(async_await)] - #![feature(arbitrary_self_types)] #![allow(non_snake_case)] diff --git a/src/test/ui/self/elision/lt-assoc-async.rs b/src/test/ui/self/elision/lt-assoc-async.rs index 98c9aa3b6c2..f060800e4da 100644 --- a/src/test/ui/self/elision/lt-assoc-async.rs +++ b/src/test/ui/self/elision/lt-assoc-async.rs @@ -1,8 +1,6 @@ // check-pass // edition:2018 -#![feature(async_await)] - #![feature(arbitrary_self_types)] #![allow(non_snake_case)] diff --git a/src/test/ui/self/elision/lt-ref-self-async.nll.stderr b/src/test/ui/self/elision/lt-ref-self-async.nll.stderr index 3e58c973019..998178dde1d 100644 --- a/src/test/ui/self/elision/lt-ref-self-async.nll.stderr +++ b/src/test/ui/self/elision/lt-ref-self-async.nll.stderr @@ -1,5 +1,5 @@ error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds - --> $DIR/lt-ref-self-async.rs:15:42 + --> $DIR/lt-ref-self-async.rs:13:42 | LL | async fn ref_self(&self, f: &u32) -> &u32 { | ^^^^ @@ -7,7 +7,7 @@ LL | async fn ref_self(&self, f: &u32) -> &u32 { = note: hidden type `impl std::future::Future` captures lifetime '_#23r error: lifetime may not live long enough - --> $DIR/lt-ref-self-async.rs:15:47 + --> $DIR/lt-ref-self-async.rs:13:47 | LL | async fn ref_self(&self, f: &u32) -> &u32 { | _______________________-_______________________^ @@ -19,7 +19,7 @@ LL | | } | |_____^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_` error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds - --> $DIR/lt-ref-self-async.rs:21:48 + --> $DIR/lt-ref-self-async.rs:19:48 | LL | async fn ref_Self(self: &Self, f: &u32) -> &u32 { | ^^^^ @@ -27,7 +27,7 @@ LL | async fn ref_Self(self: &Self, f: &u32) -> &u32 { = note: hidden type `impl std::future::Future` captures lifetime '_#23r error: lifetime may not live long enough - --> $DIR/lt-ref-self-async.rs:21:53 + --> $DIR/lt-ref-self-async.rs:19:53 | LL | async fn ref_Self(self: &Self, f: &u32) -> &u32 { | _____________________________-_______________________^ @@ -39,7 +39,7 @@ LL | | } | |_____^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_` error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds - --> $DIR/lt-ref-self-async.rs:25:57 + --> $DIR/lt-ref-self-async.rs:23:57 | LL | async fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 { | ^^^^ @@ -47,7 +47,7 @@ LL | async fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 { = note: hidden type `impl std::future::Future` captures lifetime '_#23r error: lifetime may not live long enough - --> $DIR/lt-ref-self-async.rs:25:62 + --> $DIR/lt-ref-self-async.rs:23:62 | LL | async fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 { | _____________________________________-________________________^ @@ -59,7 +59,7 @@ LL | | } | |_____^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_` error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds - --> $DIR/lt-ref-self-async.rs:29:57 + --> $DIR/lt-ref-self-async.rs:27:57 | LL | async fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 { | ^^^^ @@ -67,7 +67,7 @@ LL | async fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 { = note: hidden type `impl std::future::Future` captures lifetime '_#23r error: lifetime may not live long enough - --> $DIR/lt-ref-self-async.rs:29:62 + --> $DIR/lt-ref-self-async.rs:27:62 | LL | async fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 { | _____________________________________-________________________^ @@ -79,7 +79,7 @@ LL | | } | |_____^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_` error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds - --> $DIR/lt-ref-self-async.rs:33:66 + --> $DIR/lt-ref-self-async.rs:31:66 | LL | async fn box_box_ref_Self(self: Box<Box<&Self>>, f: &u32) -> &u32 { | ^^^^ @@ -87,7 +87,7 @@ LL | async fn box_box_ref_Self(self: Box<Box<&Self>>, f: &u32) -> &u32 { = note: hidden type `impl std::future::Future` captures lifetime '_#23r error: lifetime may not live long enough - --> $DIR/lt-ref-self-async.rs:33:71 + --> $DIR/lt-ref-self-async.rs:31:71 | LL | async fn box_box_ref_Self(self: Box<Box<&Self>>, f: &u32) -> &u32 { | _____________________________________________-_________________________^ @@ -99,7 +99,7 @@ LL | | } | |_____^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_` error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds - --> $DIR/lt-ref-self-async.rs:37:62 + --> $DIR/lt-ref-self-async.rs:35:62 | LL | async fn box_pin_Self(self: Box<Pin<&Self>>, f: &u32) -> &u32 { | ^^^^ @@ -107,7 +107,7 @@ LL | async fn box_pin_Self(self: Box<Pin<&Self>>, f: &u32) -> &u32 { = note: hidden type `impl std::future::Future` captures lifetime '_#23r error: lifetime may not live long enough - --> $DIR/lt-ref-self-async.rs:37:67 + --> $DIR/lt-ref-self-async.rs:35:67 | LL | async fn box_pin_Self(self: Box<Pin<&Self>>, f: &u32) -> &u32 { | _________________________________________-_________________________^ diff --git a/src/test/ui/self/elision/lt-ref-self-async.rs b/src/test/ui/self/elision/lt-ref-self-async.rs index 79a4771978a..e3ca0c2e2dd 100644 --- a/src/test/ui/self/elision/lt-ref-self-async.rs +++ b/src/test/ui/self/elision/lt-ref-self-async.rs @@ -1,7 +1,5 @@ // edition:2018 -#![feature(async_await)] - #![feature(arbitrary_self_types)] #![allow(non_snake_case)] diff --git a/src/test/ui/self/elision/lt-ref-self-async.stderr b/src/test/ui/self/elision/lt-ref-self-async.stderr index 0a459257fa7..2bc64bdf1f7 100644 --- a/src/test/ui/self/elision/lt-ref-self-async.stderr +++ b/src/test/ui/self/elision/lt-ref-self-async.stderr @@ -1,5 +1,5 @@ error[E0623]: lifetime mismatch - --> $DIR/lt-ref-self-async.rs:15:42 + --> $DIR/lt-ref-self-async.rs:13:42 | LL | async fn ref_self(&self, f: &u32) -> &u32 { | ----- ^^^^ @@ -8,7 +8,7 @@ LL | async fn ref_self(&self, f: &u32) -> &u32 { | this parameter and the return type are declared with different lifetimes... error[E0623]: lifetime mismatch - --> $DIR/lt-ref-self-async.rs:21:48 + --> $DIR/lt-ref-self-async.rs:19:48 | LL | async fn ref_Self(self: &Self, f: &u32) -> &u32 { | ----- ^^^^ @@ -17,7 +17,7 @@ LL | async fn ref_Self(self: &Self, f: &u32) -> &u32 { | this parameter and the return type are declared with different lifetimes... error[E0623]: lifetime mismatch - --> $DIR/lt-ref-self-async.rs:25:57 + --> $DIR/lt-ref-self-async.rs:23:57 | LL | async fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 { | ----- ^^^^ @@ -26,7 +26,7 @@ LL | async fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 { | this parameter and the return type are declared with different lifetimes... error[E0623]: lifetime mismatch - --> $DIR/lt-ref-self-async.rs:29:57 + --> $DIR/lt-ref-self-async.rs:27:57 | LL | async fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 { | ----- ^^^^ @@ -35,7 +35,7 @@ LL | async fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 { | this parameter and the return type are declared with different lifetimes... error[E0623]: lifetime mismatch - --> $DIR/lt-ref-self-async.rs:33:66 + --> $DIR/lt-ref-self-async.rs:31:66 | LL | async fn box_box_ref_Self(self: Box<Box<&Self>>, f: &u32) -> &u32 { | ----- ^^^^ @@ -44,7 +44,7 @@ LL | async fn box_box_ref_Self(self: Box<Box<&Self>>, f: &u32) -> &u32 { | this parameter and the return type are declared with different lifetimes... error[E0623]: lifetime mismatch - --> $DIR/lt-ref-self-async.rs:37:62 + --> $DIR/lt-ref-self-async.rs:35:62 | LL | async fn box_pin_Self(self: Box<Pin<&Self>>, f: &u32) -> &u32 { | ----- ^^^^ diff --git a/src/test/ui/self/elision/lt-self-async.rs b/src/test/ui/self/elision/lt-self-async.rs index 0202db8a635..42647b82ef8 100644 --- a/src/test/ui/self/elision/lt-self-async.rs +++ b/src/test/ui/self/elision/lt-self-async.rs @@ -1,8 +1,6 @@ // check-pass // edition:2018 -#![feature(async_await)] - #![feature(arbitrary_self_types)] #![allow(non_snake_case)] diff --git a/src/test/ui/self/elision/lt-struct-async.rs b/src/test/ui/self/elision/lt-struct-async.rs index c0fc63d4232..dc5a53b89d7 100644 --- a/src/test/ui/self/elision/lt-struct-async.rs +++ b/src/test/ui/self/elision/lt-struct-async.rs @@ -1,8 +1,6 @@ // check-pass // edition:2018 -#![feature(async_await)] - #![feature(arbitrary_self_types)] #![allow(non_snake_case)] diff --git a/src/test/ui/self/elision/multiple-ref-self-async.rs b/src/test/ui/self/elision/multiple-ref-self-async.rs index eb8c25277e1..be073c6edba 100644 --- a/src/test/ui/self/elision/multiple-ref-self-async.rs +++ b/src/test/ui/self/elision/multiple-ref-self-async.rs @@ -1,8 +1,6 @@ // check-pass // edition:2018 -#![feature(async_await)] - #![feature(arbitrary_self_types)] #![allow(non_snake_case)] diff --git a/src/test/ui/self/elision/ref-alias-async.rs b/src/test/ui/self/elision/ref-alias-async.rs index acc4b2153ef..4b02c2fd00c 100644 --- a/src/test/ui/self/elision/ref-alias-async.rs +++ b/src/test/ui/self/elision/ref-alias-async.rs @@ -1,8 +1,6 @@ // edition:2018 // check-pass -#![feature(async_await)] - #![feature(arbitrary_self_types)] #![allow(non_snake_case)] diff --git a/src/test/ui/self/elision/ref-assoc-async.rs b/src/test/ui/self/elision/ref-assoc-async.rs index a6b6cbd6da3..258e27b7cb3 100644 --- a/src/test/ui/self/elision/ref-assoc-async.rs +++ b/src/test/ui/self/elision/ref-assoc-async.rs @@ -1,8 +1,6 @@ // edition:2018 // check-pass -#![feature(async_await)] - #![feature(arbitrary_self_types)] #![allow(non_snake_case)] diff --git a/src/test/ui/self/elision/ref-mut-alias-async.rs b/src/test/ui/self/elision/ref-mut-alias-async.rs index 873e92bc6d3..5f9ccf3bc7f 100644 --- a/src/test/ui/self/elision/ref-mut-alias-async.rs +++ b/src/test/ui/self/elision/ref-mut-alias-async.rs @@ -1,7 +1,6 @@ // edition:2018 // check-pass -#![feature(async_await)] #![feature(arbitrary_self_types)] #![allow(non_snake_case)] diff --git a/src/test/ui/self/elision/ref-mut-self-async.nll.stderr b/src/test/ui/self/elision/ref-mut-self-async.nll.stderr index b8a53808810..97bc80509df 100644 --- a/src/test/ui/self/elision/ref-mut-self-async.nll.stderr +++ b/src/test/ui/self/elision/ref-mut-self-async.nll.stderr @@ -1,5 +1,5 @@ error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds - --> $DIR/ref-mut-self-async.rs:15:46 + --> $DIR/ref-mut-self-async.rs:13:46 | LL | async fn ref_self(&mut self, f: &u32) -> &u32 { | ^^^^ @@ -7,7 +7,7 @@ LL | async fn ref_self(&mut self, f: &u32) -> &u32 { = note: hidden type `impl std::future::Future` captures lifetime '_#15r error: lifetime may not live long enough - --> $DIR/ref-mut-self-async.rs:15:51 + --> $DIR/ref-mut-self-async.rs:13:51 | LL | async fn ref_self(&mut self, f: &u32) -> &u32 { | _______________________-___________________________^ @@ -19,7 +19,7 @@ LL | | } | |_____^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_` error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds - --> $DIR/ref-mut-self-async.rs:21:52 + --> $DIR/ref-mut-self-async.rs:19:52 | LL | async fn ref_Self(self: &mut Self, f: &u32) -> &u32 { | ^^^^ @@ -27,7 +27,7 @@ LL | async fn ref_Self(self: &mut Self, f: &u32) -> &u32 { = note: hidden type `impl std::future::Future` captures lifetime '_#15r error: lifetime may not live long enough - --> $DIR/ref-mut-self-async.rs:21:57 + --> $DIR/ref-mut-self-async.rs:19:57 | LL | async fn ref_Self(self: &mut Self, f: &u32) -> &u32 { | _____________________________-___________________________^ @@ -39,7 +39,7 @@ LL | | } | |_____^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_` error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds - --> $DIR/ref-mut-self-async.rs:25:61 + --> $DIR/ref-mut-self-async.rs:23:61 | LL | async fn box_ref_Self(self: Box<&mut Self>, f: &u32) -> &u32 { | ^^^^ @@ -47,7 +47,7 @@ LL | async fn box_ref_Self(self: Box<&mut Self>, f: &u32) -> &u32 { = note: hidden type `impl std::future::Future` captures lifetime '_#15r error: lifetime may not live long enough - --> $DIR/ref-mut-self-async.rs:25:66 + --> $DIR/ref-mut-self-async.rs:23:66 | LL | async fn box_ref_Self(self: Box<&mut Self>, f: &u32) -> &u32 { | _____________________________________-____________________________^ @@ -59,7 +59,7 @@ LL | | } | |_____^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_` error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds - --> $DIR/ref-mut-self-async.rs:29:61 + --> $DIR/ref-mut-self-async.rs:27:61 | LL | async fn pin_ref_Self(self: Pin<&mut Self>, f: &u32) -> &u32 { | ^^^^ @@ -67,7 +67,7 @@ LL | async fn pin_ref_Self(self: Pin<&mut Self>, f: &u32) -> &u32 { = note: hidden type `impl std::future::Future` captures lifetime '_#15r error: lifetime may not live long enough - --> $DIR/ref-mut-self-async.rs:29:66 + --> $DIR/ref-mut-self-async.rs:27:66 | LL | async fn pin_ref_Self(self: Pin<&mut Self>, f: &u32) -> &u32 { | _____________________________________-____________________________^ @@ -79,7 +79,7 @@ LL | | } | |_____^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_` error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds - --> $DIR/ref-mut-self-async.rs:33:70 + --> $DIR/ref-mut-self-async.rs:31:70 | LL | async fn box_box_ref_Self(self: Box<Box<&mut Self>>, f: &u32) -> &u32 { | ^^^^ @@ -87,7 +87,7 @@ LL | async fn box_box_ref_Self(self: Box<Box<&mut Self>>, f: &u32) -> &u32 { = note: hidden type `impl std::future::Future` captures lifetime '_#15r error: lifetime may not live long enough - --> $DIR/ref-mut-self-async.rs:33:75 + --> $DIR/ref-mut-self-async.rs:31:75 | LL | async fn box_box_ref_Self(self: Box<Box<&mut Self>>, f: &u32) -> &u32 { | _____________________________________________-_____________________________^ @@ -99,7 +99,7 @@ LL | | } | |_____^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_` error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds - --> $DIR/ref-mut-self-async.rs:37:70 + --> $DIR/ref-mut-self-async.rs:35:70 | LL | async fn box_pin_ref_Self(self: Box<Pin<&mut Self>>, f: &u32) -> &u32 { | ^^^^ @@ -107,7 +107,7 @@ LL | async fn box_pin_ref_Self(self: Box<Pin<&mut Self>>, f: &u32) -> &u32 { = note: hidden type `impl std::future::Future` captures lifetime '_#15r error: lifetime may not live long enough - --> $DIR/ref-mut-self-async.rs:37:75 + --> $DIR/ref-mut-self-async.rs:35:75 | LL | async fn box_pin_ref_Self(self: Box<Pin<&mut Self>>, f: &u32) -> &u32 { | _____________________________________________-_____________________________^ diff --git a/src/test/ui/self/elision/ref-mut-self-async.rs b/src/test/ui/self/elision/ref-mut-self-async.rs index a6bd9d69316..2ca14800a75 100644 --- a/src/test/ui/self/elision/ref-mut-self-async.rs +++ b/src/test/ui/self/elision/ref-mut-self-async.rs @@ -1,7 +1,5 @@ // edition:2018 -#![feature(async_await)] - #![feature(arbitrary_self_types)] #![allow(non_snake_case)] diff --git a/src/test/ui/self/elision/ref-mut-self-async.stderr b/src/test/ui/self/elision/ref-mut-self-async.stderr index 805833f9472..39a1b30ca53 100644 --- a/src/test/ui/self/elision/ref-mut-self-async.stderr +++ b/src/test/ui/self/elision/ref-mut-self-async.stderr @@ -1,5 +1,5 @@ error[E0623]: lifetime mismatch - --> $DIR/ref-mut-self-async.rs:15:46 + --> $DIR/ref-mut-self-async.rs:13:46 | LL | async fn ref_self(&mut self, f: &u32) -> &u32 { | --------- ^^^^ @@ -8,7 +8,7 @@ LL | async fn ref_self(&mut self, f: &u32) -> &u32 { | this parameter and the return type are declared with different lifetimes... error[E0623]: lifetime mismatch - --> $DIR/ref-mut-self-async.rs:21:52 + --> $DIR/ref-mut-self-async.rs:19:52 | LL | async fn ref_Self(self: &mut Self, f: &u32) -> &u32 { | --------- ^^^^ @@ -17,7 +17,7 @@ LL | async fn ref_Self(self: &mut Self, f: &u32) -> &u32 { | this parameter and the return type are declared with different lifetimes... error[E0623]: lifetime mismatch - --> $DIR/ref-mut-self-async.rs:25:61 + --> $DIR/ref-mut-self-async.rs:23:61 | LL | async fn box_ref_Self(self: Box<&mut Self>, f: &u32) -> &u32 { | --------- ^^^^ @@ -26,7 +26,7 @@ LL | async fn box_ref_Self(self: Box<&mut Self>, f: &u32) -> &u32 { | this parameter and the return type are declared with different lifetimes... error[E0623]: lifetime mismatch - --> $DIR/ref-mut-self-async.rs:29:61 + --> $DIR/ref-mut-self-async.rs:27:61 | LL | async fn pin_ref_Self(self: Pin<&mut Self>, f: &u32) -> &u32 { | --------- ^^^^ @@ -35,7 +35,7 @@ LL | async fn pin_ref_Self(self: Pin<&mut Self>, f: &u32) -> &u32 { | this parameter and the return type are declared with different lifetimes... error[E0623]: lifetime mismatch - --> $DIR/ref-mut-self-async.rs:33:70 + --> $DIR/ref-mut-self-async.rs:31:70 | LL | async fn box_box_ref_Self(self: Box<Box<&mut Self>>, f: &u32) -> &u32 { | --------- ^^^^ @@ -44,7 +44,7 @@ LL | async fn box_box_ref_Self(self: Box<Box<&mut Self>>, f: &u32) -> &u32 { | this parameter and the return type are declared with different lifetimes... error[E0623]: lifetime mismatch - --> $DIR/ref-mut-self-async.rs:37:70 + --> $DIR/ref-mut-self-async.rs:35:70 | LL | async fn box_pin_ref_Self(self: Box<Pin<&mut Self>>, f: &u32) -> &u32 { | --------- ^^^^ diff --git a/src/test/ui/self/elision/ref-mut-struct-async.nll.stderr b/src/test/ui/self/elision/ref-mut-struct-async.nll.stderr index cee008de667..2905a022e5d 100644 --- a/src/test/ui/self/elision/ref-mut-struct-async.nll.stderr +++ b/src/test/ui/self/elision/ref-mut-struct-async.nll.stderr @@ -1,5 +1,5 @@ error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds - --> $DIR/ref-mut-struct-async.rs:15:56 + --> $DIR/ref-mut-struct-async.rs:13:56 | LL | async fn ref_Struct(self: &mut Struct, f: &u32) -> &u32 { | ^^^^ @@ -7,7 +7,7 @@ LL | async fn ref_Struct(self: &mut Struct, f: &u32) -> &u32 { = note: hidden type `impl std::future::Future` captures lifetime '_#15r error: lifetime may not live long enough - --> $DIR/ref-mut-struct-async.rs:15:61 + --> $DIR/ref-mut-struct-async.rs:13:61 | LL | async fn ref_Struct(self: &mut Struct, f: &u32) -> &u32 { | _______________________________-_____________________________^ @@ -19,7 +19,7 @@ LL | | } | |_____^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_` error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds - --> $DIR/ref-mut-struct-async.rs:19:65 + --> $DIR/ref-mut-struct-async.rs:17:65 | LL | async fn box_ref_Struct(self: Box<&mut Struct>, f: &u32) -> &u32 { | ^^^^ @@ -27,7 +27,7 @@ LL | async fn box_ref_Struct(self: Box<&mut Struct>, f: &u32) -> &u32 { = note: hidden type `impl std::future::Future` captures lifetime '_#15r error: lifetime may not live long enough - --> $DIR/ref-mut-struct-async.rs:19:70 + --> $DIR/ref-mut-struct-async.rs:17:70 | LL | async fn box_ref_Struct(self: Box<&mut Struct>, f: &u32) -> &u32 { | _______________________________________-______________________________^ @@ -39,7 +39,7 @@ LL | | } | |_____^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_` error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds - --> $DIR/ref-mut-struct-async.rs:23:65 + --> $DIR/ref-mut-struct-async.rs:21:65 | LL | async fn pin_ref_Struct(self: Pin<&mut Struct>, f: &u32) -> &u32 { | ^^^^ @@ -47,7 +47,7 @@ LL | async fn pin_ref_Struct(self: Pin<&mut Struct>, f: &u32) -> &u32 { = note: hidden type `impl std::future::Future` captures lifetime '_#15r error: lifetime may not live long enough - --> $DIR/ref-mut-struct-async.rs:23:70 + --> $DIR/ref-mut-struct-async.rs:21:70 | LL | async fn pin_ref_Struct(self: Pin<&mut Struct>, f: &u32) -> &u32 { | _______________________________________-______________________________^ @@ -59,7 +59,7 @@ LL | | } | |_____^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_` error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds - --> $DIR/ref-mut-struct-async.rs:27:74 + --> $DIR/ref-mut-struct-async.rs:25:74 | LL | async fn box_box_ref_Struct(self: Box<Box<&mut Struct>>, f: &u32) -> &u32 { | ^^^^ @@ -67,7 +67,7 @@ LL | async fn box_box_ref_Struct(self: Box<Box<&mut Struct>>, f: &u32) -> &u = note: hidden type `impl std::future::Future` captures lifetime '_#15r error: lifetime may not live long enough - --> $DIR/ref-mut-struct-async.rs:27:79 + --> $DIR/ref-mut-struct-async.rs:25:79 | LL | async fn box_box_ref_Struct(self: Box<Box<&mut Struct>>, f: &u32) -> &u32 { | _______________________________________________-_______________________________^ @@ -79,7 +79,7 @@ LL | | } | |_____^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_` error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds - --> $DIR/ref-mut-struct-async.rs:31:74 + --> $DIR/ref-mut-struct-async.rs:29:74 | LL | async fn box_pin_ref_Struct(self: Box<Pin<&mut Struct>>, f: &u32) -> &u32 { | ^^^^ @@ -87,7 +87,7 @@ LL | async fn box_pin_ref_Struct(self: Box<Pin<&mut Struct>>, f: &u32) -> &u = note: hidden type `impl std::future::Future` captures lifetime '_#15r error: lifetime may not live long enough - --> $DIR/ref-mut-struct-async.rs:31:79 + --> $DIR/ref-mut-struct-async.rs:29:79 | LL | async fn box_pin_ref_Struct(self: Box<Pin<&mut Struct>>, f: &u32) -> &u32 { | _______________________________________________-_______________________________^ diff --git a/src/test/ui/self/elision/ref-mut-struct-async.rs b/src/test/ui/self/elision/ref-mut-struct-async.rs index 7a89ef9596a..a671116de25 100644 --- a/src/test/ui/self/elision/ref-mut-struct-async.rs +++ b/src/test/ui/self/elision/ref-mut-struct-async.rs @@ -1,7 +1,5 @@ // edition:2018 -#![feature(async_await)] - #![feature(arbitrary_self_types)] #![allow(non_snake_case)] diff --git a/src/test/ui/self/elision/ref-mut-struct-async.stderr b/src/test/ui/self/elision/ref-mut-struct-async.stderr index 4c983872942..fe4a636ada6 100644 --- a/src/test/ui/self/elision/ref-mut-struct-async.stderr +++ b/src/test/ui/self/elision/ref-mut-struct-async.stderr @@ -1,5 +1,5 @@ error[E0623]: lifetime mismatch - --> $DIR/ref-mut-struct-async.rs:15:56 + --> $DIR/ref-mut-struct-async.rs:13:56 | LL | async fn ref_Struct(self: &mut Struct, f: &u32) -> &u32 { | ----------- ^^^^ @@ -8,7 +8,7 @@ LL | async fn ref_Struct(self: &mut Struct, f: &u32) -> &u32 { | this parameter and the return type are declared with different lifetimes... error[E0623]: lifetime mismatch - --> $DIR/ref-mut-struct-async.rs:19:65 + --> $DIR/ref-mut-struct-async.rs:17:65 | LL | async fn box_ref_Struct(self: Box<&mut Struct>, f: &u32) -> &u32 { | ----------- ^^^^ @@ -17,7 +17,7 @@ LL | async fn box_ref_Struct(self: Box<&mut Struct>, f: &u32) -> &u32 { | this parameter and the return type are declared with different lifetimes... error[E0623]: lifetime mismatch - --> $DIR/ref-mut-struct-async.rs:23:65 + --> $DIR/ref-mut-struct-async.rs:21:65 | LL | async fn pin_ref_Struct(self: Pin<&mut Struct>, f: &u32) -> &u32 { | ----------- ^^^^ @@ -26,7 +26,7 @@ LL | async fn pin_ref_Struct(self: Pin<&mut Struct>, f: &u32) -> &u32 { | this parameter and the return type are declared with different lifetimes... error[E0623]: lifetime mismatch - --> $DIR/ref-mut-struct-async.rs:27:74 + --> $DIR/ref-mut-struct-async.rs:25:74 | LL | async fn box_box_ref_Struct(self: Box<Box<&mut Struct>>, f: &u32) -> &u32 { | ----------- ^^^^ @@ -35,7 +35,7 @@ LL | async fn box_box_ref_Struct(self: Box<Box<&mut Struct>>, f: &u32) -> &u | this parameter and the return type are declared with different lifetimes... error[E0623]: lifetime mismatch - --> $DIR/ref-mut-struct-async.rs:31:74 + --> $DIR/ref-mut-struct-async.rs:29:74 | LL | async fn box_pin_ref_Struct(self: Box<Pin<&mut Struct>>, f: &u32) -> &u32 { | ----------- ^^^^ diff --git a/src/test/ui/self/elision/ref-self-async.nll.stderr b/src/test/ui/self/elision/ref-self-async.nll.stderr index c3c15485b22..0eee56654f7 100644 --- a/src/test/ui/self/elision/ref-self-async.nll.stderr +++ b/src/test/ui/self/elision/ref-self-async.nll.stderr @@ -1,5 +1,5 @@ error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds - --> $DIR/ref-self-async.rs:24:42 + --> $DIR/ref-self-async.rs:22:42 | LL | async fn ref_self(&self, f: &u32) -> &u32 { | ^^^^ @@ -7,7 +7,7 @@ LL | async fn ref_self(&self, f: &u32) -> &u32 { = note: hidden type `impl std::future::Future` captures lifetime '_#15r error: lifetime may not live long enough - --> $DIR/ref-self-async.rs:24:47 + --> $DIR/ref-self-async.rs:22:47 | LL | async fn ref_self(&self, f: &u32) -> &u32 { | _______________________-_______________________^ @@ -19,7 +19,7 @@ LL | | } | |_____^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_` error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds - --> $DIR/ref-self-async.rs:30:48 + --> $DIR/ref-self-async.rs:28:48 | LL | async fn ref_Self(self: &Self, f: &u32) -> &u32 { | ^^^^ @@ -27,7 +27,7 @@ LL | async fn ref_Self(self: &Self, f: &u32) -> &u32 { = note: hidden type `impl std::future::Future` captures lifetime '_#15r error: lifetime may not live long enough - --> $DIR/ref-self-async.rs:30:53 + --> $DIR/ref-self-async.rs:28:53 | LL | async fn ref_Self(self: &Self, f: &u32) -> &u32 { | _____________________________-_______________________^ @@ -39,7 +39,7 @@ LL | | } | |_____^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_` error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds - --> $DIR/ref-self-async.rs:34:57 + --> $DIR/ref-self-async.rs:32:57 | LL | async fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 { | ^^^^ @@ -47,7 +47,7 @@ LL | async fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 { = note: hidden type `impl std::future::Future` captures lifetime '_#15r error: lifetime may not live long enough - --> $DIR/ref-self-async.rs:34:62 + --> $DIR/ref-self-async.rs:32:62 | LL | async fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 { | _____________________________________-________________________^ @@ -59,7 +59,7 @@ LL | | } | |_____^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_` error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds - --> $DIR/ref-self-async.rs:38:57 + --> $DIR/ref-self-async.rs:36:57 | LL | async fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 { | ^^^^ @@ -67,7 +67,7 @@ LL | async fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 { = note: hidden type `impl std::future::Future` captures lifetime '_#15r error: lifetime may not live long enough - --> $DIR/ref-self-async.rs:38:62 + --> $DIR/ref-self-async.rs:36:62 | LL | async fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 { | _____________________________________-________________________^ @@ -79,7 +79,7 @@ LL | | } | |_____^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_` error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds - --> $DIR/ref-self-async.rs:42:66 + --> $DIR/ref-self-async.rs:40:66 | LL | async fn box_box_ref_Self(self: Box<Box<&Self>>, f: &u32) -> &u32 { | ^^^^ @@ -87,7 +87,7 @@ LL | async fn box_box_ref_Self(self: Box<Box<&Self>>, f: &u32) -> &u32 { = note: hidden type `impl std::future::Future` captures lifetime '_#15r error: lifetime may not live long enough - --> $DIR/ref-self-async.rs:42:71 + --> $DIR/ref-self-async.rs:40:71 | LL | async fn box_box_ref_Self(self: Box<Box<&Self>>, f: &u32) -> &u32 { | _____________________________________________-_________________________^ @@ -99,7 +99,7 @@ LL | | } | |_____^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_` error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds - --> $DIR/ref-self-async.rs:46:66 + --> $DIR/ref-self-async.rs:44:66 | LL | async fn box_pin_ref_Self(self: Box<Pin<&Self>>, f: &u32) -> &u32 { | ^^^^ @@ -107,7 +107,7 @@ LL | async fn box_pin_ref_Self(self: Box<Pin<&Self>>, f: &u32) -> &u32 { = note: hidden type `impl std::future::Future` captures lifetime '_#15r error: lifetime may not live long enough - --> $DIR/ref-self-async.rs:46:71 + --> $DIR/ref-self-async.rs:44:71 | LL | async fn box_pin_ref_Self(self: Box<Pin<&Self>>, f: &u32) -> &u32 { | _____________________________________________-_________________________^ @@ -119,7 +119,7 @@ LL | | } | |_____^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_` error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds - --> $DIR/ref-self-async.rs:50:69 + --> $DIR/ref-self-async.rs:48:69 | LL | async fn wrap_ref_Self_Self(self: Wrap<&Self, Self>, f: &u8) -> &u8 { | ^^^ @@ -127,7 +127,7 @@ LL | async fn wrap_ref_Self_Self(self: Wrap<&Self, Self>, f: &u8) -> &u8 { = note: hidden type `impl std::future::Future` captures lifetime '_#15r error: lifetime may not live long enough - --> $DIR/ref-self-async.rs:50:73 + --> $DIR/ref-self-async.rs:48:73 | LL | async fn wrap_ref_Self_Self(self: Wrap<&Self, Self>, f: &u8) -> &u8 { | ____________________________________________-____________________________^ diff --git a/src/test/ui/self/elision/ref-self-async.rs b/src/test/ui/self/elision/ref-self-async.rs index 5a5705d7e09..06f3b127b21 100644 --- a/src/test/ui/self/elision/ref-self-async.rs +++ b/src/test/ui/self/elision/ref-self-async.rs @@ -1,7 +1,5 @@ // edition:2018 -#![feature(async_await)] - #![feature(arbitrary_self_types)] #![allow(non_snake_case)] diff --git a/src/test/ui/self/elision/ref-self-async.stderr b/src/test/ui/self/elision/ref-self-async.stderr index eb796a07a86..2f9e2a01e34 100644 --- a/src/test/ui/self/elision/ref-self-async.stderr +++ b/src/test/ui/self/elision/ref-self-async.stderr @@ -1,5 +1,5 @@ error[E0623]: lifetime mismatch - --> $DIR/ref-self-async.rs:24:42 + --> $DIR/ref-self-async.rs:22:42 | LL | async fn ref_self(&self, f: &u32) -> &u32 { | ----- ^^^^ @@ -8,7 +8,7 @@ LL | async fn ref_self(&self, f: &u32) -> &u32 { | this parameter and the return type are declared with different lifetimes... error[E0623]: lifetime mismatch - --> $DIR/ref-self-async.rs:30:48 + --> $DIR/ref-self-async.rs:28:48 | LL | async fn ref_Self(self: &Self, f: &u32) -> &u32 { | ----- ^^^^ @@ -17,7 +17,7 @@ LL | async fn ref_Self(self: &Self, f: &u32) -> &u32 { | this parameter and the return type are declared with different lifetimes... error[E0623]: lifetime mismatch - --> $DIR/ref-self-async.rs:34:57 + --> $DIR/ref-self-async.rs:32:57 | LL | async fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 { | ----- ^^^^ @@ -26,7 +26,7 @@ LL | async fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 { | this parameter and the return type are declared with different lifetimes... error[E0623]: lifetime mismatch - --> $DIR/ref-self-async.rs:38:57 + --> $DIR/ref-self-async.rs:36:57 | LL | async fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 { | ----- ^^^^ @@ -35,7 +35,7 @@ LL | async fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 { | this parameter and the return type are declared with different lifetimes... error[E0623]: lifetime mismatch - --> $DIR/ref-self-async.rs:42:66 + --> $DIR/ref-self-async.rs:40:66 | LL | async fn box_box_ref_Self(self: Box<Box<&Self>>, f: &u32) -> &u32 { | ----- ^^^^ @@ -44,7 +44,7 @@ LL | async fn box_box_ref_Self(self: Box<Box<&Self>>, f: &u32) -> &u32 { | this parameter and the return type are declared with different lifetimes... error[E0623]: lifetime mismatch - --> $DIR/ref-self-async.rs:46:66 + --> $DIR/ref-self-async.rs:44:66 | LL | async fn box_pin_ref_Self(self: Box<Pin<&Self>>, f: &u32) -> &u32 { | ----- ^^^^ @@ -53,7 +53,7 @@ LL | async fn box_pin_ref_Self(self: Box<Pin<&Self>>, f: &u32) -> &u32 { | this parameter and the return type are declared with different lifetimes... error[E0623]: lifetime mismatch - --> $DIR/ref-self-async.rs:50:69 + --> $DIR/ref-self-async.rs:48:69 | LL | async fn wrap_ref_Self_Self(self: Wrap<&Self, Self>, f: &u8) -> &u8 { | ----- ^^^ diff --git a/src/test/ui/self/elision/ref-struct-async.nll.stderr b/src/test/ui/self/elision/ref-struct-async.nll.stderr index ff50f6825bc..8508e42264b 100644 --- a/src/test/ui/self/elision/ref-struct-async.nll.stderr +++ b/src/test/ui/self/elision/ref-struct-async.nll.stderr @@ -1,5 +1,5 @@ error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds - --> $DIR/ref-struct-async.rs:15:52 + --> $DIR/ref-struct-async.rs:13:52 | LL | async fn ref_Struct(self: &Struct, f: &u32) -> &u32 { | ^^^^ @@ -7,7 +7,7 @@ LL | async fn ref_Struct(self: &Struct, f: &u32) -> &u32 { = note: hidden type `impl std::future::Future` captures lifetime '_#15r error: lifetime may not live long enough - --> $DIR/ref-struct-async.rs:15:57 + --> $DIR/ref-struct-async.rs:13:57 | LL | async fn ref_Struct(self: &Struct, f: &u32) -> &u32 { | _______________________________-_________________________^ @@ -19,7 +19,7 @@ LL | | } | |_____^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_` error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds - --> $DIR/ref-struct-async.rs:19:61 + --> $DIR/ref-struct-async.rs:17:61 | LL | async fn box_ref_Struct(self: Box<&Struct>, f: &u32) -> &u32 { | ^^^^ @@ -27,7 +27,7 @@ LL | async fn box_ref_Struct(self: Box<&Struct>, f: &u32) -> &u32 { = note: hidden type `impl std::future::Future` captures lifetime '_#15r error: lifetime may not live long enough - --> $DIR/ref-struct-async.rs:19:66 + --> $DIR/ref-struct-async.rs:17:66 | LL | async fn box_ref_Struct(self: Box<&Struct>, f: &u32) -> &u32 { | _______________________________________-__________________________^ @@ -39,7 +39,7 @@ LL | | } | |_____^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_` error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds - --> $DIR/ref-struct-async.rs:23:61 + --> $DIR/ref-struct-async.rs:21:61 | LL | async fn pin_ref_Struct(self: Pin<&Struct>, f: &u32) -> &u32 { | ^^^^ @@ -47,7 +47,7 @@ LL | async fn pin_ref_Struct(self: Pin<&Struct>, f: &u32) -> &u32 { = note: hidden type `impl std::future::Future` captures lifetime '_#15r error: lifetime may not live long enough - --> $DIR/ref-struct-async.rs:23:66 + --> $DIR/ref-struct-async.rs:21:66 | LL | async fn pin_ref_Struct(self: Pin<&Struct>, f: &u32) -> &u32 { | _______________________________________-__________________________^ @@ -59,7 +59,7 @@ LL | | } | |_____^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_` error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds - --> $DIR/ref-struct-async.rs:27:70 + --> $DIR/ref-struct-async.rs:25:70 | LL | async fn box_box_ref_Struct(self: Box<Box<&Struct>>, f: &u32) -> &u32 { | ^^^^ @@ -67,7 +67,7 @@ LL | async fn box_box_ref_Struct(self: Box<Box<&Struct>>, f: &u32) -> &u32 { = note: hidden type `impl std::future::Future` captures lifetime '_#15r error: lifetime may not live long enough - --> $DIR/ref-struct-async.rs:27:75 + --> $DIR/ref-struct-async.rs:25:75 | LL | async fn box_box_ref_Struct(self: Box<Box<&Struct>>, f: &u32) -> &u32 { | _______________________________________________-___________________________^ @@ -79,7 +79,7 @@ LL | | } | |_____^ function was supposed to return data with lifetime `'_` but it is returning data with lifetime `'_` error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds - --> $DIR/ref-struct-async.rs:31:66 + --> $DIR/ref-struct-async.rs:29:66 | LL | async fn box_pin_Struct(self: Box<Pin<&Struct>>, f: &u32) -> &u32 { | ^^^^ @@ -87,7 +87,7 @@ LL | async fn box_pin_Struct(self: Box<Pin<&Struct>>, f: &u32) -> &u32 { = note: hidden type `impl std::future::Future` captures lifetime '_#15r error: lifetime may not live long enough - --> $DIR/ref-struct-async.rs:31:71 + --> $DIR/ref-struct-async.rs:29:71 | LL | async fn box_pin_Struct(self: Box<Pin<&Struct>>, f: &u32) -> &u32 { | ___________________________________________-___________________________^ diff --git a/src/test/ui/self/elision/ref-struct-async.rs b/src/test/ui/self/elision/ref-struct-async.rs index f0410bbee90..94eaeedc734 100644 --- a/src/test/ui/self/elision/ref-struct-async.rs +++ b/src/test/ui/self/elision/ref-struct-async.rs @@ -1,7 +1,5 @@ // edition:2018 -#![feature(async_await)] - #![feature(arbitrary_self_types)] #![allow(non_snake_case)] diff --git a/src/test/ui/self/elision/ref-struct-async.stderr b/src/test/ui/self/elision/ref-struct-async.stderr index 574b0fddc1e..222e27ebf0d 100644 --- a/src/test/ui/self/elision/ref-struct-async.stderr +++ b/src/test/ui/self/elision/ref-struct-async.stderr @@ -1,5 +1,5 @@ error[E0623]: lifetime mismatch - --> $DIR/ref-struct-async.rs:15:52 + --> $DIR/ref-struct-async.rs:13:52 | LL | async fn ref_Struct(self: &Struct, f: &u32) -> &u32 { | ------- ^^^^ @@ -8,7 +8,7 @@ LL | async fn ref_Struct(self: &Struct, f: &u32) -> &u32 { | this parameter and the return type are declared with different lifetimes... error[E0623]: lifetime mismatch - --> $DIR/ref-struct-async.rs:19:61 + --> $DIR/ref-struct-async.rs:17:61 | LL | async fn box_ref_Struct(self: Box<&Struct>, f: &u32) -> &u32 { | ------- ^^^^ @@ -17,7 +17,7 @@ LL | async fn box_ref_Struct(self: Box<&Struct>, f: &u32) -> &u32 { | this parameter and the return type are declared with different lifetimes... error[E0623]: lifetime mismatch - --> $DIR/ref-struct-async.rs:23:61 + --> $DIR/ref-struct-async.rs:21:61 | LL | async fn pin_ref_Struct(self: Pin<&Struct>, f: &u32) -> &u32 { | ------- ^^^^ @@ -26,7 +26,7 @@ LL | async fn pin_ref_Struct(self: Pin<&Struct>, f: &u32) -> &u32 { | this parameter and the return type are declared with different lifetimes... error[E0623]: lifetime mismatch - --> $DIR/ref-struct-async.rs:27:70 + --> $DIR/ref-struct-async.rs:25:70 | LL | async fn box_box_ref_Struct(self: Box<Box<&Struct>>, f: &u32) -> &u32 { | ------- ^^^^ @@ -35,7 +35,7 @@ LL | async fn box_box_ref_Struct(self: Box<Box<&Struct>>, f: &u32) -> &u32 { | this parameter and the return type are declared with different lifetimes... error[E0623]: lifetime mismatch - --> $DIR/ref-struct-async.rs:31:66 + --> $DIR/ref-struct-async.rs:29:66 | LL | async fn box_pin_Struct(self: Box<Pin<&Struct>>, f: &u32) -> &u32 { | ------- ^^^^ diff --git a/src/test/ui/self/elision/self-async.rs b/src/test/ui/self/elision/self-async.rs index d1dc050be0d..e1379bfaf2e 100644 --- a/src/test/ui/self/elision/self-async.rs +++ b/src/test/ui/self/elision/self-async.rs @@ -1,8 +1,6 @@ // check-pass // edition:2018 -#![feature(async_await)] - #![feature(arbitrary_self_types)] #![allow(non_snake_case)] diff --git a/src/test/ui/self/elision/struct-async.rs b/src/test/ui/self/elision/struct-async.rs index f7c8591ebd3..4a38a2164c8 100644 --- a/src/test/ui/self/elision/struct-async.rs +++ b/src/test/ui/self/elision/struct-async.rs @@ -1,8 +1,6 @@ // check-pass // edition:2018 -#![feature(async_await)] - #![feature(arbitrary_self_types)] #![allow(non_snake_case)] diff --git a/src/test/ui/self/self_lifetime-async.rs b/src/test/ui/self/self_lifetime-async.rs index ec4c3d15224..c3c6e56582d 100644 --- a/src/test/ui/self/self_lifetime-async.rs +++ b/src/test/ui/self/self_lifetime-async.rs @@ -1,8 +1,6 @@ // check-pass // edition:2018 -#![feature(async_await)] - struct Foo<'a>(&'a ()); impl<'a> Foo<'a> { async fn foo<'b>(self: &'b Foo<'a>) -> &() { self.0 } diff --git a/src/test/ui/specialization/issue-63716-parse-async.rs b/src/test/ui/specialization/issue-63716-parse-async.rs new file mode 100644 index 00000000000..c3764ffaab8 --- /dev/null +++ b/src/test/ui/specialization/issue-63716-parse-async.rs @@ -0,0 +1,14 @@ +// Ensure that `default async fn` will parse. +// See issue #63716 for details. + +// check-pass +// edition:2018 + +#![feature(specialization)] + +fn main() {} + +#[cfg(FALSE)] +impl Foo for Bar { + default async fn baz() {} +} diff --git a/src/test/ui/suggestions/dont-suggest-ref/duplicate-suggestions.rs b/src/test/ui/suggestions/dont-suggest-ref/duplicate-suggestions.rs index 1c1230346a5..bf0c1dc27ce 100644 --- a/src/test/ui/suggestions/dont-suggest-ref/duplicate-suggestions.rs +++ b/src/test/ui/suggestions/dont-suggest-ref/duplicate-suggestions.rs @@ -34,7 +34,7 @@ pub fn main() { let vs = &vx; let vsm = &mut vec![X(Y)]; - // -------- test for duplicate suggestions -------- + // test for duplicate suggestions let &(X(_t), X(_u)) = &(x.clone(), x.clone()); //~^ ERROR cannot move diff --git a/src/test/ui/suggestions/dont-suggest-ref/move-into-closure.rs b/src/test/ui/suggestions/dont-suggest-ref/move-into-closure.rs index 6e3879a4155..f1e043c30f2 100644 --- a/src/test/ui/suggestions/dont-suggest-ref/move-into-closure.rs +++ b/src/test/ui/suggestions/dont-suggest-ref/move-into-closure.rs @@ -22,7 +22,7 @@ fn move_into_fn() { let x = X(Y); - // -------- move into Fn -------- + // move into Fn consume_fn(|| { let X(_t) = x; @@ -89,7 +89,7 @@ fn move_into_fnmut() { let x = X(Y); - // -------- move into FnMut -------- + // move into FnMut consume_fnmut(|| { let X(_t) = x; diff --git a/src/test/ui/suggestions/dont-suggest-ref/simple.rs b/src/test/ui/suggestions/dont-suggest-ref/simple.rs index 69b303a6623..c53ac3d2cd6 100644 --- a/src/test/ui/suggestions/dont-suggest-ref/simple.rs +++ b/src/test/ui/suggestions/dont-suggest-ref/simple.rs @@ -33,7 +33,7 @@ pub fn main() { let vs = &vx; let vsm = &mut vec![X(Y)]; - // -------- move from Either/X place -------- + // move from Either/X place let X(_t) = *s; //~^ ERROR cannot move @@ -163,7 +163,7 @@ pub fn main() { // FIXME: should suggest removing `ref` too } - // -------- move from &Either/&X place -------- + // move from &Either/&X place let &X(_t) = s; //~^ ERROR cannot move @@ -251,7 +251,7 @@ pub fn main() { //~| HELP consider removing the `&mut` //~| SUGGESTION X(_t) - // -------- move from tuple of &Either/&X -------- + // move from tuple of &Either/&X // FIXME: These should have suggestions. @@ -283,7 +283,7 @@ pub fn main() { fn f4((&mut X(_t),): (&mut X,)) { } //~^ ERROR cannot move - // -------- move from &Either/&X value -------- + // move from &Either/&X value let &X(_t) = &x; //~^ ERROR cannot move diff --git a/src/test/ui/suggestions/opaque-type-error.rs b/src/test/ui/suggestions/opaque-type-error.rs new file mode 100644 index 00000000000..979bb60d48c --- /dev/null +++ b/src/test/ui/suggestions/opaque-type-error.rs @@ -0,0 +1,24 @@ +// edition:2018 +use core::future::Future; + +async fn base_thing() -> Result<(), ()> { + Ok(()) +} + +fn thing_one() -> impl Future<Output = Result<(), ()>> { + base_thing() +} + +fn thing_two() -> impl Future<Output = Result<(), ()>> { + base_thing() +} + +async fn thing() -> Result<(), ()> { + if true { + thing_one() + } else { + thing_two() //~ ERROR if and else have incompatible types + }.await +} + +fn main() {} diff --git a/src/test/ui/suggestions/opaque-type-error.stderr b/src/test/ui/suggestions/opaque-type-error.stderr new file mode 100644 index 00000000000..3c9ea05aece --- /dev/null +++ b/src/test/ui/suggestions/opaque-type-error.stderr @@ -0,0 +1,20 @@ +error[E0308]: if and else have incompatible types + --> $DIR/opaque-type-error.rs:20:9 + | +LL | / if true { +LL | | thing_one() + | | ----------- expected because of this +LL | | } else { +LL | | thing_two() + | | ^^^^^^^^^^^ expected opaque type, found a different opaque type +LL | | }.await + | |_____- if and else have incompatible types + | + = note: expected type `impl std::future::Future` (opaque type) + found type `impl std::future::Future` (opaque type) + = note: distinct uses of `impl Trait` result in different opaque types + = help: if both `Future`s have the same `Output` type, consider `.await`ing on both of them + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/traits/traits-conditional-model-fn.rs b/src/test/ui/traits/traits-conditional-model-fn.rs index afdfb96394b..ba88670032c 100644 --- a/src/test/ui/traits/traits-conditional-model-fn.rs +++ b/src/test/ui/traits/traits-conditional-model-fn.rs @@ -6,7 +6,6 @@ // aux-build:go_trait.rs - extern crate go_trait; use go_trait::{Go, GoMut, GoOnce, go, go_mut, go_once}; diff --git a/src/tools/build-manifest/Cargo.toml b/src/tools/build-manifest/Cargo.toml index 63b6399bb90..c364479d8db 100644 --- a/src/tools/build-manifest/Cargo.toml +++ b/src/tools/build-manifest/Cargo.toml @@ -5,5 +5,5 @@ authors = ["Alex Crichton <alex@alexcrichton.com>"] edition = "2018" [dependencies] -toml = "0.4" +toml = "0.5" serde = { version = "1.0", features = ["derive"] } diff --git a/src/tools/cargo b/src/tools/cargo -Subproject e853aa976543168fbb6bfcc983c35c3facca984 +Subproject 3f700ec43ce72305eb5315cfc710681f3469d4b diff --git a/src/tools/clippy b/src/tools/clippy -Subproject 72da1015d6d918fe1b29170acbf486d30e0c269 +Subproject 2bcb6155948e2f8b86db08152a5f54bd5af625e diff --git a/src/tools/error_index_generator/Cargo.toml b/src/tools/error_index_generator/Cargo.toml index 116be234f3c..992af261b83 100644 --- a/src/tools/error_index_generator/Cargo.toml +++ b/src/tools/error_index_generator/Cargo.toml @@ -3,10 +3,14 @@ authors = ["The Rust Project Developers"] name = "error_index_generator" version = "0.0.0" edition = "2018" +build = "build.rs" [dependencies] rustdoc = { path = "../../librustdoc" } +[build-dependencies] +walkdir = "2" + [[bin]] name = "error_index_generator" path = "main.rs" diff --git a/src/tools/error_index_generator/build.rs b/src/tools/error_index_generator/build.rs new file mode 100644 index 00000000000..2ac7351fce4 --- /dev/null +++ b/src/tools/error_index_generator/build.rs @@ -0,0 +1,64 @@ +use walkdir::WalkDir; +use std::path::PathBuf; +use std::{env, fs}; + +fn main() { + // The src directory (we are in src/tools/error_index_generator) + // Note that we could skip one of the .. but this ensures we at least loosely find the right + // directory. + let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap()); + let dest = out_dir.join("error_codes.rs"); + let mut idx = 0; + for entry in WalkDir::new("../../../src") { + let entry = entry.unwrap(); + if entry.file_name() == "error_codes.rs" { + println!("cargo:rerun-if-changed={}", entry.path().to_str().unwrap()); + let file = fs::read_to_string(entry.path()).unwrap() + .replace("use syntax::{register_diagnostics, register_long_diagnostics};", "") + .replace("use syntax::register_diagnostics;", "") + .replace("use syntax::register_long_diagnostics;", ""); + let contents = format!("(|| {{\n{}\n}})();", file); + + fs::write(&out_dir.join(&format!("error_{}.rs", idx)), &contents).unwrap(); + + idx += 1; + } + } + + let mut all = String::new(); + all.push_str("fn register_all() -> Vec<(&'static str, Option<&'static str>)> {\n"); + all.push_str("let mut long_codes: Vec<(&'static str, Option<&'static str>)> = Vec::new();\n"); + all.push_str(r#" +macro_rules! register_diagnostics { + ($($code:tt),*) => {{ + long_codes.extend([$( + stringify!($code), + )*].iter().cloned().map(|s| (s, None)).collect::<Vec<_>>()); + }}; + ($($code:tt),*,) => {{ + long_codes.extend([$( + stringify!($code), + )*].iter().cloned().map(|s| (s, None))); + }} +} + +macro_rules! register_long_diagnostics { + ($($code:tt: $description:tt),*) => { + {long_codes.extend([$( + (stringify!($code), Some(stringify!($description))), + )*].iter());} + }; + ($($code:tt: $description:tt),*,) => { + {long_codes.extend([$( + (stringify!($code), Some(stringify!($description))), + )*].iter());} + } +}"#); + for idx in 0..idx { + all.push_str(&format!(r#"include!(concat!(env!("OUT_DIR"), "/error_{}.rs"));"#, idx)); + } + all.push_str("\nlong_codes\n"); + all.push_str("}\n"); + + fs::write(&dest, all).unwrap(); +} diff --git a/src/tools/error_index_generator/main.rs b/src/tools/error_index_generator/main.rs index a9d1d9997f6..c4826a0c31d 100644 --- a/src/tools/error_index_generator/main.rs +++ b/src/tools/error_index_generator/main.rs @@ -2,22 +2,26 @@ extern crate env_logger; extern crate syntax; -extern crate serialize as rustc_serialize; use std::collections::BTreeMap; use std::env; use std::error::Error; -use std::fs::{self, read_dir, File}; +use std::fs::File; use std::io::Write; use std::path::Path; use std::path::PathBuf; use std::cell::RefCell; use syntax::edition::DEFAULT_EDITION; -use syntax::diagnostics::metadata::{get_metadata_dir, ErrorMetadataMap, ErrorMetadata}; use rustdoc::html::markdown::{Markdown, IdMap, ErrorCodes, Playground}; -use rustc_serialize::json; + +pub struct ErrorMetadata { + pub description: Option<String>, +} + +/// Mapping from error codes to metadata that can be (de)serialized. +pub type ErrorMetadataMap = BTreeMap<String, ErrorMetadata>; enum OutputFormat { HTML(HTMLFormatter), @@ -80,11 +84,7 @@ impl Formatter for HTMLFormatter { Some(_) => "error-described", None => "error-undescribed", }; - let use_desc = match info.use_site { - Some(_) => "error-used", - None => "error-unused", - }; - write!(output, "<div class=\"{} {}\">", desc_desc, use_desc)?; + write!(output, "<div class=\"{}\">", desc_desc)?; // Error title (with self-link). write!(output, @@ -199,25 +199,6 @@ impl Formatter for MarkdownFormatter { } } -/// Loads all the metadata files from `metadata_dir` into an in-memory map. -fn load_all_errors(metadata_dir: &Path) -> Result<ErrorMetadataMap, Box<dyn Error>> { - let mut all_errors = BTreeMap::new(); - - for entry in read_dir(metadata_dir)? { - let path = entry?.path(); - - let metadata_str = fs::read_to_string(&path)?; - - let some_errors: ErrorMetadataMap = json::decode(&metadata_str)?; - - for (err_code, info) in some_errors { - all_errors.insert(err_code, info); - } - } - - Ok(all_errors) -} - /// Output an HTML page for the errors in `err_map` to `output_path`. fn render_error_page<T: Formatter>(err_map: &ErrorMetadataMap, output_path: &Path, formatter: T) -> Result<(), Box<dyn Error>> { @@ -234,9 +215,13 @@ fn render_error_page<T: Formatter>(err_map: &ErrorMetadataMap, output_path: &Pat } fn main_with_result(format: OutputFormat, dst: &Path) -> Result<(), Box<dyn Error>> { - let build_arch = env::var("CFG_BUILD")?; - let metadata_dir = get_metadata_dir(&build_arch); - let err_map = load_all_errors(&metadata_dir)?; + let long_codes = register_all(); + let mut err_map = BTreeMap::new(); + for (code, desc) in long_codes { + err_map.insert(code.to_string(), ErrorMetadata { + description: desc.map(String::from), + }); + } match format { OutputFormat::Unknown(s) => panic!("Unknown output format: {}", s), OutputFormat::HTML(h) => render_error_page(&err_map, dst, h)?, @@ -272,3 +257,5 @@ fn main() { panic!("{}", e.description()); } } + +include!(concat!(env!("OUT_DIR"), "/error_codes.rs")); diff --git a/src/tools/miri b/src/tools/miri -Subproject 4f6f264c305ea30f1de90ad0c2f341e84d972b2 +Subproject d77fe6c63ca4c50b207a1161def90c9e57368d5 diff --git a/src/tools/publish_toolstate.py b/src/tools/publish_toolstate.py index b8dcba3afc3..648838d26ef 100755 --- a/src/tools/publish_toolstate.py +++ b/src/tools/publish_toolstate.py @@ -34,7 +34,7 @@ MAINTAINERS = { '@ryankurte @thejpster @therealprof' ), 'edition-guide': '@ehuss @Centril @steveklabnik', - 'rustc-guide': '@mark-i-m @spastorino' + 'rustc-guide': '@mark-i-m @spastorino @amanjeev' } REPOS = { diff --git a/src/tools/rustc-std-workspace-std/Cargo.toml b/src/tools/rustc-std-workspace-std/Cargo.toml new file mode 100644 index 00000000000..ce1644809db --- /dev/null +++ b/src/tools/rustc-std-workspace-std/Cargo.toml @@ -0,0 +1,15 @@ +[package] +name = "rustc-std-workspace-std" +version = "1.0.0" +authors = ["Alex Crichton <alex@alexcrichton.com>"] +license = 'MIT OR Apache-2.0' +description = """ +Hack for the compiler's own build system +""" +edition = "2018" + +[lib] +path = "lib.rs" + +[dependencies] +std = { path = "../../libstd" } diff --git a/src/tools/rustc-std-workspace-std/README.md b/src/tools/rustc-std-workspace-std/README.md new file mode 100644 index 00000000000..2228907f304 --- /dev/null +++ b/src/tools/rustc-std-workspace-std/README.md @@ -0,0 +1,3 @@ +# The `rustc-std-workspace-std` crate + +See documentation for the `rustc-std-workspace-core` crate. diff --git a/src/tools/rustc-std-workspace-std/lib.rs b/src/tools/rustc-std-workspace-std/lib.rs new file mode 100644 index 00000000000..f40d09cafbb --- /dev/null +++ b/src/tools/rustc-std-workspace-std/lib.rs @@ -0,0 +1 @@ +pub use std::*; diff --git a/src/tools/rustfmt b/src/tools/rustfmt -Subproject 0462008de87d2757e8ef1dc26f2c54dd789a59a +Subproject 9792ff05297c0a5c40942b346c9b0341b9e7c0e diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs index de54eb8f573..e07a07234c7 100644 --- a/src/tools/tidy/src/deps.rs +++ b/src/tools/tidy/src/deps.rs @@ -90,15 +90,18 @@ const WHITELIST: &[Crate<'_>] = &[ Crate("crossbeam-epoch"), Crate("crossbeam-utils"), Crate("datafrog"), + Crate("dlmalloc"), Crate("either"), Crate("ena"), Crate("env_logger"), Crate("filetime"), Crate("flate2"), + Crate("fortanix-sgx-abi"), Crate("fuchsia-zircon"), Crate("fuchsia-zircon-sys"), Crate("getopts"), Crate("getrandom"), + Crate("hashbrown"), Crate("humantime"), Crate("indexmap"), Crate("itertools"), diff --git a/src/tools/tidy/src/features.rs b/src/tools/tidy/src/features.rs index 88a469ef955..468e5600101 100644 --- a/src/tools/tidy/src/features.rs +++ b/src/tools/tidy/src/features.rs @@ -221,7 +221,14 @@ fn test_filen_gate(filen_underscore: &str, features: &mut Features) -> bool { } pub fn collect_lang_features(base_src_path: &Path, bad: &mut bool) -> Features { - let contents = t!(fs::read_to_string(base_src_path.join("libsyntax/feature_gate.rs"))); + let mut all = collect_lang_features_in(base_src_path, "active.rs", bad); + all.extend(collect_lang_features_in(base_src_path, "accepted.rs", bad)); + all.extend(collect_lang_features_in(base_src_path, "removed.rs", bad)); + all +} + +fn collect_lang_features_in(base: &Path, file: &str, bad: &mut bool) -> Features { + let contents = t!(fs::read_to_string(base.join("libsyntax/feature_gate").join(file))); // We allow rustc-internal features to omit a tracking issue. // To make tidy accept omitting a tracking issue, group the list of features |
