diff --git a/.azure-pipelines/steps/run.yml b/.azure-pipelines/steps/run.yml index a646b34fe7d02..49bac629e7285 100644 --- a/.azure-pipelines/steps/run.yml +++ b/.azure-pipelines/steps/run.yml @@ -74,8 +74,9 @@ steps: # images, etc. - bash: | set -e + source src/ci/shared.sh sudo apt-get install -y python3-setuptools - pip3 install awscli --upgrade --user + retry pip3 install awscli --upgrade --user echo "##vso[task.prependpath]$HOME/.local/bin" displayName: Install awscli (Linux) condition: and(succeeded(), eq(variables['Agent.OS'], 'Linux')) diff --git a/Cargo.lock b/Cargo.lock index 948074ce0fc48..40c8047e8a2ac 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1813,6 +1813,7 @@ name = "panic_unwind" version = "0.0.0" dependencies = [ "alloc 0.0.0", + "cfg-if 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", "compiler_builtins 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", "core 0.0.0", "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3338,6 +3339,7 @@ dependencies = [ "alloc 0.0.0", "backtrace 0.3.29 (registry+https://github.com/rust-lang/crates.io-index)", "cc 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", "compiler_builtins 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", "core 0.0.0", "dlmalloc 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -3936,6 +3938,7 @@ name = "unwind" version = "0.0.0" dependencies = [ "cc 1.0.35 (registry+https://github.com/rust-lang/crates.io-index)", + "cfg-if 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", "compiler_builtins 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", "core 0.0.0", "libc 0.2.54 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/README.md b/README.md index b522b161ecf93..15d09f4aada3b 100644 --- a/README.md +++ b/README.md @@ -130,9 +130,9 @@ build. MSVC builds of Rust additionally require an installation of Visual Studio 2017 (or later) so `rustc` can use its linker. The simplest way is to get the -[Visual Studio Build Tools] and check the “C++ build tools” workload. +[Visual Studio], check the “C++ build tools” and “Windows 10 SDK” workload. -[Visual Studio Build Tools]: https://visualstudio.microsoft.com/downloads/#build-tools-for-visual-studio-2019 +[Visual Studio]: https://visualstudio.microsoft.com/downloads/ (If you're installing cmake yourself, be careful that “C++ CMake tools for Windows” doesn't get included under “Individual components”.) diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index 2281a45e014a9..c665a618fbc36 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -1693,10 +1693,6 @@ mod __test { compiler: Compiler { host: a, stage: 1 }, target: b, }, - compile::Std { - compiler: Compiler { host: a, stage: 2 }, - target: b, - }, ] ); assert_eq!( diff --git a/src/bootstrap/doc.rs b/src/bootstrap/doc.rs index 2a3577a3d2044..6fd94285ff9c7 100644 --- a/src/bootstrap/doc.rs +++ b/src/bootstrap/doc.rs @@ -46,10 +46,11 @@ macro_rules! book { } fn run(self, builder: &Builder<'_>) { - builder.ensure(Rustbook { + builder.ensure(RustbookSrc { target: self.target, name: INTERNER.intern_str($book_name), version: $book_ver, + src: doc_src(builder), }) } } @@ -75,35 +76,8 @@ enum RustbookVersion { MdBook2, } -#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] -struct Rustbook { - target: Interned, - name: Interned, - version: RustbookVersion, -} - -impl Step for Rustbook { - type Output = (); - - // rustbook is never directly called, and only serves as a shim for the nomicon and the - // reference. - fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { - run.never() - } - - /// Invoke `rustbook` for `target` for the doc book `name`. - /// - /// This will not actually generate any documentation if the documentation has - /// already been generated. - fn run(self, builder: &Builder<'_>) { - let src = builder.src.join("src/doc"); - builder.ensure(RustbookSrc { - target: self.target, - name: self.name, - src: INTERNER.intern_path(src), - version: self.version, - }); - } +fn doc_src(builder: &Builder<'_>) -> Interned { + INTERNER.intern_path(builder.src.join("src/doc")) } #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] @@ -274,33 +248,37 @@ impl Step for TheBook { let name = self.name; // build book - builder.ensure(Rustbook { + builder.ensure(RustbookSrc { target, name: INTERNER.intern_string(name.to_string()), version: RustbookVersion::MdBook2, + src: doc_src(builder), }); // building older edition redirects let source_name = format!("{}/first-edition", name); - builder.ensure(Rustbook { + builder.ensure(RustbookSrc { target, name: INTERNER.intern_string(source_name), version: RustbookVersion::MdBook2, + src: doc_src(builder), }); let source_name = format!("{}/second-edition", name); - builder.ensure(Rustbook { + builder.ensure(RustbookSrc { target, name: INTERNER.intern_string(source_name), version: RustbookVersion::MdBook2, + src: doc_src(builder), }); let source_name = format!("{}/2018-edition", name); - builder.ensure(Rustbook { + builder.ensure(RustbookSrc { target, name: INTERNER.intern_string(source_name), version: RustbookVersion::MdBook2, + src: doc_src(builder), }); // build the version info page and CSS @@ -898,11 +876,6 @@ impl Step for UnstableBookGen { fn run(self, builder: &Builder<'_>) { let target = self.target; - builder.ensure(compile::Std { - compiler: builder.compiler(builder.top_stage, builder.config.build), - target, - }); - builder.info(&format!("Generating unstable book md files ({})", target)); let out = builder.md_doc_out(target).join("unstable-book"); builder.create_dir(&out); diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index b9d287abb0c7e..7f652c0d7a776 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -270,14 +270,9 @@ pub struct Build { #[derive(Debug)] struct Crate { name: Interned, - version: String, deps: HashSet>, id: String, path: PathBuf, - doc_step: String, - build_step: String, - test_step: String, - bench_step: String, } impl Crate { diff --git a/src/bootstrap/metadata.rs b/src/bootstrap/metadata.rs index 4a71fd2ce0bd2..b622b3682a777 100644 --- a/src/bootstrap/metadata.rs +++ b/src/bootstrap/metadata.rs @@ -20,7 +20,6 @@ struct Output { struct Package { id: String, name: String, - version: String, source: Option, manifest_path: String, } @@ -84,12 +83,7 @@ fn build_krate(features: &str, build: &mut Build, resolves: &mut Vec Mode { - Mode::ToolBootstrap - } - /// Whether this tool requires LLVM to run pub fn uses_llvm_tools(&self) -> bool { match self { @@ -345,6 +341,7 @@ bootstrap_tool!( Compiletest, "src/tools/compiletest", "compiletest", llvm_tools = true; BuildManifest, "src/tools/build-manifest", "build-manifest"; RemoteTestClient, "src/tools/remote-test-client", "remote-test-client"; + RemoteTestServer, "src/tools/remote-test-server", "remote-test-server"; RustInstaller, "src/tools/rust-installer", "fabricate", is_external_tool = true; RustdocTheme, "src/tools/rustdoc-themes", "rustdoc-themes"; ); @@ -397,40 +394,6 @@ impl Step for ErrorIndex { } } -#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] -pub struct RemoteTestServer { - pub compiler: Compiler, - pub target: Interned, -} - -impl Step for RemoteTestServer { - type Output = PathBuf; - - fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { - run.path("src/tools/remote-test-server") - } - - fn make_run(run: RunConfig<'_>) { - run.builder.ensure(RemoteTestServer { - compiler: run.builder.compiler(run.builder.top_stage, run.builder.config.build), - target: run.target, - }); - } - - fn run(self, builder: &Builder<'_>) -> PathBuf { - builder.ensure(ToolBuild { - compiler: self.compiler, - target: self.target, - tool: "remote-test-server", - mode: Mode::ToolStd, - path: "src/tools/remote-test-server", - is_optional_tool: false, - source_type: SourceType::InTree, - extra_features: Vec::new(), - }).expect("expected to build -- essential tool") - } -} - #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] pub struct Rustdoc { /// This should only ever be 0 or 2. @@ -659,23 +622,14 @@ impl<'a> Builder<'a> { pub fn tool_cmd(&self, tool: Tool) -> Command { let mut cmd = Command::new(self.tool_exe(tool)); let compiler = self.compiler(0, self.config.build); - self.prepare_tool_cmd(compiler, tool, &mut cmd); - cmd - } - - /// Prepares the `cmd` provided to be able to run the `compiler` provided. - /// - /// Notably this munges the dynamic library lookup path to point to the - /// right location to run `compiler`. - fn prepare_tool_cmd(&self, compiler: Compiler, tool: Tool, cmd: &mut Command) { let host = &compiler.host; + // Prepares the `cmd` provided to be able to run the `compiler` provided. + // + // Notably this munges the dynamic library lookup path to point to the + // right location to run `compiler`. let mut lib_paths: Vec = vec![ - if compiler.stage == 0 { - self.build.rustc_snapshot_libdir() - } else { - PathBuf::from(&self.sysroot_libdir(compiler, compiler.host)) - }, - self.cargo_out(compiler, tool.get_mode(), *host).join("deps"), + self.build.rustc_snapshot_libdir(), + self.cargo_out(compiler, Mode::ToolBootstrap, *host).join("deps"), ]; // On MSVC a tool may invoke a C compiler (e.g., compiletest in run-make @@ -696,6 +650,7 @@ impl<'a> Builder<'a> { } } - add_lib_path(lib_paths, cmd); + add_lib_path(lib_paths, &mut cmd); + cmd } } diff --git a/src/libcore/hint.rs b/src/libcore/hint.rs index 94eddbeda2b86..519212bb6cb4e 100644 --- a/src/libcore/hint.rs +++ b/src/libcore/hint.rs @@ -111,31 +111,31 @@ pub fn spin_loop() { /// This function is a no-op, and does not even read from `dummy`. #[inline] #[unstable(feature = "test", issue = "27812")] +#[allow(unreachable_code)] // this makes #[cfg] a bit easier below. pub fn black_box(dummy: T) -> T { - cfg_if! { - if #[cfg(any( - target_arch = "asmjs", - all( - target_arch = "wasm32", - target_os = "emscripten" - ) - ))] { - #[inline] - unsafe fn black_box_impl(d: T) -> T { - // these targets do not support inline assembly - let ret = crate::ptr::read_volatile(&d); - crate::mem::forget(d); - ret - } - } else { - #[inline] - unsafe fn black_box_impl(d: T) -> T { - // we need to "use" the argument in some way LLVM can't - // introspect. - asm!("" : : "r"(&d)); - d - } - } + // We need to "use" the argument in some way LLVM can't introspect, and on + // targets that support it we can typically leverage inline assembly to do + // this. LLVM's intepretation of inline assembly is that it's, well, a black + // box. This isn't the greatest implementation since it probably deoptimizes + // more than we want, but it's so far good enough. + #[cfg(not(any( + target_arch = "asmjs", + all( + target_arch = "wasm32", + target_os = "emscripten" + ) + )))] + unsafe { + asm!("" : : "r"(&dummy)); + return dummy; + } + + // Not all platforms support inline assembly so try to do something without + // inline assembly which in theory still hinders at least some optimizations + // on those targets. This is the "best effort" scenario. + unsafe { + let ret = crate::ptr::read_volatile(&dummy); + crate::mem::forget(dummy); + ret } - unsafe { black_box_impl(dummy) } } diff --git a/src/libcore/internal_macros.rs b/src/libcore/internal_macros.rs index dd5b92857be63..3acf2ec837d88 100644 --- a/src/libcore/internal_macros.rs +++ b/src/libcore/internal_macros.rs @@ -117,84 +117,3 @@ macro_rules! impl_fn_for_zst { )+ } } - -/// A macro for defining `#[cfg]` if-else statements. -/// -/// The macro provided by this crate, `cfg_if`, is similar to the `if/elif` C -/// preprocessor macro by allowing definition of a cascade of `#[cfg]` cases, -/// emitting the implementation which matches first. -/// -/// This allows you to conveniently provide a long list `#[cfg]`'d blocks of code -/// without having to rewrite each clause multiple times. -/// -/// # Example -/// -/// ``` -/// #[macro_use] -/// extern crate cfg_if; -/// -/// cfg_if! { -/// if #[cfg(unix)] { -/// fn foo() { /* unix specific functionality */ } -/// } else if #[cfg(target_pointer_width = "32")] { -/// fn foo() { /* non-unix, 32-bit functionality */ } -/// } else { -/// fn foo() { /* fallback implementation */ } -/// } -/// } -/// -/// # fn main() {} -/// ``` -macro_rules! cfg_if { - // match if/else chains with a final `else` - ($( - if #[cfg($($meta:meta),*)] { $($it:item)* } - ) else * else { - $($it2:item)* - }) => { - cfg_if! { - @__items - () ; - $( ( ($($meta),*) ($($it)*) ), )* - ( () ($($it2)*) ), - } - }; - - // match if/else chains lacking a final `else` - ( - if #[cfg($($i_met:meta),*)] { $($i_it:item)* } - $( - else if #[cfg($($e_met:meta),*)] { $($e_it:item)* } - )* - ) => { - cfg_if! { - @__items - () ; - ( ($($i_met),*) ($($i_it)*) ), - $( ( ($($e_met),*) ($($e_it)*) ), )* - ( () () ), - } - }; - - // Internal and recursive macro to emit all the items - // - // Collects all the negated cfgs in a list at the beginning and after the - // semicolon is all the remaining items - (@__items ($($not:meta,)*) ; ) => {}; - (@__items ($($not:meta,)*) ; ( ($($m:meta),*) ($($it:item)*) ), $($rest:tt)*) => { - // Emit all items within one block, applying an approprate #[cfg]. The - // #[cfg] will require all `$m` matchers specified and must also negate - // all previous matchers. - cfg_if! { @__apply cfg(all($($m,)* not(any($($not),*)))), $($it)* } - - // Recurse to emit all other items in `$rest`, and when we do so add all - // our `$m` matchers to the list of `$not` matchers as future emissions - // will have to negate everything we just matched as well. - cfg_if! { @__items ($($not,)* $($m,)*) ; $($rest)* } - }; - - // Internal macro to Apply a cfg attribute to a list of items - (@__apply $m:meta, $($it:item)*) => { - $(#[$m] $it)* - }; -} diff --git a/src/libcore/iter/traits/iterator.rs b/src/libcore/iter/traits/iterator.rs index d0fdd79473e67..30923c7414504 100644 --- a/src/libcore/iter/traits/iterator.rs +++ b/src/libcore/iter/traits/iterator.rs @@ -1495,13 +1495,13 @@ pub trait Iterator { let mut left: B = Default::default(); let mut right: B = Default::default(); - for x in self { + self.for_each(|x| { if f(&x) { left.extend(Some(x)) } else { right.extend(Some(x)) } - } + }); (left, right) } diff --git a/src/libcore/slice/mod.rs b/src/libcore/slice/mod.rs index 0e782bef39dd8..c9c73f4d66ee9 100644 --- a/src/libcore/slice/mod.rs +++ b/src/libcore/slice/mod.rs @@ -5420,7 +5420,7 @@ macro_rules! impl_marker_for { } impl_marker_for!(BytewiseEquality, - u8 i8 u16 i16 u32 i32 u64 i64 usize isize char bool); + u8 i8 u16 i16 u32 i32 u64 i64 u128 i128 usize isize char bool); #[doc(hidden)] unsafe impl<'a, T> TrustedRandomAccess for Iter<'a, T> { diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs index 8a128b0d5e7b2..34f2d8917ea47 100644 --- a/src/libcore/str/mod.rs +++ b/src/libcore/str/mod.rs @@ -4000,11 +4000,11 @@ impl str { /// # Examples /// /// ``` - /// let mut s = String::from("Grüße, Jürgen ❤"); + /// let mut s = String::from("GRÜßE, JÜRGEN ❤"); /// /// s.make_ascii_lowercase(); /// - /// assert_eq!("grüße, jürgen ❤", s); + /// assert_eq!("grÜße, jÜrgen ❤", s); /// ``` #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")] pub fn make_ascii_lowercase(&mut self) { diff --git a/src/libpanic_unwind/Cargo.toml b/src/libpanic_unwind/Cargo.toml index 1b3901ac11a96..47cd09f1b0510 100644 --- a/src/libpanic_unwind/Cargo.toml +++ b/src/libpanic_unwind/Cargo.toml @@ -16,3 +16,4 @@ core = { path = "../libcore" } libc = { version = "0.2", default-features = false } unwind = { path = "../libunwind" } compiler_builtins = "0.1.0" +cfg-if = "0.1.8" diff --git a/src/libpanic_unwind/lib.rs b/src/libpanic_unwind/lib.rs index 72ddafb420ce7..2bb9ce6ab220b 100644 --- a/src/libpanic_unwind/lib.rs +++ b/src/libpanic_unwind/lib.rs @@ -38,10 +38,7 @@ use core::mem; use core::raw; use core::panic::BoxMeUp; -#[macro_use] -mod macros; - -cfg_if! { +cfg_if::cfg_if! { if #[cfg(target_os = "emscripten")] { #[path = "emcc.rs"] mod imp; diff --git a/src/libpanic_unwind/macros.rs b/src/libpanic_unwind/macros.rs deleted file mode 100644 index 659e977285e35..0000000000000 --- a/src/libpanic_unwind/macros.rs +++ /dev/null @@ -1,35 +0,0 @@ -/// A macro for defining `#[cfg]` if-else statements. -/// -/// This is similar to the `if/elif` C preprocessor macro by allowing definition -/// of a cascade of `#[cfg]` cases, emitting the implementation which matches -/// first. -/// -/// This allows you to conveniently provide a long list `#[cfg]`'d blocks of code -/// without having to rewrite each clause multiple times. -macro_rules! cfg_if { - ($( - if #[cfg($($meta:meta),*)] { $($it:item)* } - ) else * else { - $($it2:item)* - }) => { - __cfg_if_items! { - () ; - $( ( ($($meta),*) ($($it)*) ), )* - ( () ($($it2)*) ), - } - } -} - -macro_rules! __cfg_if_items { - (($($not:meta,)*) ; ) => {}; - (($($not:meta,)*) ; ( ($($m:meta),*) ($($it:item)*) ), $($rest:tt)*) => { - __cfg_if_apply! { cfg(all(not(any($($not),*)), $($m,)*)), $($it)* } - __cfg_if_items! { ($($not,)* $($m,)*) ; $($rest)* } - } -} - -macro_rules! __cfg_if_apply { - ($m:meta, $($it:item)*) => { - $(#[$m] $it)* - } -} diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index 003fdd501a35a..86a606b5fd3d6 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -227,13 +227,17 @@ impl OutputType { } } +/// The type of diagnostics output to generate. #[derive(Clone, Copy, Debug, PartialEq, Eq)] pub enum ErrorOutputType { + /// Output meant for the consumption of humans. HumanReadable(HumanReadableErrorType), + /// Output that's consumed by other tools such as `rustfix` or the `RLS`. Json { - /// Render the json in a human readable way (with indents and newlines) + /// Render the JSON in a human readable way (with indents and newlines). pretty: bool, - /// The way the `rendered` field is created + /// The JSON output includes a `rendered` field that includes the rendered + /// human output. json_rendered: HumanReadableErrorType, }, } diff --git a/src/librustc_errors/diagnostic_builder.rs b/src/librustc_errors/diagnostic_builder.rs index 31f697a724a03..fc74e43ff5739 100644 --- a/src/librustc_errors/diagnostic_builder.rs +++ b/src/librustc_errors/diagnostic_builder.rs @@ -348,7 +348,7 @@ impl<'a> DiagnosticBuilder<'a> { /// Convenience function for internal use, clients should use one of the /// struct_* methods on Handler. - pub fn new_with_code(handler: &'a Handler, + crate fn new_with_code(handler: &'a Handler, level: Level, code: Option, message: &str) diff --git a/src/librustc_errors/emitter.rs b/src/librustc_errors/emitter.rs index 3bf477efe35f9..fca8298409a61 100644 --- a/src/librustc_errors/emitter.rs +++ b/src/librustc_errors/emitter.rs @@ -1,3 +1,12 @@ +//! The current rustc diagnostics emitter. +//! +//! An `Emitter` takes care of generating the output from a `DiagnosticBuilder` struct. +//! +//! There are various `Emitter` implementations that generate different output formats such as +//! JSON and human readable output. +//! +//! The output types are defined in `librustc::session::config::ErrorOutputType`. + use Destination::*; use syntax_pos::{SourceFile, Span, MultiSpan}; diff --git a/src/librustc_errors/lib.rs b/src/librustc_errors/lib.rs index cc3180c783bdf..6ec1b90cd91cd 100644 --- a/src/librustc_errors/lib.rs +++ b/src/librustc_errors/lib.rs @@ -1,5 +1,10 @@ +//! Diagnostics creation and emission for `rustc`. +//! +//! This module contains the code for creating and emitting diagnostics. + #![doc(html_root_url = "https://doc.rust-lang.org/nightly/")] +#![feature(crate_visibility_modifier)] #![allow(unused_attributes)] #![cfg_attr(unix, feature(libc))] #![feature(nll)] diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs index 991bebc647d0f..7ffba41e2569a 100644 --- a/src/librustc_metadata/creader.rs +++ b/src/librustc_metadata/creader.rs @@ -614,7 +614,7 @@ impl<'a> CrateLoader<'a> { match decl { ProcMacro::CustomDerive { trait_name, attributes, client } => { let attrs = attributes.iter().cloned().map(Symbol::intern).collect::>(); - (trait_name, SyntaxExtension::ProcMacroDerive( + (trait_name, SyntaxExtension::Derive( Box::new(ProcMacroDerive { client, attrs: attrs.clone(), @@ -624,13 +624,13 @@ impl<'a> CrateLoader<'a> { )) } ProcMacro::Attr { name, client } => { - (name, SyntaxExtension::AttrProcMacro( + (name, SyntaxExtension::Attr( Box::new(AttrProcMacro { client }), root.edition, )) } ProcMacro::Bang { name, client } => { - (name, SyntaxExtension::ProcMacro { + (name, SyntaxExtension::Bang { expander: Box::new(BangProcMacro { client }), allow_internal_unstable: None, edition: root.edition, diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs index db452bb4ac7bc..35faa1df82b84 100644 --- a/src/librustc_metadata/cstore_impl.rs +++ b/src/librustc_metadata/cstore_impl.rs @@ -430,7 +430,7 @@ impl cstore::CStore { use syntax_ext::proc_macro_impl::BangProcMacro; let client = proc_macro::bridge::client::Client::expand1(proc_macro::quote); - let ext = SyntaxExtension::ProcMacro { + let ext = SyntaxExtension::Bang { expander: Box::new(BangProcMacro { client }), allow_internal_unstable: Some(vec![sym::proc_macro_def_site].into()), edition: data.root.edition, diff --git a/src/librustc_plugin/registry.rs b/src/librustc_plugin/registry.rs index 2ed6f868fa1ee..dd5e42684c427 100644 --- a/src/librustc_plugin/registry.rs +++ b/src/librustc_plugin/registry.rs @@ -4,8 +4,9 @@ use rustc::lint::{EarlyLintPassObject, LateLintPassObject, LintId, Lint}; use rustc::session::Session; use rustc::util::nodemap::FxHashMap; -use syntax::ext::base::{SyntaxExtension, NamedSyntaxExtension, NormalTT, IdentTT}; +use syntax::ext::base::{SyntaxExtension, NamedSyntaxExtension}; use syntax::ext::base::MacroExpanderFn; +use syntax::ext::hygiene::Transparency; use syntax::symbol::{Symbol, sym}; use syntax::ast; use syntax::feature_gate::AttributeType; @@ -84,47 +85,26 @@ impl<'a> Registry<'a> { /// Register a syntax extension of any kind. /// /// This is the most general hook into `libsyntax`'s expansion behavior. - pub fn register_syntax_extension(&mut self, name: ast::Name, extension: SyntaxExtension) { + pub fn register_syntax_extension(&mut self, name: ast::Name, mut extension: SyntaxExtension) { if name == sym::macro_rules { panic!("user-defined macros may not be named `macro_rules`"); } - self.syntax_exts.push((name, match extension { - NormalTT { - expander, - def_info: _, - allow_internal_unstable, - allow_internal_unsafe, - local_inner_macros, - unstable_feature, - edition, - } => { - let nid = ast::CRATE_NODE_ID; - NormalTT { - expander, - def_info: Some((nid, self.krate_span)), - allow_internal_unstable, - allow_internal_unsafe, - local_inner_macros, - unstable_feature, - edition, - } - } - IdentTT { expander, span: _, allow_internal_unstable } => { - IdentTT { expander, span: Some(self.krate_span), allow_internal_unstable } - } - _ => extension, - })); + if let SyntaxExtension::LegacyBang { def_info: ref mut def_info @ None, .. } = extension { + *def_info = Some((ast::CRATE_NODE_ID, self.krate_span)); + } + self.syntax_exts.push((name, extension)); } /// Register a macro of the usual kind. /// /// This is a convenience wrapper for `register_syntax_extension`. - /// It builds for you a `NormalTT` that calls `expander`, + /// It builds for you a `SyntaxExtension::LegacyBang` that calls `expander`, /// and also takes care of interning the macro's name. pub fn register_macro(&mut self, name: &str, expander: MacroExpanderFn) { - self.register_syntax_extension(Symbol::intern(name), NormalTT { + self.register_syntax_extension(Symbol::intern(name), SyntaxExtension::LegacyBang { expander: Box::new(expander), def_info: None, + transparency: Transparency::SemiTransparent, allow_internal_unstable: None, allow_internal_unsafe: false, local_inner_macros: false, diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs index 08ab5b8532522..2369bddf4f75f 100644 --- a/src/librustc_resolve/macros.rs +++ b/src/librustc_resolve/macros.rs @@ -242,8 +242,7 @@ impl<'a> base::Resolver for Resolver<'a> { fn check_unused_macros(&self) { for did in self.unused_macros.iter() { let id_span = match *self.macro_map[did] { - SyntaxExtension::NormalTT { def_info, .. } | - SyntaxExtension::DeclMacro { def_info, .. } => def_info, + SyntaxExtension::LegacyBang { def_info, .. } => def_info, _ => None, }; if let Some((id, span)) = id_span { @@ -587,7 +586,7 @@ impl<'a> Resolver<'a> { match self.resolve_macro_to_res(derive, MacroKind::Derive, &parent_scope, true, force) { Ok((_, ext)) => { - if let SyntaxExtension::ProcMacroDerive(_, helpers, _) = &*ext { + if let SyntaxExtension::Derive(_, helpers, _) = &*ext { if helpers.contains(&ident.name) { let binding = (Res::NonMacroAttr(NonMacroAttrKind::DeriveHelper), diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 63d9f0920cc7b..5a46c9d440b5d 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -2155,6 +2155,17 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { result_ty } + /// Returns the `DefId` of the constant parameter that the provided expression is a path to. + pub fn const_param_def_id(&self, expr: &hir::Expr) -> Option { + match &expr.node { + ExprKind::Path(hir::QPath::Resolved(_, path)) => match path.res { + Res::Def(DefKind::ConstParam, did) => Some(did), + _ => None, + }, + _ => None, + } + } + pub fn ast_const_to_const( &self, ast_const: &hir::AnonConst, @@ -2185,19 +2196,17 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { } } - if let ExprKind::Path(ref qpath) = expr.node { - if let hir::QPath::Resolved(_, ref path) = qpath { - if let Res::Def(DefKind::ConstParam, def_id) = path.res { - let node_id = tcx.hir().as_local_node_id(def_id).unwrap(); - let item_id = tcx.hir().get_parent_node(node_id); - let item_def_id = tcx.hir().local_def_id(item_id); - let generics = tcx.generics_of(item_def_id); - let index = generics.param_def_id_to_index[&tcx.hir().local_def_id(node_id)]; - let name = tcx.hir().name(node_id).as_interned_str(); - const_.val = ConstValue::Param(ty::ParamConst::new(index, name)); - } - } - }; + if let Some(def_id) = self.const_param_def_id(expr) { + // Find the name and index of the const parameter by indexing the generics of the + // parent item and construct a `ParamConst`. + let node_id = tcx.hir().as_local_node_id(def_id).unwrap(); + let item_id = tcx.hir().get_parent_node(node_id); + let item_def_id = tcx.hir().local_def_id(item_id); + let generics = tcx.generics_of(item_def_id); + let index = generics.param_def_id_to_index[&tcx.hir().local_def_id(node_id)]; + let name = tcx.hir().name(node_id).as_interned_str(); + const_.val = ConstValue::Param(ty::ParamConst::new(index, name)); + } tcx.mk_const(const_) } diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 0b558a20ed47e..209609ba3b8e0 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -2460,6 +2460,11 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { ty } + /// Returns the `DefId` of the constant parameter that the provided expression is a path to. + pub fn const_param_def_id(&self, hir_c: &hir::AnonConst) -> Option { + AstConv::const_param_def_id(self, &self.tcx.hir().body(hir_c.body).value) + } + pub fn to_const(&self, ast_c: &hir::AnonConst, ty: Ty<'tcx>) -> &'tcx ty::Const<'tcx> { AstConv::ast_const_to_const(self, ast_c, ty) } @@ -4435,19 +4440,24 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } ExprKind::Repeat(ref element, ref count) => { let count_def_id = tcx.hir().local_def_id_from_hir_id(count.hir_id); - let param_env = ty::ParamEnv::empty(); - let substs = InternalSubsts::identity_for_item(tcx.global_tcx(), count_def_id); - let instance = ty::Instance::resolve( - tcx.global_tcx(), - param_env, - count_def_id, - substs, - ).unwrap(); - let global_id = GlobalId { - instance, - promoted: None + let count = if self.const_param_def_id(count).is_some() { + Ok(self.to_const(count, self.tcx.type_of(count_def_id))) + } else { + let param_env = ty::ParamEnv::empty(); + let substs = InternalSubsts::identity_for_item(tcx.global_tcx(), count_def_id); + let instance = ty::Instance::resolve( + tcx.global_tcx(), + param_env, + count_def_id, + substs, + ).unwrap(); + let global_id = GlobalId { + instance, + promoted: None + }; + + tcx.const_eval(param_env.and(global_id)) }; - let count = tcx.const_eval(param_env.and(global_id)); let uty = match expected { ExpectHasType(uty) => { diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index 15108a7dbb91c..5a5540e7e3855 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -471,7 +471,7 @@ fn build_macro(cx: &DocContext<'_>, did: DefId, name: ast::Name) -> clean::ItemE } LoadedMacro::ProcMacro(ext) => { let helpers = match &*ext { - &SyntaxExtension::ProcMacroDerive(_, ref syms, ..) => { syms.clean(cx) } + &SyntaxExtension::Derive(_, ref syms, ..) => { syms.clean(cx) } _ => Vec::new(), }; diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 860ea18a58ad0..7fbfc3e1fc0f4 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -433,7 +433,7 @@ fn macro_resolve(cx: &DocContext<'_>, path_str: &str) -> Option { if let Res::Def(DefKind::Macro(MacroKind::ProcMacroStub), _) = res { // skip proc-macro stubs, they'll cause `get_macro` to crash } else { - if let SyntaxExtension::DeclMacro { .. } = *resolver.get_macro(res) { + if let SyntaxExtension::LegacyBang { .. } = *resolver.get_macro(res) { return Some(res.map_id(|_| panic!("unexpected id"))); } } diff --git a/src/libstd/Cargo.toml b/src/libstd/Cargo.toml index 30e23f1007f20..a170dae2b08ca 100644 --- a/src/libstd/Cargo.toml +++ b/src/libstd/Cargo.toml @@ -15,6 +15,7 @@ crate-type = ["dylib", "rlib"] [dependencies] alloc = { path = "../liballoc" } +cfg-if = "0.1.8" panic_unwind = { path = "../libpanic_unwind", optional = true } panic_abort = { path = "../libpanic_abort" } core = { path = "../libcore" } diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index a3356e6be2c3f..e0ffc9ba92f11 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -336,6 +336,12 @@ extern crate libc; #[allow(unused_extern_crates)] extern crate unwind; +// Only needed for now for the `std_detect` module until that crate changes to +// use `cfg_if::cfg_if!` +#[macro_use] +#[cfg(not(test))] +extern crate cfg_if; + // During testing, this crate is not actually the "real" std library, but rather // it links to the real std library, which was compiled from this same source // code. So any lang items std defines are conditionally excluded (or else they diff --git a/src/libstd/macros.rs b/src/libstd/macros.rs index ef7179f0b6f90..92b9a16f3e316 100644 --- a/src/libstd/macros.rs +++ b/src/libstd/macros.rs @@ -896,39 +896,3 @@ mod builtin { ($cond:expr, $($arg:tt)+) => ({ /* compiler built-in */ }); } } - -/// Defines `#[cfg]` if-else statements. -/// -/// This is similar to the `if/elif` C preprocessor macro by allowing definition -/// of a cascade of `#[cfg]` cases, emitting the implementation which matches -/// first. -/// -/// This allows you to conveniently provide a long list `#[cfg]`'d blocks of code -/// without having to rewrite each clause multiple times. -macro_rules! cfg_if { - ($( - if #[cfg($($meta:meta),*)] { $($it:item)* } - ) else * else { - $($it2:item)* - }) => { - __cfg_if_items! { - () ; - $( ( ($($meta),*) ($($it)*) ), )* - ( () ($($it2)*) ), - } - } -} - -macro_rules! __cfg_if_items { - (($($not:meta,)*) ; ) => {}; - (($($not:meta,)*) ; ( ($($m:meta),*) ($($it:item)*) ), $($rest:tt)*) => { - __cfg_if_apply! { cfg(all(not(any($($not),*)), $($m,)*)), $($it)* } - __cfg_if_items! { ($($not,)* $($m,)*) ; $($rest)* } - } -} - -macro_rules! __cfg_if_apply { - ($m:meta, $($it:item)*) => { - $(#[$m] $it)* - } -} diff --git a/src/libstd/os/mod.rs b/src/libstd/os/mod.rs index 44cbc180b8b01..94e8b7805cf93 100644 --- a/src/libstd/os/mod.rs +++ b/src/libstd/os/mod.rs @@ -3,7 +3,7 @@ #![stable(feature = "os", since = "1.0.0")] #![allow(missing_docs, nonstandard_style, missing_debug_implementations)] -cfg_if! { +cfg_if::cfg_if! { if #[cfg(rustdoc)] { // When documenting libstd we want to show unix/windows/linux modules as diff --git a/src/libstd/sys/mod.rs b/src/libstd/sys/mod.rs index 3f3cedc53b729..21360e2e0f028 100644 --- a/src/libstd/sys/mod.rs +++ b/src/libstd/sys/mod.rs @@ -22,7 +22,7 @@ #![allow(missing_debug_implementations)] -cfg_if! { +cfg_if::cfg_if! { if #[cfg(unix)] { mod unix; pub use self::unix::*; @@ -54,7 +54,7 @@ cfg_if! { // Windows when we're compiling for Linux. #[cfg(rustdoc)] -cfg_if! { +cfg_if::cfg_if! { if #[cfg(any(unix, target_os = "redox"))] { // On unix we'll document what's already available #[stable(feature = "rust1", since = "1.0.0")] @@ -77,7 +77,7 @@ cfg_if! { } #[cfg(rustdoc)] -cfg_if! { +cfg_if::cfg_if! { if #[cfg(windows)] { // On windows we'll just be documenting what's already available #[allow(missing_docs)] diff --git a/src/libstd/sys/wasm/mod.rs b/src/libstd/sys/wasm/mod.rs index 9ea8bd1653851..7d157709eb6bf 100644 --- a/src/libstd/sys/wasm/mod.rs +++ b/src/libstd/sys/wasm/mod.rs @@ -40,7 +40,7 @@ pub mod stdio; pub use crate::sys_common::os_str_bytes as os_str; -cfg_if! { +cfg_if::cfg_if! { if #[cfg(target_feature = "atomics")] { #[path = "condvar_atomics.rs"] pub mod condvar; diff --git a/src/libstd/sys/wasm/thread.rs b/src/libstd/sys/wasm/thread.rs index 1dc786cd5d7b6..61b4003cd3d14 100644 --- a/src/libstd/sys/wasm/thread.rs +++ b/src/libstd/sys/wasm/thread.rs @@ -59,7 +59,7 @@ pub mod guard { pub unsafe fn init() -> Option { None } } -cfg_if! { +cfg_if::cfg_if! { if #[cfg(all(target_feature = "atomics", feature = "wasm-bindgen-threads"))] { #[link(wasm_import_module = "__wbindgen_thread_xform__")] extern { diff --git a/src/libstd/sys_common/mod.rs b/src/libstd/sys_common/mod.rs index c4daedefd8e6d..13a59f66c5c2f 100644 --- a/src/libstd/sys_common/mod.rs +++ b/src/libstd/sys_common/mod.rs @@ -65,7 +65,7 @@ pub mod bytestring; pub mod process; pub mod fs; -cfg_if! { +cfg_if::cfg_if! { if #[cfg(any(target_os = "cloudabi", target_os = "l4re", target_os = "redox", diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index 61c736662c71e..38b7dee40c447 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -1,6 +1,4 @@ -pub use SyntaxExtension::*; - -use crate::ast::{self, Attribute, Name, PatKind, MetaItem}; +use crate::ast::{self, Attribute, Name, PatKind}; use crate::attr::HasAttrs; use crate::source_map::{SourceMap, Spanned, respan}; use crate::edition::Edition; @@ -137,29 +135,6 @@ impl Annotatable { } } -// A more flexible ItemDecorator. -pub trait MultiItemDecorator { - fn expand(&self, - ecx: &mut ExtCtxt<'_>, - sp: Span, - meta_item: &ast::MetaItem, - item: &Annotatable, - push: &mut dyn FnMut(Annotatable)); -} - -impl MultiItemDecorator for F - where F : Fn(&mut ExtCtxt<'_>, Span, &ast::MetaItem, &Annotatable, &mut dyn FnMut(Annotatable)) -{ - fn expand(&self, - ecx: &mut ExtCtxt<'_>, - sp: Span, - meta_item: &ast::MetaItem, - item: &Annotatable, - push: &mut dyn FnMut(Annotatable)) { - (*self)(ecx, sp, meta_item, item, push) - } -} - // `meta_item` is the annotation, and `item` is the item being modified. // FIXME Decorators should follow the same pattern too. pub trait MultiItemModifier { @@ -288,34 +263,6 @@ impl TTMacroExpander for F } } -pub trait IdentMacroExpander { - fn expand<'cx>(&self, - cx: &'cx mut ExtCtxt<'_>, - sp: Span, - ident: ast::Ident, - token_tree: Vec) - -> Box; -} - -pub type IdentMacroExpanderFn = - for<'cx> fn(&'cx mut ExtCtxt<'_>, Span, ast::Ident, Vec) - -> Box; - -impl IdentMacroExpander for F - where F : for<'cx> Fn(&'cx mut ExtCtxt<'_>, Span, ast::Ident, - Vec) -> Box -{ - fn expand<'cx>(&self, - cx: &'cx mut ExtCtxt<'_>, - sp: Span, - ident: ast::Ident, - token_tree: Vec) - -> Box - { - (*self)(cx, sp, ident, token_tree) - } -} - // Use a macro because forwarding to a simple function has type system issues macro_rules! make_stmts_default { ($me:expr) => { @@ -570,9 +517,6 @@ impl MacResult for DummyResult { } } -pub type BuiltinDeriveFn = - for<'cx> fn(&'cx mut ExtCtxt<'_>, Span, &MetaItem, &Annotatable, &mut dyn FnMut(Annotatable)); - /// Represents different kinds of macro invocations that can be resolved. #[derive(Clone, Copy, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] pub enum MacroKind { @@ -606,129 +550,116 @@ impl MacroKind { /// An enum representing the different kinds of syntax extensions. pub enum SyntaxExtension { - /// A trivial "extension" that does nothing, only keeps the attribute and marks it as known. - NonMacroAttr { mark_used: bool }, - - /// A syntax extension that is attached to an item and creates new items - /// based upon it. - /// - /// `#[derive(...)]` is a `MultiItemDecorator`. - /// - /// Prefer ProcMacro or MultiModifier since they are more flexible. - MultiDecorator(Box), - - /// A syntax extension that is attached to an item and modifies it - /// in-place. Also allows decoration, i.e., creating new items. - MultiModifier(Box), - - /// A function-like procedural macro. TokenStream -> TokenStream. - ProcMacro { + /// A token-based function-like macro. + Bang { + /// An expander with signature TokenStream -> TokenStream. expander: Box, - /// Whitelist of unstable features that are treated as stable inside this macro + /// Whitelist of unstable features that are treated as stable inside this macro. allow_internal_unstable: Option>, + /// Edition of the crate in which this macro is defined. edition: Edition, }, - /// An attribute-like procedural macro. TokenStream, TokenStream -> TokenStream. - /// The first TokenSteam is the attribute, the second is the annotated item. - /// Allows modification of the input items and adding new items, similar to - /// MultiModifier, but uses TokenStreams, rather than AST nodes. - AttrProcMacro(Box, Edition), - - /// A normal, function-like syntax extension. - /// - /// `bytes!` is a `NormalTT`. - NormalTT { + /// An AST-based function-like macro. + LegacyBang { + /// An expander with signature TokenStream -> AST. expander: Box, + /// Some info about the macro's definition point. def_info: Option<(ast::NodeId, Span)>, - /// Whether the contents of the macro can - /// directly use `#[unstable]` things. - /// - /// Only allows things that require a feature gate in the given whitelist + /// Hygienic properties of identifiers produced by this macro. + transparency: Transparency, + /// Whitelist of unstable features that are treated as stable inside this macro. allow_internal_unstable: Option>, - /// Whether the contents of the macro can use `unsafe` - /// without triggering the `unsafe_code` lint. + /// Suppresses the `unsafe_code` lint for code produced by this macro. allow_internal_unsafe: bool, - /// Enables the macro helper hack (`ident!(...)` -> `$crate::ident!(...)`) - /// for a given macro. + /// Enables the macro helper hack (`ident!(...)` -> `$crate::ident!(...)`) for this macro. local_inner_macros: bool, - /// The macro's feature name if it is unstable, and the stability feature + /// The macro's feature name and tracking issue number if it is unstable. unstable_feature: Option<(Symbol, u32)>, - /// Edition of the crate in which the macro is defined + /// Edition of the crate in which this macro is defined. edition: Edition, }, - /// A function-like syntax extension that has an extra ident before - /// the block. - IdentTT { - expander: Box, - span: Option, - allow_internal_unstable: Option>, + /// A token-based attribute macro. + Attr( + /// An expander with signature (TokenStream, TokenStream) -> TokenStream. + /// The first TokenSteam is the attribute itself, the second is the annotated item. + /// The produced TokenSteam replaces the input TokenSteam. + Box, + /// Edition of the crate in which this macro is defined. + Edition, + ), + + /// An AST-based attribute macro. + LegacyAttr( + /// An expander with signature (AST, AST) -> AST. + /// The first AST fragment is the attribute itself, the second is the annotated item. + /// The produced AST fragment replaces the input AST fragment. + Box, + ), + + /// A trivial attribute "macro" that does nothing, + /// only keeps the attribute and marks it as known. + NonMacroAttr { + /// Suppresses the `unused_attributes` lint for this attribute. + mark_used: bool, }, - /// An attribute-like procedural macro. TokenStream -> TokenStream. - /// The input is the annotated item. - /// Allows generating code to implement a Trait for a given struct - /// or enum item. - ProcMacroDerive(Box, - Vec /* inert attribute names */, Edition), - - /// An attribute-like procedural macro that derives a builtin trait. - BuiltinDerive(BuiltinDeriveFn), - - /// A declarative macro, e.g., `macro m() {}`. - DeclMacro { - expander: Box, - def_info: Option<(ast::NodeId, Span)>, - is_transparent: bool, - edition: Edition, - } + /// A token-based derive macro. + Derive( + /// An expander with signature TokenStream -> TokenStream (not yet). + /// The produced TokenSteam is appended to the input TokenSteam. + Box, + /// Names of helper attributes registered by this macro. + Vec, + /// Edition of the crate in which this macro is defined. + Edition, + ), + + /// An AST-based derive macro. + LegacyDerive( + /// An expander with signature AST -> AST. + /// The produced AST fragment is appended to the input AST fragment. + Box, + ), } impl SyntaxExtension { /// Returns which kind of macro calls this syntax extension. pub fn kind(&self) -> MacroKind { match *self { - SyntaxExtension::DeclMacro { .. } | - SyntaxExtension::NormalTT { .. } | - SyntaxExtension::IdentTT { .. } | - SyntaxExtension::ProcMacro { .. } => - MacroKind::Bang, - SyntaxExtension::NonMacroAttr { .. } | - SyntaxExtension::MultiDecorator(..) | - SyntaxExtension::MultiModifier(..) | - SyntaxExtension::AttrProcMacro(..) => - MacroKind::Attr, - SyntaxExtension::ProcMacroDerive(..) | - SyntaxExtension::BuiltinDerive(..) => - MacroKind::Derive, + SyntaxExtension::Bang { .. } | + SyntaxExtension::LegacyBang { .. } => MacroKind::Bang, + SyntaxExtension::Attr(..) | + SyntaxExtension::LegacyAttr(..) | + SyntaxExtension::NonMacroAttr { .. } => MacroKind::Attr, + SyntaxExtension::Derive(..) | + SyntaxExtension::LegacyDerive(..) => MacroKind::Derive, } } pub fn default_transparency(&self) -> Transparency { match *self { - SyntaxExtension::ProcMacro { .. } | - SyntaxExtension::AttrProcMacro(..) | - SyntaxExtension::ProcMacroDerive(..) | - SyntaxExtension::DeclMacro { is_transparent: false, .. } => Transparency::Opaque, - SyntaxExtension::DeclMacro { is_transparent: true, .. } => Transparency::Transparent, - _ => Transparency::SemiTransparent, + SyntaxExtension::LegacyBang { transparency, .. } => transparency, + SyntaxExtension::Bang { .. } | + SyntaxExtension::Attr(..) | + SyntaxExtension::Derive(..) | + SyntaxExtension::NonMacroAttr { .. } => Transparency::Opaque, + SyntaxExtension::LegacyAttr(..) | + SyntaxExtension::LegacyDerive(..) => Transparency::SemiTransparent, } } pub fn edition(&self, default_edition: Edition) -> Edition { match *self { - SyntaxExtension::NormalTT { edition, .. } | - SyntaxExtension::DeclMacro { edition, .. } | - SyntaxExtension::ProcMacro { edition, .. } | - SyntaxExtension::AttrProcMacro(.., edition) | - SyntaxExtension::ProcMacroDerive(.., edition) => edition, + SyntaxExtension::Bang { edition, .. } | + SyntaxExtension::LegacyBang { edition, .. } | + SyntaxExtension::Attr(.., edition) | + SyntaxExtension::Derive(.., edition) => edition, // Unstable legacy stuff SyntaxExtension::NonMacroAttr { .. } | - SyntaxExtension::IdentTT { .. } | - SyntaxExtension::MultiDecorator(..) | - SyntaxExtension::MultiModifier(..) | - SyntaxExtension::BuiltinDerive(..) => default_edition, + SyntaxExtension::LegacyAttr(..) | + SyntaxExtension::LegacyDerive(..) => default_edition, } } } diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 9960539555332..084d4fd382017 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -389,7 +389,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { let item = match self.cx.resolver.resolve_macro_path( path, MacroKind::Derive, Mark::root(), Vec::new(), false) { Ok(ext) => match *ext { - BuiltinDerive(..) => item_with_markers.clone(), + SyntaxExtension::LegacyDerive(..) => item_with_markers.clone(), _ => item.clone(), }, _ => item.clone(), @@ -548,7 +548,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { _ => unreachable!(), }; - if let NonMacroAttr { mark_used: false } = *ext {} else { + if let SyntaxExtension::NonMacroAttr { mark_used: false } = *ext {} else { // Macro attrs are always used when expanded, // non-macro attrs are considered used when the field says so. attr::mark_used(&attr); @@ -564,26 +564,18 @@ impl<'a, 'b> MacroExpander<'a, 'b> { }); match *ext { - NonMacroAttr { .. } => { + SyntaxExtension::NonMacroAttr { .. } => { attr::mark_known(&attr); item.visit_attrs(|attrs| attrs.push(attr)); Some(invoc.fragment_kind.expect_from_annotatables(iter::once(item))) } - MultiModifier(ref mac) => { + SyntaxExtension::LegacyAttr(ref mac) => { let meta = attr.parse_meta(self.cx.parse_sess) .map_err(|mut e| { e.emit(); }).ok()?; let item = mac.expand(self.cx, attr.span, &meta, item); Some(invoc.fragment_kind.expect_from_annotatables(item)) } - MultiDecorator(ref mac) => { - let mut items = Vec::new(); - let meta = attr.parse_meta(self.cx.parse_sess) - .expect("derive meta should already have been parsed"); - mac.expand(self.cx, attr.span, &meta, &item, &mut |item| items.push(item)); - items.push(item); - Some(invoc.fragment_kind.expect_from_annotatables(items)) - } - AttrProcMacro(ref mac, ..) => { + SyntaxExtension::Attr(ref mac, ..) => { self.gate_proc_macro_attr_item(attr.span, &item); let item_tok = TokenTree::token(token::Interpolated(Lrc::new(match item { Annotatable::Item(item) => token::NtItem(item), @@ -600,7 +592,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { self.gate_proc_macro_expansion(attr.span, &res); res } - ProcMacroDerive(..) | BuiltinDerive(..) => { + SyntaxExtension::Derive(..) | SyntaxExtension::LegacyDerive(..) => { self.cx.span_err(attr.span, &format!("`{}` is a derive macro", attr.path)); self.cx.trace_macros_diag(); invoc.fragment_kind.dummy(attr.span) @@ -755,17 +747,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { }; let opt_expanded = match *ext { - DeclMacro { ref expander, def_info, edition, .. } => { - if let Err(dummy_span) = validate_and_set_expn_info(self, def_info.map(|(_, s)| s), - None, false, false, None, - edition) { - dummy_span - } else { - kind.make_from(expander.expand(self.cx, span, mac.node.stream(), None)) - } - } - - NormalTT { + SyntaxExtension::LegacyBang { ref expander, def_info, ref allow_internal_unstable, @@ -773,6 +755,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> { local_inner_macros, unstable_feature, edition, + .. } => { if let Err(dummy_span) = validate_and_set_expn_info(self, def_info.map(|(_, s)| s), allow_internal_unstable.clone(), @@ -791,43 +774,22 @@ impl<'a, 'b> MacroExpander<'a, 'b> { } } - IdentTT { ref expander, span: tt_span, ref allow_internal_unstable } => { - if ident.name == kw::Invalid { - self.cx.span_err(path.span, - &format!("macro {}! expects an ident argument", path)); - self.cx.trace_macros_diag(); - kind.dummy(span) - } else { - invoc.expansion_data.mark.set_expn_info(ExpnInfo { - call_site: span, - def_site: tt_span, - format: macro_bang_format(path), - allow_internal_unstable: allow_internal_unstable.clone(), - allow_internal_unsafe: false, - local_inner_macros: false, - edition: self.cx.parse_sess.edition, - }); - - let input: Vec<_> = mac.node.stream().into_trees().collect(); - kind.make_from(expander.expand(self.cx, span, ident, input)) - } - } - - MultiDecorator(..) | MultiModifier(..) | - AttrProcMacro(..) | SyntaxExtension::NonMacroAttr { .. } => { + SyntaxExtension::Attr(..) | + SyntaxExtension::LegacyAttr(..) | + SyntaxExtension::NonMacroAttr { .. } => { self.cx.span_err(path.span, &format!("`{}` can only be used in attributes", path)); self.cx.trace_macros_diag(); kind.dummy(span) } - ProcMacroDerive(..) | BuiltinDerive(..) => { + SyntaxExtension::Derive(..) | SyntaxExtension::LegacyDerive(..) => { self.cx.span_err(path.span, &format!("`{}` is a derive macro", path)); self.cx.trace_macros_diag(); kind.dummy(span) } - SyntaxExtension::ProcMacro { ref expander, ref allow_internal_unstable, edition } => { + SyntaxExtension::Bang { ref expander, ref allow_internal_unstable, edition } => { if ident.name != kw::Invalid { let msg = format!("macro {}! expects no ident argument, given '{}'", path, ident); @@ -924,29 +886,29 @@ impl<'a, 'b> MacroExpander<'a, 'b> { edition: ext.edition(self.cx.parse_sess.edition), }; - match *ext { - ProcMacroDerive(ref ext, ..) => { - invoc.expansion_data.mark.set_expn_info(expn_info); - let span = span.with_ctxt(self.cx.backtrace()); - let dummy = ast::MetaItem { // FIXME(jseyfried) avoid this - path: Path::from_ident(Ident::invalid()), - span: DUMMY_SP, - node: ast::MetaItemKind::Word, + match ext { + SyntaxExtension::Derive(expander, ..) | SyntaxExtension::LegacyDerive(expander) => { + let meta = match ext { + SyntaxExtension::Derive(..) => ast::MetaItem { // FIXME(jseyfried) avoid this + path: Path::from_ident(Ident::invalid()), + span: DUMMY_SP, + node: ast::MetaItemKind::Word, + }, + _ => { + expn_info.allow_internal_unstable = Some(vec![ + sym::rustc_attrs, + Symbol::intern("derive_clone_copy"), + Symbol::intern("derive_eq"), + // RustcDeserialize and RustcSerialize + Symbol::intern("libstd_sys_internals"), + ].into()); + attr.meta()? + } }; - let items = ext.expand(self.cx, span, &dummy, item); - Some(invoc.fragment_kind.expect_from_annotatables(items)) - } - BuiltinDerive(func) => { - expn_info.allow_internal_unstable = Some(vec![ - sym::rustc_attrs, - Symbol::intern("derive_clone_copy"), - Symbol::intern("derive_eq"), - Symbol::intern("libstd_sys_internals"), // RustcDeserialize and RustcSerialize - ].into()); + invoc.expansion_data.mark.set_expn_info(expn_info); let span = span.with_ctxt(self.cx.backtrace()); - let mut items = Vec::new(); - func(self.cx, span, &attr.meta()?, &item, &mut |a| items.push(a)); + let items = expander.expand(self.cx, span, &meta, item); Some(invoc.fragment_kind.expect_from_annotatables(items)) } _ => { diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs index 6f82f5094651e..5dbf21867afa6 100644 --- a/src/libsyntax/ext/tt/macro_rules.rs +++ b/src/libsyntax/ext/tt/macro_rules.rs @@ -1,8 +1,8 @@ use crate::{ast, attr}; use crate::edition::Edition; -use crate::ext::base::{DummyResult, ExtCtxt, MacResult, SyntaxExtension}; -use crate::ext::base::{NormalTT, TTMacroExpander}; +use crate::ext::base::{DummyResult, ExtCtxt, MacResult, SyntaxExtension, TTMacroExpander}; use crate::ext::expand::{AstFragment, AstFragmentKind}; +use crate::ext::hygiene::Transparency; use crate::ext::tt::macro_parser::{Success, Error, Failure}; use crate::ext::tt::macro_parser::{MatchedSeq, MatchedNonterminal}; use crate::ext::tt::macro_parser::{parse, parse_failure_msg}; @@ -374,65 +374,65 @@ pub fn compile( valid, }); - if body.legacy { - let allow_internal_unstable = attr::find_by_name(&def.attrs, sym::allow_internal_unstable) - .map(|attr| attr - .meta_item_list() - .map(|list| list.iter() - .filter_map(|it| { - let name = it.ident().map(|ident| ident.name); - if name.is_none() { - sess.span_diagnostic.span_err(it.span(), - "allow internal unstable expects feature names") - } - name - }) - .collect::>().into() - ) - .unwrap_or_else(|| { - sess.span_diagnostic.span_warn( - attr.span, "allow_internal_unstable expects list of feature names. In the \ - future this will become a hard error. Please use `allow_internal_unstable(\ - foo, bar)` to only allow the `foo` and `bar` features", - ); - vec![sym::allow_internal_unstable_backcompat_hack].into() + let transparency = if attr::contains_name(&def.attrs, sym::rustc_transparent_macro) { + Transparency::Transparent + } else if body.legacy { + Transparency::SemiTransparent + } else { + Transparency::Opaque + }; + + let allow_internal_unstable = attr::find_by_name(&def.attrs, sym::allow_internal_unstable) + .map(|attr| attr + .meta_item_list() + .map(|list| list.iter() + .filter_map(|it| { + let name = it.ident().map(|ident| ident.name); + if name.is_none() { + sess.span_diagnostic.span_err(it.span(), + "allow internal unstable expects feature names") + } + name }) - ); - let allow_internal_unsafe = attr::contains_name(&def.attrs, sym::allow_internal_unsafe); - let mut local_inner_macros = false; - if let Some(macro_export) = attr::find_by_name(&def.attrs, sym::macro_export) { - if let Some(l) = macro_export.meta_item_list() { - local_inner_macros = attr::list_contains_name(&l, sym::local_inner_macros); - } - } + .collect::>().into() + ) + .unwrap_or_else(|| { + sess.span_diagnostic.span_warn( + attr.span, "allow_internal_unstable expects list of feature names. In the \ + future this will become a hard error. Please use `allow_internal_unstable(\ + foo, bar)` to only allow the `foo` and `bar` features", + ); + vec![sym::allow_internal_unstable_backcompat_hack].into() + }) + ); - let unstable_feature = attr::find_stability(&sess, - &def.attrs, def.span).and_then(|stability| { - if let attr::StabilityLevel::Unstable { issue, .. } = stability.level { - Some((stability.feature, issue)) - } else { - None - } - }); - - NormalTT { - expander, - def_info: Some((def.id, def.span)), - allow_internal_unstable, - allow_internal_unsafe, - local_inner_macros, - unstable_feature, - edition, + let allow_internal_unsafe = attr::contains_name(&def.attrs, sym::allow_internal_unsafe); + + let mut local_inner_macros = false; + if let Some(macro_export) = attr::find_by_name(&def.attrs, sym::macro_export) { + if let Some(l) = macro_export.meta_item_list() { + local_inner_macros = attr::list_contains_name(&l, sym::local_inner_macros); } - } else { - let is_transparent = attr::contains_name(&def.attrs, sym::rustc_transparent_macro); + } - SyntaxExtension::DeclMacro { - expander, - def_info: Some((def.id, def.span)), - is_transparent, - edition, + let unstable_feature = attr::find_stability(&sess, + &def.attrs, def.span).and_then(|stability| { + if let attr::StabilityLevel::Unstable { issue, .. } = stability.level { + Some((stability.feature, issue)) + } else { + None } + }); + + SyntaxExtension::LegacyBang { + expander, + def_info: Some((def.id, def.span)), + transparency, + allow_internal_unstable, + allow_internal_unsafe, + local_inner_macros, + unstable_feature, + edition, } } diff --git a/src/libsyntax_ext/deriving/mod.rs b/src/libsyntax_ext/deriving/mod.rs index ac41f30e6b39f..cf54eacc3d46c 100644 --- a/src/libsyntax_ext/deriving/mod.rs +++ b/src/libsyntax_ext/deriving/mod.rs @@ -1,8 +1,8 @@ //! The compiler code necessary to implement the `#[derive]` extensions. use rustc_data_structures::sync::Lrc; -use syntax::ast; -use syntax::ext::base::{Annotatable, ExtCtxt, SyntaxExtension, Resolver}; +use syntax::ast::{self, MetaItem}; +use syntax::ext::base::{Annotatable, ExtCtxt, SyntaxExtension, Resolver, MultiItemModifier}; use syntax::ext::build::AstBuilder; use syntax::ext::hygiene::{Mark, SyntaxContext}; use syntax::ptr::P; @@ -39,9 +39,25 @@ pub mod partial_ord; #[path="cmp/ord.rs"] pub mod ord; - pub mod generic; +struct BuiltinDerive( + fn(&mut ExtCtxt<'_>, Span, &MetaItem, &Annotatable, &mut dyn FnMut(Annotatable)) +); + +impl MultiItemModifier for BuiltinDerive { + fn expand(&self, + ecx: &mut ExtCtxt<'_>, + span: Span, + meta_item: &MetaItem, + item: Annotatable) + -> Vec { + let mut items = Vec::new(); + (self.0)(ecx, span, meta_item, &item, &mut |a| items.push(a)); + items + } +} + macro_rules! derive_traits { ($( $name:expr => $func:path, )+) => { pub fn is_builtin_trait(name: ast::Name) -> bool { @@ -55,7 +71,7 @@ macro_rules! derive_traits { $( resolver.add_builtin( ast::Ident::with_empty_ctxt(Symbol::intern($name)), - Lrc::new(SyntaxExtension::BuiltinDerive($func)) + Lrc::new(SyntaxExtension::LegacyDerive(Box::new(BuiltinDerive($func)))) ); )* } diff --git a/src/libsyntax_ext/lib.rs b/src/libsyntax_ext/lib.rs index fc00154427501..7c4085aa09653 100644 --- a/src/libsyntax_ext/lib.rs +++ b/src/libsyntax_ext/lib.rs @@ -41,7 +41,9 @@ pub mod proc_macro_impl; use rustc_data_structures::sync::Lrc; use syntax::ast; -use syntax::ext::base::{MacroExpanderFn, NormalTT, NamedSyntaxExtension, MultiModifier}; + +use syntax::ext::base::{MacroExpanderFn, NamedSyntaxExtension, SyntaxExtension}; +use syntax::ext::hygiene::Transparency; use syntax::edition::Edition; use syntax::symbol::{sym, Symbol}; @@ -56,9 +58,10 @@ pub fn register_builtins(resolver: &mut dyn syntax::ext::base::Resolver, macro_rules! register { ($( $name:ident: $f:expr, )*) => { $( register(Symbol::intern(stringify!($name)), - NormalTT { + SyntaxExtension::LegacyBang { expander: Box::new($f as MacroExpanderFn), def_info: None, + transparency: Transparency::SemiTransparent, allow_internal_unstable: None, allow_internal_unsafe: false, local_inner_macros: false, @@ -93,15 +96,16 @@ pub fn register_builtins(resolver: &mut dyn syntax::ext::base::Resolver, assert: assert::expand_assert, } - register(sym::test_case, MultiModifier(Box::new(test_case::expand))); - register(sym::test, MultiModifier(Box::new(test::expand_test))); - register(sym::bench, MultiModifier(Box::new(test::expand_bench))); + register(sym::test_case, SyntaxExtension::LegacyAttr(Box::new(test_case::expand))); + register(sym::test, SyntaxExtension::LegacyAttr(Box::new(test::expand_test))); + register(sym::bench, SyntaxExtension::LegacyAttr(Box::new(test::expand_bench))); // format_args uses `unstable` things internally. register(Symbol::intern("format_args"), - NormalTT { + SyntaxExtension::LegacyBang { expander: Box::new(format::expand_format_args), def_info: None, + transparency: Transparency::SemiTransparent, allow_internal_unstable: Some(vec![sym::fmt_internals].into()), allow_internal_unsafe: false, local_inner_macros: false, @@ -109,9 +113,10 @@ pub fn register_builtins(resolver: &mut dyn syntax::ext::base::Resolver, edition, }); register(sym::format_args_nl, - NormalTT { + SyntaxExtension::LegacyBang { expander: Box::new(format::expand_format_args_nl), def_info: None, + transparency: Transparency::SemiTransparent, allow_internal_unstable: Some(vec![sym::fmt_internals].into()), allow_internal_unsafe: false, local_inner_macros: false, diff --git a/src/libunwind/Cargo.toml b/src/libunwind/Cargo.toml index 4ddc878997ee5..f0f1bab425d7a 100644 --- a/src/libunwind/Cargo.toml +++ b/src/libunwind/Cargo.toml @@ -19,6 +19,7 @@ doc = false core = { path = "../libcore" } libc = { version = "0.2.43", features = ['rustc-dep-of-std'], default-features = false } compiler_builtins = "0.1.0" +cfg-if = "0.1.8" [build-dependencies] cc = { optional = true, version = "1.0.1" } diff --git a/src/libunwind/lib.rs b/src/libunwind/lib.rs index 0ccffea317053..9182e349b196e 100644 --- a/src/libunwind/lib.rs +++ b/src/libunwind/lib.rs @@ -11,10 +11,7 @@ #![cfg_attr(not(target_env = "msvc"), feature(libc))] -#[macro_use] -mod macros; - -cfg_if! { +cfg_if::cfg_if! { if #[cfg(target_env = "msvc")] { // no extra unwinder support needed } else if #[cfg(all(target_arch = "wasm32", not(target_os = "emscripten")))] { diff --git a/src/libunwind/libunwind.rs b/src/libunwind/libunwind.rs index 339b554ed6abd..5794e0b7683cb 100644 --- a/src/libunwind/libunwind.rs +++ b/src/libunwind/libunwind.rs @@ -1,10 +1,5 @@ #![allow(nonstandard_style)] -macro_rules! cfg_if { - ( $( if #[cfg( $meta:meta )] { $($it1:item)* } else { $($it2:item)* } )* ) => - ( $( $( #[cfg($meta)] $it1)* $( #[cfg(not($meta))] $it2)* )* ) -} - use libc::{c_int, c_void, uintptr_t}; #[repr(C)] @@ -82,7 +77,7 @@ extern "C" { pub fn _Unwind_GetDataRelBase(ctx: *mut _Unwind_Context) -> _Unwind_Ptr; } -cfg_if! { +cfg_if::cfg_if! { if #[cfg(all(any(target_os = "ios", target_os = "netbsd", not(target_arch = "arm"))))] { // Not ARM EHABI #[repr(C)] @@ -206,7 +201,9 @@ if #[cfg(all(any(target_os = "ios", target_os = "netbsd", not(target_arch = "arm pc } } +} // cfg_if! +cfg_if::cfg_if! { if #[cfg(not(all(target_os = "ios", target_arch = "arm")))] { // Not 32-bit iOS extern "C" { diff --git a/src/libunwind/macros.rs b/src/libunwind/macros.rs deleted file mode 100644 index 659e977285e35..0000000000000 --- a/src/libunwind/macros.rs +++ /dev/null @@ -1,35 +0,0 @@ -/// A macro for defining `#[cfg]` if-else statements. -/// -/// This is similar to the `if/elif` C preprocessor macro by allowing definition -/// of a cascade of `#[cfg]` cases, emitting the implementation which matches -/// first. -/// -/// This allows you to conveniently provide a long list `#[cfg]`'d blocks of code -/// without having to rewrite each clause multiple times. -macro_rules! cfg_if { - ($( - if #[cfg($($meta:meta),*)] { $($it:item)* } - ) else * else { - $($it2:item)* - }) => { - __cfg_if_items! { - () ; - $( ( ($($meta),*) ($($it)*) ), )* - ( () ($($it2)*) ), - } - } -} - -macro_rules! __cfg_if_items { - (($($not:meta,)*) ; ) => {}; - (($($not:meta,)*) ; ( ($($m:meta),*) ($($it:item)*) ), $($rest:tt)*) => { - __cfg_if_apply! { cfg(all(not(any($($not),*)), $($m,)*)), $($it)* } - __cfg_if_items! { ($($not,)* $($m,)*) ; $($rest)* } - } -} - -macro_rules! __cfg_if_apply { - ($m:meta, $($it:item)*) => { - $(#[$m] $it)* - } -} diff --git a/src/test/codegen/exact_div.rs b/src/test/codegen/intrinsics/exact_div.rs similarity index 87% rename from src/test/codegen/exact_div.rs rename to src/test/codegen/intrinsics/exact_div.rs index 6a55b492cb1e1..68eaa39997a15 100644 --- a/src/test/codegen/exact_div.rs +++ b/src/test/codegen/intrinsics/exact_div.rs @@ -8,13 +8,13 @@ use std::intrinsics::exact_div; // CHECK-LABEL: @exact_sdiv #[no_mangle] pub unsafe fn exact_sdiv(x: i32, y: i32) -> i32 { -// CHECK: sdiv exact + // CHECK: sdiv exact exact_div(x, y) } // CHECK-LABEL: @exact_udiv #[no_mangle] pub unsafe fn exact_udiv(x: u32, y: u32) -> u32 { -// CHECK: udiv exact + // CHECK: udiv exact exact_div(x, y) } diff --git a/src/test/codegen/likely.rs b/src/test/codegen/intrinsics/likely.rs similarity index 100% rename from src/test/codegen/likely.rs rename to src/test/codegen/intrinsics/likely.rs diff --git a/src/test/codegen/move-val-init.rs b/src/test/codegen/intrinsics/move-val-init.rs similarity index 100% rename from src/test/codegen/move-val-init.rs rename to src/test/codegen/intrinsics/move-val-init.rs diff --git a/src/test/codegen/nontemporal.rs b/src/test/codegen/intrinsics/nontemporal.rs similarity index 100% rename from src/test/codegen/nontemporal.rs rename to src/test/codegen/intrinsics/nontemporal.rs diff --git a/src/test/codegen/prefetch.rs b/src/test/codegen/intrinsics/prefetch.rs similarity index 100% rename from src/test/codegen/prefetch.rs rename to src/test/codegen/intrinsics/prefetch.rs diff --git a/src/test/codegen/unchecked_math.rs b/src/test/codegen/intrinsics/unchecked_math.rs similarity index 100% rename from src/test/codegen/unchecked_math.rs rename to src/test/codegen/intrinsics/unchecked_math.rs diff --git a/src/test/run-pass-fulldeps/auxiliary/custom-derive-partial-eq.rs b/src/test/run-pass-fulldeps/auxiliary/custom-derive-partial-eq.rs deleted file mode 100644 index 4d6ff47a3ee91..0000000000000 --- a/src/test/run-pass-fulldeps/auxiliary/custom-derive-partial-eq.rs +++ /dev/null @@ -1,71 +0,0 @@ -// force-host - -#![feature(plugin_registrar, rustc_private)] - -extern crate syntax; -extern crate syntax_ext; -extern crate rustc_plugin; - -use syntax_ext::deriving; -use deriving::generic::*; -use deriving::generic::ty::*; - -use rustc_plugin::Registry; -use syntax::ast::*; -use syntax::source_map::Span; -use syntax::ext::base::*; -use syntax::ext::build::AstBuilder; -use syntax::symbol::Symbol; -use syntax::ptr::P; - -#[plugin_registrar] -pub fn plugin_registrar(reg: &mut Registry) { - reg.register_syntax_extension(Symbol::intern("derive_CustomPartialEq"), - MultiDecorator(Box::new(expand_deriving_partial_eq))); -} - -fn expand_deriving_partial_eq(cx: &mut ExtCtxt, span: Span, mitem: &MetaItem, item: &Annotatable, - push: &mut FnMut(Annotatable)) { - // structures are equal if all fields are equal, and non equal, if - // any fields are not equal or if the enum variants are different - fn cs_eq(cx: &mut ExtCtxt, span: Span, substr: &Substructure) -> P { - cs_fold(true, - |cx, span, subexpr, self_f, other_fs| { - let other_f = (other_fs.len(), other_fs.get(0)).1.unwrap(); - let eq = cx.expr_binary(span, BinOpKind::Eq, self_f, other_f.clone()); - cx.expr_binary(span, BinOpKind::And, subexpr, eq) - }, - cx.expr_bool(span, true), - Box::new(|cx, span, _, _| cx.expr_bool(span, false)), - cx, - span, - substr) - } - - let inline = cx.meta_word(span, Symbol::intern("inline")); - let attrs = vec![cx.attribute(span, inline)]; - let methods = vec![MethodDef { - name: "eq", - generics: LifetimeBounds::empty(), - explicit_self: borrowed_explicit_self(), - args: vec![(borrowed_self(), "other")], - ret_ty: Literal(deriving::generic::ty::Path::new_local("bool")), - attributes: attrs, - is_unsafe: false, - unify_fieldless_variants: true, - combine_substructure: combine_substructure(Box::new(cs_eq)), - }]; - - let trait_def = TraitDef { - span: span, - attributes: Vec::new(), - path: deriving::generic::ty::Path::new(vec!["cmp", "PartialEq"]), - additional_bounds: Vec::new(), - generics: LifetimeBounds::empty(), - is_unsafe: false, - supports_unions: false, - methods: methods, - associated_types: Vec::new(), - }; - trait_def.expand(cx, mitem, item, push) -} diff --git a/src/test/run-pass-fulldeps/auxiliary/custom-derive-plugin-attr.rs b/src/test/run-pass-fulldeps/auxiliary/custom-derive-plugin-attr.rs deleted file mode 100644 index c6b33fbc75ee2..0000000000000 --- a/src/test/run-pass-fulldeps/auxiliary/custom-derive-plugin-attr.rs +++ /dev/null @@ -1,84 +0,0 @@ -// force-host - -#![feature(plugin_registrar)] -#![feature(box_syntax)] -#![feature(rustc_private)] - -extern crate syntax; -extern crate syntax_ext; -extern crate syntax_pos; -extern crate rustc; -extern crate rustc_plugin; - -use syntax::ast; -use syntax::attr; -use syntax::ext::base::{MultiDecorator, ExtCtxt, Annotatable}; -use syntax::ext::build::AstBuilder; -use syntax::symbol::{Symbol, sym}; -use syntax::ptr::P; -use syntax_ext::deriving::generic::{TraitDef, MethodDef, combine_substructure}; -use syntax_ext::deriving::generic::{Substructure, Struct, EnumMatching}; -use syntax_ext::deriving::generic::ty::{Literal, LifetimeBounds, Path, borrowed_explicit_self}; -use syntax_pos::Span; -use rustc_plugin::Registry; - -#[plugin_registrar] -pub fn plugin_registrar(reg: &mut Registry) { - reg.register_syntax_extension( - Symbol::intern("rustc_derive_TotalSum"), - MultiDecorator(box expand)); -} - -fn expand(cx: &mut ExtCtxt, - span: Span, - mitem: &ast::MetaItem, - item: &Annotatable, - push: &mut FnMut(Annotatable)) { - let trait_def = TraitDef { - span: span, - attributes: vec![], - path: Path::new_local("TotalSum"), - additional_bounds: vec![], - generics: LifetimeBounds::empty(), - associated_types: vec![], - is_unsafe: false, - supports_unions: false, - methods: vec![ - MethodDef { - name: "total_sum", - generics: LifetimeBounds::empty(), - explicit_self: borrowed_explicit_self(), - args: vec![], - ret_ty: Literal(Path::new_local("isize")), - attributes: vec![], - is_unsafe: false, - unify_fieldless_variants: true, - combine_substructure: combine_substructure(Box::new(totalsum_substructure)), - }, - ], - }; - - trait_def.expand(cx, mitem, item, push) -} - -// Mostly copied from syntax::ext::deriving::hash -/// Defines how the implementation for `trace()` is to be generated -fn totalsum_substructure(cx: &mut ExtCtxt, trait_span: Span, - substr: &Substructure) -> P { - let fields = match *substr.fields { - Struct(_, ref fs) | EnumMatching(.., ref fs) => fs, - _ => cx.span_bug(trait_span, "impossible substructure") - }; - - fields.iter().fold(cx.expr_isize(trait_span, 0), |acc, ref item| { - if attr::contains_name(&item.attrs, sym::ignore) { - acc - } else { - cx.expr_binary(item.span, ast::BinOpKind::Add, acc, - cx.expr_method_call(item.span, - item.self_.clone(), - substr.method_ident, - Vec::new())) - } - }) -} diff --git a/src/test/run-pass-fulldeps/auxiliary/custom-derive-plugin.rs b/src/test/run-pass-fulldeps/auxiliary/custom-derive-plugin.rs deleted file mode 100644 index 874a0ec7c13fb..0000000000000 --- a/src/test/run-pass-fulldeps/auxiliary/custom-derive-plugin.rs +++ /dev/null @@ -1,76 +0,0 @@ -// force-host - -#![feature(plugin_registrar)] -#![feature(box_syntax)] -#![feature(rustc_private)] - -extern crate syntax; -extern crate syntax_ext; -extern crate syntax_pos; -extern crate rustc; -extern crate rustc_plugin; - -use syntax::ast; -use syntax::ext::base::{MultiDecorator, ExtCtxt, Annotatable}; -use syntax::ext::build::AstBuilder; -use syntax::symbol::Symbol; -use syntax_ext::deriving::generic::{cs_fold, TraitDef, MethodDef, combine_substructure}; -use syntax_ext::deriving::generic::ty::{Literal, LifetimeBounds, Path, borrowed_explicit_self}; -use syntax_pos::Span; -use rustc_plugin::Registry; - -#[plugin_registrar] -pub fn plugin_registrar(reg: &mut Registry) { - reg.register_syntax_extension( - Symbol::intern("derive_TotalSum"), - MultiDecorator(box expand)); - - reg.register_syntax_extension( - Symbol::intern("derive_Nothing"), - MultiDecorator(box noop)); -} - -fn noop(_: &mut ExtCtxt, _: Span, _: &ast::MetaItem, _: &Annotatable, _: &mut FnMut(Annotatable)) {} - -fn expand(cx: &mut ExtCtxt, - span: Span, - mitem: &ast::MetaItem, - item: &Annotatable, - push: &mut FnMut(Annotatable)) { - let trait_def = TraitDef { - span: span, - attributes: vec![], - path: Path::new_local("TotalSum"), - additional_bounds: vec![], - generics: LifetimeBounds::empty(), - associated_types: vec![], - is_unsafe: false, - supports_unions: false, - methods: vec![ - MethodDef { - name: "total_sum", - generics: LifetimeBounds::empty(), - explicit_self: borrowed_explicit_self(), - args: vec![], - ret_ty: Literal(Path::new_local("isize")), - attributes: vec![], - is_unsafe: false, - unify_fieldless_variants: true, - combine_substructure: combine_substructure(box |cx, span, substr| { - let zero = cx.expr_isize(span, 0); - cs_fold(false, - |cx, span, subexpr, field, _| { - cx.expr_binary(span, ast::BinOpKind::Add, subexpr, - cx.expr_method_call(span, field, - ast::Ident::from_str("total_sum"), vec![])) - }, - zero, - box |cx, span, _, _| { cx.span_bug(span, "wtf??"); }, - cx, span, substr) - }), - }, - ], - }; - - trait_def.expand(cx, mitem, item, push) -} diff --git a/src/test/run-pass-fulldeps/auxiliary/plugin-args.rs b/src/test/run-pass-fulldeps/auxiliary/plugin-args.rs index 096701bd9b3ed..330459fc08f55 100644 --- a/src/test/run-pass-fulldeps/auxiliary/plugin-args.rs +++ b/src/test/run-pass-fulldeps/auxiliary/plugin-args.rs @@ -10,11 +10,10 @@ extern crate rustc_plugin; use std::borrow::ToOwned; use syntax::ast; -use syntax::ext::hygiene; use syntax::ext::build::AstBuilder; -use syntax::ext::base::{TTMacroExpander, ExtCtxt, MacResult, MacEager, NormalTT}; +use syntax::ext::base::{SyntaxExtension, TTMacroExpander, ExtCtxt, MacResult, MacEager}; +use syntax::ext::hygiene::Transparency; use syntax::print::pprust; -use syntax::ptr::P; use syntax::symbol::Symbol; use syntax_pos::Span; use syntax::tokenstream::TokenStream; @@ -29,7 +28,7 @@ impl TTMacroExpander for Expander { ecx: &'cx mut ExtCtxt, sp: Span, _: TokenStream, - _: Option) -> Box { + _: Option) -> Box { let args = self.args.iter().map(|i| pprust::meta_list_item_to_string(i)) .collect::>().join(", "); MacEager::expr(ecx.expr_str(sp, Symbol::intern(&args))) @@ -40,9 +39,10 @@ impl TTMacroExpander for Expander { pub fn plugin_registrar(reg: &mut Registry) { let args = reg.args().to_owned(); reg.register_syntax_extension(Symbol::intern("plugin_args"), - NormalTT { + SyntaxExtension::LegacyBang { expander: Box::new(Expander { args: args, }), def_info: None, + transparency: Transparency::SemiTransparent, allow_internal_unstable: None, allow_internal_unsafe: false, local_inner_macros: false, diff --git a/src/test/run-pass-fulldeps/custom-derive-partial-eq.rs b/src/test/run-pass-fulldeps/custom-derive-partial-eq.rs deleted file mode 100644 index ac8fff4f6bfad..0000000000000 --- a/src/test/run-pass-fulldeps/custom-derive-partial-eq.rs +++ /dev/null @@ -1,10 +0,0 @@ -// aux-build:custom-derive-partial-eq.rs -// ignore-stage1 -#![feature(plugin)] -#![plugin(custom_derive_partial_eq)] -#![allow(unused)] - -#[derive_CustomPartialEq] // Check that this is not a stability error. -enum E { V1, V2 } - -fn main() {} diff --git a/src/test/run-pass-fulldeps/derive-totalsum-attr.rs b/src/test/run-pass-fulldeps/derive-totalsum-attr.rs deleted file mode 100644 index 38eaa71dd6aba..0000000000000 --- a/src/test/run-pass-fulldeps/derive-totalsum-attr.rs +++ /dev/null @@ -1,64 +0,0 @@ -// aux-build:custom-derive-plugin-attr.rs -// ignore-stage1 - -#![feature(plugin, rustc_attrs)] -#![plugin(custom_derive_plugin_attr)] - -trait TotalSum { - fn total_sum(&self) -> isize; -} - -impl TotalSum for isize { - fn total_sum(&self) -> isize { - *self - } -} - -struct Seven; - -impl TotalSum for Seven { - fn total_sum(&self) -> isize { - 7 - } -} - -#[rustc_derive_TotalSum] -struct Foo { - seven: Seven, - bar: Bar, - baz: isize, - #[ignore] - nan: NaN, -} - -#[rustc_derive_TotalSum] -struct Bar { - quux: isize, - bleh: isize, - #[ignore] - nan: NaN2 -} - -struct NaN; - -impl TotalSum for NaN { - fn total_sum(&self) -> isize { - panic!(); - } -} - -struct NaN2; - -pub fn main() { - let v = Foo { - seven: Seven, - bar: Bar { - quux: 9, - bleh: 3, - nan: NaN2 - }, - baz: 80, - nan: NaN - }; - assert_eq!(v.total_sum(), 99); -} diff --git a/src/test/run-pass-fulldeps/derive-totalsum.rs b/src/test/run-pass-fulldeps/derive-totalsum.rs deleted file mode 100644 index 2b0bb51d90aec..0000000000000 --- a/src/test/run-pass-fulldeps/derive-totalsum.rs +++ /dev/null @@ -1,49 +0,0 @@ -// aux-build:custom-derive-plugin.rs -// ignore-stage1 - -#![feature(plugin)] -#![plugin(custom_derive_plugin)] - -trait TotalSum { - fn total_sum(&self) -> isize; -} - -impl TotalSum for isize { - fn total_sum(&self) -> isize { - *self - } -} - -struct Seven; - -impl TotalSum for Seven { - fn total_sum(&self) -> isize { - 7 - } -} - -#[derive_TotalSum] -struct Foo { - seven: Seven, - bar: Bar, - baz: isize, -} - -#[derive_TotalSum] -struct Bar { - quux: isize, - bleh: isize, -} - - -pub fn main() { - let v = Foo { - seven: Seven, - bar: Bar { - quux: 9, - bleh: 3, - }, - baz: 80, - }; - assert_eq!(v.total_sum(), 99); -} diff --git a/src/test/run-pass-fulldeps/issue-40663.rs b/src/test/run-pass-fulldeps/issue-40663.rs deleted file mode 100644 index 133f6302bde57..0000000000000 --- a/src/test/run-pass-fulldeps/issue-40663.rs +++ /dev/null @@ -1,13 +0,0 @@ -#![allow(dead_code)] -// aux-build:custom-derive-plugin.rs -// ignore-stage1 - -#![feature(plugin)] -#![plugin(custom_derive_plugin)] - -#[derive_Nothing] -#[derive_Nothing] -#[derive_Nothing] -struct S; - -fn main() {} diff --git a/src/test/ui/const-generics/issue-61336-1.rs b/src/test/ui/const-generics/issue-61336-1.rs new file mode 100644 index 0000000000000..5b5e431bf2ff6 --- /dev/null +++ b/src/test/ui/const-generics/issue-61336-1.rs @@ -0,0 +1,12 @@ +#![feature(const_generics)] +//~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash + +fn f(x: T) -> [T; N] { + [x; N] + //~^ ERROR array lengths can't depend on generic parameters +} + +fn main() { + let x: [u32; 5] = f::(3); + assert_eq!(x, [3u32; 5]); +} diff --git a/src/test/ui/const-generics/issue-61336-1.stderr b/src/test/ui/const-generics/issue-61336-1.stderr new file mode 100644 index 0000000000000..1a5bb9f763bcf --- /dev/null +++ b/src/test/ui/const-generics/issue-61336-1.stderr @@ -0,0 +1,14 @@ +warning: the feature `const_generics` is incomplete and may cause the compiler to crash + --> $DIR/issue-61336-1.rs:1:12 + | +LL | #![feature(const_generics)] + | ^^^^^^^^^^^^^^ + +error: array lengths can't depend on generic parameters + --> $DIR/issue-61336-1.rs:5:9 + | +LL | [x; N] + | ^ + +error: aborting due to previous error + diff --git a/src/test/ui/const-generics/issue-61336.rs b/src/test/ui/const-generics/issue-61336.rs new file mode 100644 index 0000000000000..95930371d5974 --- /dev/null +++ b/src/test/ui/const-generics/issue-61336.rs @@ -0,0 +1,16 @@ +#![feature(const_generics)] +//~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash + +fn f(x: T) -> [T; N] { + [x; N] +} + +fn g(x: T) -> [T; N] { + [x; N] + //~^ ERROR the trait bound `T: std::marker::Copy` is not satisfied [E0277] +} + +fn main() { + let x: [u32; 5] = f::(3); + assert_eq!(x, [3u32; 5]); +} diff --git a/src/test/ui/const-generics/issue-61336.stderr b/src/test/ui/const-generics/issue-61336.stderr new file mode 100644 index 0000000000000..9939a5998340f --- /dev/null +++ b/src/test/ui/const-generics/issue-61336.stderr @@ -0,0 +1,18 @@ +warning: the feature `const_generics` is incomplete and may cause the compiler to crash + --> $DIR/issue-61336.rs:1:12 + | +LL | #![feature(const_generics)] + | ^^^^^^^^^^^^^^ + +error[E0277]: the trait bound `T: std::marker::Copy` is not satisfied + --> $DIR/issue-61336.rs:9:5 + | +LL | [x; N] + | ^^^^^^ the trait `std::marker::Copy` is not implemented for `T` + | + = help: consider adding a `where T: std::marker::Copy` bound + = note: the `Copy` trait is required because the repeated element will be copied + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/macros/nonterminal-matching.stderr b/src/test/ui/macros/nonterminal-matching.stderr index 5fba8002e1c48..93cc97d45830b 100644 --- a/src/test/ui/macros/nonterminal-matching.stderr +++ b/src/test/ui/macros/nonterminal-matching.stderr @@ -1,6 +1,9 @@ error: no rules expected the token `enum E { }` --> $DIR/nonterminal-matching.rs:19:10 | +LL | macro n(a $nt_item b) { + | --------------------- when calling this macro +... LL | n!(a $nt_item b); | ^^^^^^^^ no rules expected this token in macro call ...