]> git.lizzy.rs Git - rust.git/commitdiff
Auto merge of #61741 - Centril:rollup-fgro5kz, r=Centril
authorbors <bors@rust-lang.org>
Tue, 11 Jun 2019 23:29:20 +0000 (23:29 +0000)
committerbors <bors@rust-lang.org>
Tue, 11 Jun 2019 23:29:20 +0000 (23:29 +0000)
Rollup of 11 pull requests

Successful merges:

 - #61518 (Add loops to doc list of things not stable in const fn)
 - #61526 (move some tests into subfolders)
 - #61550 (Windows 10 SDK is also required now.)
 - #61606 (Remove some legacy proc macro flavors)
 - #61652 (Mention slice patterns in array)
 - #61686 (librustc_errors: Add some more documentation)
 - #61698 (typeck: Fix const generic in repeat param ICE.)
 - #61707 (Azure: retry failed awscli installs)
 - #61715 (make sure make_ascii_lowercase actually leaves upper-case non-ASCII characters alone)
 - #61724 (core: use memcmp optimization for 128 bit integer slices)
 - #61726 (Use `for_each` in `Iterator::partition`)

Failed merges:

r? @ghost

54 files changed:
.azure-pipelines/steps/run.yml
README.md
src/libcore/iter/traits/iterator.rs
src/libcore/slice/mod.rs
src/libcore/str/mod.rs
src/librustc/session/config.rs
src/librustc_errors/diagnostic_builder.rs
src/librustc_errors/emitter.rs
src/librustc_errors/lib.rs
src/librustc_metadata/creader.rs
src/librustc_metadata/cstore_impl.rs
src/librustc_mir/transform/qualify_min_const_fn.rs
src/librustc_plugin/registry.rs
src/librustc_resolve/macros.rs
src/librustc_typeck/astconv.rs
src/librustc_typeck/check/mod.rs
src/librustdoc/clean/inline.rs
src/librustdoc/passes/collect_intra_doc_links.rs
src/libstd/primitive_docs.rs
src/libsyntax/ext/base.rs
src/libsyntax/ext/expand.rs
src/libsyntax/ext/tt/macro_rules.rs
src/libsyntax_ext/deriving/mod.rs
src/libsyntax_ext/lib.rs
src/test/codegen/exact_div.rs [deleted file]
src/test/codegen/intrinsics/exact_div.rs [new file with mode: 0644]
src/test/codegen/intrinsics/likely.rs [new file with mode: 0644]
src/test/codegen/intrinsics/move-val-init.rs [new file with mode: 0644]
src/test/codegen/intrinsics/nontemporal.rs [new file with mode: 0644]
src/test/codegen/intrinsics/prefetch.rs [new file with mode: 0644]
src/test/codegen/intrinsics/unchecked_math.rs [new file with mode: 0644]
src/test/codegen/likely.rs [deleted file]
src/test/codegen/move-val-init.rs [deleted file]
src/test/codegen/nontemporal.rs [deleted file]
src/test/codegen/prefetch.rs [deleted file]
src/test/codegen/unchecked_math.rs [deleted file]
src/test/run-pass-fulldeps/auxiliary/custom-derive-partial-eq.rs [deleted file]
src/test/run-pass-fulldeps/auxiliary/custom-derive-plugin-attr.rs [deleted file]
src/test/run-pass-fulldeps/auxiliary/custom-derive-plugin.rs [deleted file]
src/test/run-pass-fulldeps/auxiliary/plugin-args.rs
src/test/run-pass-fulldeps/custom-derive-partial-eq.rs [deleted file]
src/test/run-pass-fulldeps/derive-totalsum-attr.rs [deleted file]
src/test/run-pass-fulldeps/derive-totalsum.rs [deleted file]
src/test/run-pass-fulldeps/issue-40663.rs [deleted file]
src/test/ui/const-generics/issue-61336-1.rs [new file with mode: 0644]
src/test/ui/const-generics/issue-61336-1.stderr [new file with mode: 0644]
src/test/ui/const-generics/issue-61336.rs [new file with mode: 0644]
src/test/ui/const-generics/issue-61336.stderr [new file with mode: 0644]
src/test/ui/consts/min_const_fn/min_const_fn.nll.stderr
src/test/ui/consts/min_const_fn/min_const_fn.rs
src/test/ui/consts/min_const_fn/min_const_fn.stderr
src/test/ui/consts/single_variant_match_ice.rs
src/test/ui/consts/single_variant_match_ice.stderr
src/test/ui/macros/nonterminal-matching.stderr

index a646b34fe7d024adb4cf8f4ba1dbfa967c326e44..49bac629e7285a028c57b55baa702e7255b965dd 100644 (file)
@@ -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'))
index b522b161ecf939d23c877e6448ddcd88cb6bef4d..15d09f4aada3b0090780252a39f96eddb026c7ed 100644 (file)
--- 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”.)
index d0fdd79473e6726eaf0cc48ffff0beb79e761822..30923c7414504c1a6863d9b50cec569c668ac430 100644 (file)
@@ -1495,13 +1495,13 @@ fn partition<B, F>(self, mut f: F) -> (B, B) where
         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)
     }
index 0e782bef39dd8ee6b4dd011f6df94da6369dee3a..c9c73f4d66ee9f85fe63f756fa8c6233dc558bcc 100644 (file)
@@ -5420,7 +5420,7 @@ impl $traitname for $ty { }
 }
 
 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> {
index 8a128b0d5e7b228075cd1627b7016a2e7e3ef84f..34f2d8917ea472a9f5d25af24e3875448378bedf 100644 (file)
@@ -4000,11 +4000,11 @@ pub fn make_ascii_uppercase(&mut self) {
     /// # 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üÃ\9fe, jürgen ❤", s);
+    /// assert_eq!("grÃ\9cÃ\9fe, jÃ\9crgen ❤", s);
     /// ```
     #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
     pub fn make_ascii_lowercase(&mut self) {
index 6a03aa64d26d19d175ce252dc5ae517e33aa178a..f4d523b92338ce95de4a255b37642c396fffdf40 100644 (file)
@@ -227,13 +227,17 @@ pub fn extension(&self) -> &'static str {
     }
 }
 
+/// 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,
     },
 }
index 31f697a724a0357385bfb81487c7684c32f84041..fc74e43ff5739e770ec056b8edd45a84acdd18ae 100644 (file)
@@ -348,7 +348,7 @@ pub fn new(handler: &'a Handler, level: Level, message: &str) -> DiagnosticBuild
 
     /// 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<DiagnosticId>,
                          message: &str)
index 3bf477efe35f91f05eb08e4bedb02ba8cb596ed9..fca8298409a61f5add93a7a787e6c4f6ba04cda2 100644 (file)
@@ -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};
index 27bd30e8afd89762417551986f598c5631830f7e..05cee6dff230935626a535485da859ad0cf1011f 100644 (file)
@@ -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)]
index 991bebc647d0f7ca48822c1af358f2010ba1c2e7..7ffba41e2569a4f32e3077e4622ffc9e17596fa2 100644 (file)
@@ -614,7 +614,7 @@ fn load_derive_macros(&mut self, root: &CrateRoot<'_>, dylib: Option<PathBuf>, s
             match decl {
                 ProcMacro::CustomDerive { trait_name, attributes, client } => {
                     let attrs = attributes.iter().cloned().map(Symbol::intern).collect::<Vec<_>>();
-                    (trait_name, SyntaxExtension::ProcMacroDerive(
+                    (trait_name, SyntaxExtension::Derive(
                         Box::new(ProcMacroDerive {
                             client,
                             attrs: attrs.clone(),
@@ -624,13 +624,13 @@ fn load_derive_macros(&mut self, root: &CrateRoot<'_>, dylib: Option<PathBuf>, s
                     ))
                 }
                 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,
index db452bb4ac7bcbad232534fa8141fff760a1df96..35faa1df82b845f3a4ef0cf18b1a86cae2d174b3 100644 (file)
@@ -430,7 +430,7 @@ pub fn load_macro_untracked(&self, id: DefId, sess: &Session) -> LoadedMacro {
             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,
index f96675864562f3b410773183e4dadf0ba255e4eb..7bafef79acd1a48ef5e18ce9ff6d5e3c4aea0b2b 100644 (file)
@@ -299,7 +299,7 @@ fn check_terminator(
 
         TerminatorKind::FalseEdges { .. } | TerminatorKind::SwitchInt { .. } => Err((
             span,
-            "`if`, `match`, `&&` and `||` are not stable in const fn".into(),
+            "loops and conditional expressions are not stable in const fn".into(),
         )),
         | TerminatorKind::Abort | TerminatorKind::Unreachable => {
             Err((span, "const fn with unreachable code is not stable".into()))
index 2ed6f868fa1ee7cd818a675eaea810b59cbb5b1e..dd5e42684c4276581471ff68738e55078e4c8e44 100644 (file)
@@ -4,8 +4,9 @@
 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 @@ pub fn args<'b>(&'b self) -> &'b [ast::NestedMetaItem] {
     /// 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,
index 08ab5b853252255e996d7fab640b3b5d264731f0..2369bddf4f75fca13ae27304aa474f65e4dc9c21 100644 (file)
@@ -242,8 +242,7 @@ fn resolve_macro_path(&mut self, path: &ast::Path, kind: MacroKind, invoc_id: Ma
     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 @@ struct Flags: u8 {
                         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),
index 63d9f0920cc7b3f7a88afd0fb839b7ed970c0a6f..5a46c9d440b5d82bb1378d636ed8fc8201409b93 100644 (file)
@@ -2155,6 +2155,17 @@ pub fn ast_ty_to_ty(&self, ast_ty: &hir::Ty) -> Ty<'tcx> {
         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<DefId> {
+        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 @@ pub fn ast_const_to_const(
             }
         }
 
-        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_)
     }
index 2e53b380cb71a6b8441b4db009c22d0b424be192..e35df6cd494a2fbfbb8a251d4d0c10b0eb0573e5 100644 (file)
@@ -2504,6 +2504,11 @@ pub fn to_ty_saving_user_provided_ty(&self, ast_ty: &hir::Ty) -> Ty<'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<DefId> {
+        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)
     }
@@ -4479,19 +4484,24 @@ fn check_expr_kind(
             }
             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) => {
index 15108a7dbb91c392836ea59e926961ce55f79721..5a5540e7e38556096e7f0206aa626d407de3d59f 100644 (file)
@@ -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(),
             };
 
index 860ea18a58ad0f8b78aa2bd038d5d6815f4a9e80..7fbfc3e1fc0f4a1030de025ee972c1a7582da564 100644 (file)
@@ -433,7 +433,7 @@ fn macro_resolve(cx: &DocContext<'_>, path_str: &str) -> Option<Res> {
             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")));
                 }
             }
index 42b64d2b5a5ff21c3e655a619bf008b5a7f0236e..e78a5defdf3bb793c06b6a56ddce25a0c0d99632 100644 (file)
@@ -482,8 +482,8 @@ mod prim_pointer { }
 /// an array. Indeed, this provides most of the API for working with arrays.
 /// Slices have a dynamic size and do not coerce to arrays.
 ///
-/// There is no way to move elements out of an array. See [`mem::replace`][replace]
-/// for an alternative.
+/// You can move elements out of an array with a slice pattern. If you want
+/// one element, see [`mem::replace`][replace].
 ///
 /// # Examples
 ///
@@ -525,6 +525,16 @@ mod prim_pointer { }
 /// for x in &array { }
 /// ```
 ///
+/// You can use a slice pattern to move elements out of an array:
+///
+/// ```
+/// fn move_away(_: String) { /* Do interesting things. */ }
+///
+/// let [john, roa] = ["John".to_string(), "Roa".to_string()];
+/// move_away(john);
+/// move_away(roa);
+/// ```
+///
 /// [slice]: primitive.slice.html
 /// [copy]: marker/trait.Copy.html
 /// [clone]: clone/trait.Clone.html
index 61c736662c71e3d09db17455f3044a9e8ac0c3ea..38b7dee40c447f52a09ba554340a4d79cb6481b6 100644 (file)
@@ -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 @@ pub fn derive_allowed(&self) -> bool {
     }
 }
 
-// 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<F> 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 @@ fn visit_mac(&mut self, mac: &mut ast::Mac) {
     }
 }
 
-pub trait IdentMacroExpander {
-    fn expand<'cx>(&self,
-                   cx: &'cx mut ExtCtxt<'_>,
-                   sp: Span,
-                   ident: ast::Ident,
-                   token_tree: Vec<tokenstream::TokenTree>)
-                   -> Box<dyn MacResult+'cx>;
-}
-
-pub type IdentMacroExpanderFn =
-    for<'cx> fn(&'cx mut ExtCtxt<'_>, Span, ast::Ident, Vec<tokenstream::TokenTree>)
-                -> Box<dyn MacResult+'cx>;
-
-impl<F> IdentMacroExpander for F
-    where F : for<'cx> Fn(&'cx mut ExtCtxt<'_>, Span, ast::Ident,
-                          Vec<tokenstream::TokenTree>) -> Box<dyn MacResult+'cx>
-{
-    fn expand<'cx>(&self,
-                   cx: &'cx mut ExtCtxt<'_>,
-                   sp: Span,
-                   ident: ast::Ident,
-                   token_tree: Vec<tokenstream::TokenTree>)
-                   -> Box<dyn MacResult+'cx>
-    {
-        (*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 @@ fn make_ty(self: Box<DummyResult>) -> Option<P<ast::Ty>> {
     }
 }
 
-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 @@ pub fn article(self) -> &'static str {
 
 /// 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<dyn MultiItemDecorator + sync::Sync + sync::Send>),
-
-    /// A syntax extension that is attached to an item and modifies it
-    /// in-place. Also allows decoration, i.e., creating new items.
-    MultiModifier(Box<dyn MultiItemModifier + sync::Sync + sync::Send>),
-
-    /// A function-like procedural macro. TokenStream -> TokenStream.
-    ProcMacro {
+    /// A token-based function-like macro.
+    Bang {
+        /// An expander with signature TokenStream -> TokenStream.
         expander: Box<dyn ProcMacro + sync::Sync + sync::Send>,
-        /// 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<Lrc<[Symbol]>>,
+        /// 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<dyn AttrProcMacro + sync::Sync + sync::Send>, 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<dyn TTMacroExpander + sync::Sync + sync::Send>,
+        /// 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<Lrc<[Symbol]>>,
-        /// 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<dyn IdentMacroExpander + sync::Sync + sync::Send>,
-        span: Option<Span>,
-        allow_internal_unstable: Option<Lrc<[Symbol]>>,
+    /// 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<dyn AttrProcMacro + sync::Sync + sync::Send>,
+        /// 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<dyn MultiItemModifier + sync::Sync + sync::Send>,
+    ),
+
+    /// 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<dyn MultiItemModifier + sync::Sync + sync::Send>,
-                    Vec<Symbol> /* 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<dyn TTMacroExpander + sync::Sync + sync::Send>,
-        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<dyn MultiItemModifier + sync::Sync + sync::Send>,
+        /// Names of helper attributes registered by this macro.
+        Vec<Symbol>,
+        /// 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<dyn MultiItemModifier + sync::Sync + sync::Send>,
+    ),
 }
 
 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,
         }
     }
 }
index 9960539555332dd99bd18b638c5b33d3a49bc97d..084d4fd3820172258374abbf414471d5a82fb624 100644 (file)
@@ -389,7 +389,7 @@ fn expand_fragment(&mut self, input_fragment: AstFragment) -> AstFragment {
                         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 @@ fn expand_attr_invoc(&mut self,
             _ => 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 @@ fn expand_attr_invoc(&mut self,
         });
 
         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 @@ fn expand_attr_invoc(&mut self,
                 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 @@ fn expand_bang_invoc(&mut self,
         };
 
         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 @@ fn expand_bang_invoc(&mut self,
                 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 @@ fn expand_bang_invoc(&mut self,
                 }
             }
 
-            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 @@ fn expand_derive_invoc(&mut self,
             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))
             }
             _ => {
index 6f82f5094651ea5c4beca1f5bf0f18d3e3897b0b..5dbf21867afa6df02811e60f539ef32559878ec2 100644 (file)
@@ -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::<Vec<Symbol>>().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::<Vec<Symbol>>().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,
     }
 }
 
index ac41f30e6b39fafd57748a06c5010d50588bda8d..cf54eacc3d46c8d715218c557f79a9c603750881 100644 (file)
@@ -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;
 #[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<Annotatable> {
+        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 @@ pub fn register_builtin_derives(resolver: &mut dyn Resolver) {
             $(
                 resolver.add_builtin(
                     ast::Ident::with_empty_ctxt(Symbol::intern($name)),
-                    Lrc::new(SyntaxExtension::BuiltinDerive($func))
+                    Lrc::new(SyntaxExtension::LegacyDerive(Box::new(BuiltinDerive($func))))
                 );
             )*
         }
index 1627f99f616ff9bc4cf51da0bc5e93df3bdd15ff..3dd17207cb8e93ed6d41e2122771a269b9115d60 100644 (file)
@@ -42,7 +42,9 @@
 
 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};
 
@@ -57,9 +59,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,
@@ -94,15 +97,16 @@ macro_rules! register {
         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,
@@ -110,9 +114,10 @@ macro_rules! register {
                 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/test/codegen/exact_div.rs b/src/test/codegen/exact_div.rs
deleted file mode 100644 (file)
index 6a55b49..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-// compile-flags: -C no-prepopulate-passes
-
-#![crate_type = "lib"]
-#![feature(core_intrinsics)]
-
-use std::intrinsics::exact_div;
-
-// CHECK-LABEL: @exact_sdiv
-#[no_mangle]
-pub unsafe fn exact_sdiv(x: i32, y: i32) -> i32 {
-// 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
-    exact_div(x, y)
-}
diff --git a/src/test/codegen/intrinsics/exact_div.rs b/src/test/codegen/intrinsics/exact_div.rs
new file mode 100644 (file)
index 0000000..68eaa39
--- /dev/null
@@ -0,0 +1,20 @@
+// compile-flags: -C no-prepopulate-passes
+
+#![crate_type = "lib"]
+#![feature(core_intrinsics)]
+
+use std::intrinsics::exact_div;
+
+// CHECK-LABEL: @exact_sdiv
+#[no_mangle]
+pub unsafe fn exact_sdiv(x: i32, y: i32) -> i32 {
+    // 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
+    exact_div(x, y)
+}
diff --git a/src/test/codegen/intrinsics/likely.rs b/src/test/codegen/intrinsics/likely.rs
new file mode 100644 (file)
index 0000000..c5a0185
--- /dev/null
@@ -0,0 +1,30 @@
+// compile-flags: -C no-prepopulate-passes
+
+#![crate_type = "lib"]
+#![feature(core_intrinsics)]
+
+use std::intrinsics::{likely,unlikely};
+
+#[no_mangle]
+pub fn check_likely(x: i32, y: i32) -> Option<i32> {
+    unsafe {
+        // CHECK: call i1 @llvm.expect.i1(i1 %{{.*}}, i1 true)
+        if likely(x == y) {
+            None
+        } else {
+            Some(x + y)
+        }
+    }
+}
+
+#[no_mangle]
+pub fn check_unlikely(x: i32, y: i32) -> Option<i32> {
+    unsafe {
+        // CHECK: call i1 @llvm.expect.i1(i1 %{{.*}}, i1 false)
+        if unlikely(x == y) {
+            None
+        } else {
+            Some(x + y)
+        }
+    }
+}
diff --git a/src/test/codegen/intrinsics/move-val-init.rs b/src/test/codegen/intrinsics/move-val-init.rs
new file mode 100644 (file)
index 0000000..6222536
--- /dev/null
@@ -0,0 +1,19 @@
+// compile-flags: -C no-prepopulate-passes
+
+#![feature(core_intrinsics)]
+#![crate_type = "lib"]
+
+// test that `move_val_init` actually avoids big allocas
+
+use std::intrinsics::move_val_init;
+
+pub struct Big {
+    pub data: [u8; 65536]
+}
+
+// CHECK-LABEL: @test_mvi
+#[no_mangle]
+pub unsafe fn test_mvi(target: *mut Big, make_big: fn() -> Big) {
+    // CHECK: call void %make_big(%Big*{{[^%]*}} %target)
+    move_val_init(target, make_big());
+}
diff --git a/src/test/codegen/intrinsics/nontemporal.rs b/src/test/codegen/intrinsics/nontemporal.rs
new file mode 100644 (file)
index 0000000..3a41fb4
--- /dev/null
@@ -0,0 +1,13 @@
+// compile-flags: -O
+
+#![feature(core_intrinsics)]
+#![crate_type = "lib"]
+
+#[no_mangle]
+pub fn a(a: &mut u32, b: u32) {
+    // CHECK-LABEL: define void @a
+    // CHECK: store i32 %b, i32* %a, align 4, !nontemporal
+    unsafe {
+        std::intrinsics::nontemporal_store(a, b);
+    }
+}
diff --git a/src/test/codegen/intrinsics/prefetch.rs b/src/test/codegen/intrinsics/prefetch.rs
new file mode 100644 (file)
index 0000000..4cd38e1
--- /dev/null
@@ -0,0 +1,63 @@
+// compile-flags: -C no-prepopulate-passes
+
+#![crate_type = "lib"]
+#![feature(core_intrinsics)]
+
+use std::intrinsics::{prefetch_read_data, prefetch_write_data,
+                      prefetch_read_instruction, prefetch_write_instruction};
+
+#[no_mangle]
+pub fn check_prefetch_read_data(data: &[i8]) {
+    unsafe {
+        // CHECK: call void @llvm.prefetch(i8* %{{.*}}, i32 0, i32 0, i32 1)
+        prefetch_read_data(data.as_ptr(), 0);
+        // CHECK: call void @llvm.prefetch(i8* %{{.*}}, i32 0, i32 1, i32 1)
+        prefetch_read_data(data.as_ptr(), 1);
+        // CHECK: call void @llvm.prefetch(i8* %{{.*}}, i32 0, i32 2, i32 1)
+        prefetch_read_data(data.as_ptr(), 2);
+        // CHECK: call void @llvm.prefetch(i8* %{{.*}}, i32 0, i32 3, i32 1)
+        prefetch_read_data(data.as_ptr(), 3);
+    }
+}
+
+#[no_mangle]
+pub fn check_prefetch_write_data(data: &[i8]) {
+    unsafe {
+        // CHECK: call void @llvm.prefetch(i8* %{{.*}}, i32 1, i32 0, i32 1)
+        prefetch_write_data(data.as_ptr(), 0);
+        // CHECK: call void @llvm.prefetch(i8* %{{.*}}, i32 1, i32 1, i32 1)
+        prefetch_write_data(data.as_ptr(), 1);
+        // CHECK: call void @llvm.prefetch(i8* %{{.*}}, i32 1, i32 2, i32 1)
+        prefetch_write_data(data.as_ptr(), 2);
+        // CHECK: call void @llvm.prefetch(i8* %{{.*}}, i32 1, i32 3, i32 1)
+        prefetch_write_data(data.as_ptr(), 3);
+    }
+}
+
+#[no_mangle]
+pub fn check_prefetch_read_instruction(data: &[i8]) {
+    unsafe {
+        // CHECK: call void @llvm.prefetch(i8* %{{.*}}, i32 0, i32 0, i32 0)
+        prefetch_read_instruction(data.as_ptr(), 0);
+        // CHECK: call void @llvm.prefetch(i8* %{{.*}}, i32 0, i32 1, i32 0)
+        prefetch_read_instruction(data.as_ptr(), 1);
+        // CHECK: call void @llvm.prefetch(i8* %{{.*}}, i32 0, i32 2, i32 0)
+        prefetch_read_instruction(data.as_ptr(), 2);
+        // CHECK: call void @llvm.prefetch(i8* %{{.*}}, i32 0, i32 3, i32 0)
+        prefetch_read_instruction(data.as_ptr(), 3);
+    }
+}
+
+#[no_mangle]
+pub fn check_prefetch_write_instruction(data: &[i8]) {
+    unsafe {
+        // CHECK: call void @llvm.prefetch(i8* %{{.*}}, i32 1, i32 0, i32 0)
+        prefetch_write_instruction(data.as_ptr(), 0);
+        // CHECK: call void @llvm.prefetch(i8* %{{.*}}, i32 1, i32 1, i32 0)
+        prefetch_write_instruction(data.as_ptr(), 1);
+        // CHECK: call void @llvm.prefetch(i8* %{{.*}}, i32 1, i32 2, i32 0)
+        prefetch_write_instruction(data.as_ptr(), 2);
+        // CHECK: call void @llvm.prefetch(i8* %{{.*}}, i32 1, i32 3, i32 0)
+        prefetch_write_instruction(data.as_ptr(), 3);
+    }
+}
diff --git a/src/test/codegen/intrinsics/unchecked_math.rs b/src/test/codegen/intrinsics/unchecked_math.rs
new file mode 100644 (file)
index 0000000..419c120
--- /dev/null
@@ -0,0 +1,46 @@
+#![crate_type = "lib"]
+#![feature(core_intrinsics)]
+
+use std::intrinsics::*;
+
+// CHECK-LABEL: @unchecked_add_signed
+#[no_mangle]
+pub unsafe fn unchecked_add_signed(a: i32, b: i32) -> i32 {
+    // CHECK: add nsw
+    unchecked_add(a, b)
+}
+
+// CHECK-LABEL: @unchecked_add_unsigned
+#[no_mangle]
+pub unsafe fn unchecked_add_unsigned(a: u32, b: u32) -> u32 {
+    // CHECK: add nuw
+    unchecked_add(a, b)
+}
+
+// CHECK-LABEL: @unchecked_sub_signed
+#[no_mangle]
+pub unsafe fn unchecked_sub_signed(a: i32, b: i32) -> i32 {
+    // CHECK: sub nsw
+    unchecked_sub(a, b)
+}
+
+// CHECK-LABEL: @unchecked_sub_unsigned
+#[no_mangle]
+pub unsafe fn unchecked_sub_unsigned(a: u32, b: u32) -> u32 {
+    // CHECK: sub nuw
+    unchecked_sub(a, b)
+}
+
+// CHECK-LABEL: @unchecked_mul_signed
+#[no_mangle]
+pub unsafe fn unchecked_mul_signed(a: i32, b: i32) -> i32 {
+    // CHECK: mul nsw
+    unchecked_mul(a, b)
+}
+
+// CHECK-LABEL: @unchecked_mul_unsigned
+#[no_mangle]
+pub unsafe fn unchecked_mul_unsigned(a: u32, b: u32) -> u32 {
+    // CHECK: mul nuw
+    unchecked_mul(a, b)
+}
diff --git a/src/test/codegen/likely.rs b/src/test/codegen/likely.rs
deleted file mode 100644 (file)
index c5a0185..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-// compile-flags: -C no-prepopulate-passes
-
-#![crate_type = "lib"]
-#![feature(core_intrinsics)]
-
-use std::intrinsics::{likely,unlikely};
-
-#[no_mangle]
-pub fn check_likely(x: i32, y: i32) -> Option<i32> {
-    unsafe {
-        // CHECK: call i1 @llvm.expect.i1(i1 %{{.*}}, i1 true)
-        if likely(x == y) {
-            None
-        } else {
-            Some(x + y)
-        }
-    }
-}
-
-#[no_mangle]
-pub fn check_unlikely(x: i32, y: i32) -> Option<i32> {
-    unsafe {
-        // CHECK: call i1 @llvm.expect.i1(i1 %{{.*}}, i1 false)
-        if unlikely(x == y) {
-            None
-        } else {
-            Some(x + y)
-        }
-    }
-}
diff --git a/src/test/codegen/move-val-init.rs b/src/test/codegen/move-val-init.rs
deleted file mode 100644 (file)
index 6222536..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-// compile-flags: -C no-prepopulate-passes
-
-#![feature(core_intrinsics)]
-#![crate_type = "lib"]
-
-// test that `move_val_init` actually avoids big allocas
-
-use std::intrinsics::move_val_init;
-
-pub struct Big {
-    pub data: [u8; 65536]
-}
-
-// CHECK-LABEL: @test_mvi
-#[no_mangle]
-pub unsafe fn test_mvi(target: *mut Big, make_big: fn() -> Big) {
-    // CHECK: call void %make_big(%Big*{{[^%]*}} %target)
-    move_val_init(target, make_big());
-}
diff --git a/src/test/codegen/nontemporal.rs b/src/test/codegen/nontemporal.rs
deleted file mode 100644 (file)
index 3a41fb4..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-// compile-flags: -O
-
-#![feature(core_intrinsics)]
-#![crate_type = "lib"]
-
-#[no_mangle]
-pub fn a(a: &mut u32, b: u32) {
-    // CHECK-LABEL: define void @a
-    // CHECK: store i32 %b, i32* %a, align 4, !nontemporal
-    unsafe {
-        std::intrinsics::nontemporal_store(a, b);
-    }
-}
diff --git a/src/test/codegen/prefetch.rs b/src/test/codegen/prefetch.rs
deleted file mode 100644 (file)
index 4cd38e1..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-// compile-flags: -C no-prepopulate-passes
-
-#![crate_type = "lib"]
-#![feature(core_intrinsics)]
-
-use std::intrinsics::{prefetch_read_data, prefetch_write_data,
-                      prefetch_read_instruction, prefetch_write_instruction};
-
-#[no_mangle]
-pub fn check_prefetch_read_data(data: &[i8]) {
-    unsafe {
-        // CHECK: call void @llvm.prefetch(i8* %{{.*}}, i32 0, i32 0, i32 1)
-        prefetch_read_data(data.as_ptr(), 0);
-        // CHECK: call void @llvm.prefetch(i8* %{{.*}}, i32 0, i32 1, i32 1)
-        prefetch_read_data(data.as_ptr(), 1);
-        // CHECK: call void @llvm.prefetch(i8* %{{.*}}, i32 0, i32 2, i32 1)
-        prefetch_read_data(data.as_ptr(), 2);
-        // CHECK: call void @llvm.prefetch(i8* %{{.*}}, i32 0, i32 3, i32 1)
-        prefetch_read_data(data.as_ptr(), 3);
-    }
-}
-
-#[no_mangle]
-pub fn check_prefetch_write_data(data: &[i8]) {
-    unsafe {
-        // CHECK: call void @llvm.prefetch(i8* %{{.*}}, i32 1, i32 0, i32 1)
-        prefetch_write_data(data.as_ptr(), 0);
-        // CHECK: call void @llvm.prefetch(i8* %{{.*}}, i32 1, i32 1, i32 1)
-        prefetch_write_data(data.as_ptr(), 1);
-        // CHECK: call void @llvm.prefetch(i8* %{{.*}}, i32 1, i32 2, i32 1)
-        prefetch_write_data(data.as_ptr(), 2);
-        // CHECK: call void @llvm.prefetch(i8* %{{.*}}, i32 1, i32 3, i32 1)
-        prefetch_write_data(data.as_ptr(), 3);
-    }
-}
-
-#[no_mangle]
-pub fn check_prefetch_read_instruction(data: &[i8]) {
-    unsafe {
-        // CHECK: call void @llvm.prefetch(i8* %{{.*}}, i32 0, i32 0, i32 0)
-        prefetch_read_instruction(data.as_ptr(), 0);
-        // CHECK: call void @llvm.prefetch(i8* %{{.*}}, i32 0, i32 1, i32 0)
-        prefetch_read_instruction(data.as_ptr(), 1);
-        // CHECK: call void @llvm.prefetch(i8* %{{.*}}, i32 0, i32 2, i32 0)
-        prefetch_read_instruction(data.as_ptr(), 2);
-        // CHECK: call void @llvm.prefetch(i8* %{{.*}}, i32 0, i32 3, i32 0)
-        prefetch_read_instruction(data.as_ptr(), 3);
-    }
-}
-
-#[no_mangle]
-pub fn check_prefetch_write_instruction(data: &[i8]) {
-    unsafe {
-        // CHECK: call void @llvm.prefetch(i8* %{{.*}}, i32 1, i32 0, i32 0)
-        prefetch_write_instruction(data.as_ptr(), 0);
-        // CHECK: call void @llvm.prefetch(i8* %{{.*}}, i32 1, i32 1, i32 0)
-        prefetch_write_instruction(data.as_ptr(), 1);
-        // CHECK: call void @llvm.prefetch(i8* %{{.*}}, i32 1, i32 2, i32 0)
-        prefetch_write_instruction(data.as_ptr(), 2);
-        // CHECK: call void @llvm.prefetch(i8* %{{.*}}, i32 1, i32 3, i32 0)
-        prefetch_write_instruction(data.as_ptr(), 3);
-    }
-}
diff --git a/src/test/codegen/unchecked_math.rs b/src/test/codegen/unchecked_math.rs
deleted file mode 100644 (file)
index 419c120..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-#![crate_type = "lib"]
-#![feature(core_intrinsics)]
-
-use std::intrinsics::*;
-
-// CHECK-LABEL: @unchecked_add_signed
-#[no_mangle]
-pub unsafe fn unchecked_add_signed(a: i32, b: i32) -> i32 {
-    // CHECK: add nsw
-    unchecked_add(a, b)
-}
-
-// CHECK-LABEL: @unchecked_add_unsigned
-#[no_mangle]
-pub unsafe fn unchecked_add_unsigned(a: u32, b: u32) -> u32 {
-    // CHECK: add nuw
-    unchecked_add(a, b)
-}
-
-// CHECK-LABEL: @unchecked_sub_signed
-#[no_mangle]
-pub unsafe fn unchecked_sub_signed(a: i32, b: i32) -> i32 {
-    // CHECK: sub nsw
-    unchecked_sub(a, b)
-}
-
-// CHECK-LABEL: @unchecked_sub_unsigned
-#[no_mangle]
-pub unsafe fn unchecked_sub_unsigned(a: u32, b: u32) -> u32 {
-    // CHECK: sub nuw
-    unchecked_sub(a, b)
-}
-
-// CHECK-LABEL: @unchecked_mul_signed
-#[no_mangle]
-pub unsafe fn unchecked_mul_signed(a: i32, b: i32) -> i32 {
-    // CHECK: mul nsw
-    unchecked_mul(a, b)
-}
-
-// CHECK-LABEL: @unchecked_mul_unsigned
-#[no_mangle]
-pub unsafe fn unchecked_mul_unsigned(a: u32, b: u32) -> u32 {
-    // CHECK: mul nuw
-    unchecked_mul(a, b)
-}
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 (file)
index 4d6ff47..0000000
+++ /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<Expr> {
-        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 (file)
index c6b33fb..0000000
+++ /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<ast::Expr> {
-    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 (file)
index 874a0ec..0000000
+++ /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)
-}
index 096701bd9b3ed4b4a56157d833626f608fb75d9a..330459fc08f551cfdb9b099c46009898458cd1fd 100644 (file)
 
 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 @@ fn expand<'cx>(&self,
                    ecx: &'cx mut ExtCtxt,
                    sp: Span,
                    _: TokenStream,
-                   _: Option<Span>) -> Box<MacResult+'cx> {
+                   _: Option<Span>) -> Box<dyn MacResult+'cx> {
         let args = self.args.iter().map(|i| pprust::meta_list_item_to_string(i))
             .collect::<Vec<_>>().join(", ");
         MacEager::expr(ecx.expr_str(sp, Symbol::intern(&args)))
@@ -40,9 +39,10 @@ fn expand<'cx>(&self,
 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 (file)
index ac8fff4..0000000
+++ /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 (file)
index 38eaa71..0000000
+++ /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 (file)
index 2b0bb51..0000000
+++ /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 (file)
index 133f630..0000000
+++ /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 (file)
index 0000000..5b5e431
--- /dev/null
@@ -0,0 +1,12 @@
+#![feature(const_generics)]
+//~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash
+
+fn f<T: Copy, const N: usize>(x: T) -> [T; N] {
+    [x; N]
+    //~^ ERROR array lengths can't depend on generic parameters
+}
+
+fn main() {
+    let x: [u32; 5] = f::<u32, 5>(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 (file)
index 0000000..1a5bb9f
--- /dev/null
@@ -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 (file)
index 0000000..9593037
--- /dev/null
@@ -0,0 +1,16 @@
+#![feature(const_generics)]
+//~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash
+
+fn f<T: Copy, const N: usize>(x: T) -> [T; N] {
+    [x; N]
+}
+
+fn g<T, const N: usize>(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::<u32, 5>(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 (file)
index 0000000..9939a59
--- /dev/null
@@ -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`.
index 7a10c469c51a0c2dbc985eea14af9c65638ee19d..abbdb4ab632dc2d7a2956d00be7ef452f82e2982 100644 (file)
@@ -160,7 +160,7 @@ LL | const fn foo30_2_with_unsafe(x: *mut u32) -> usize { unsafe { x as usize }
    = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563
    = help: add #![feature(const_fn)] to the crate attributes to enable
 
-error[E0723]: `if`, `match`, `&&` and `||` are not stable in const fn
+error[E0723]: loops and conditional expressions are not stable in const fn
   --> $DIR/min_const_fn.rs:100:38
    |
 LL | const fn foo30_4(b: bool) -> usize { if b { 1 } else { 42 } }
@@ -169,7 +169,7 @@ LL | const fn foo30_4(b: bool) -> usize { if b { 1 } else { 42 } }
    = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563
    = help: add #![feature(const_fn)] to the crate attributes to enable
 
-error[E0723]: `if`, `match`, `&&` and `||` are not stable in const fn
+error[E0723]: loops and conditional expressions are not stable in const fn
   --> $DIR/min_const_fn.rs:102:29
    |
 LL | const fn foo30_5(b: bool) { while b { } }
@@ -178,7 +178,7 @@ LL | const fn foo30_5(b: bool) { while b { } }
    = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563
    = help: add #![feature(const_fn)] to the crate attributes to enable
 
-error[E0723]: `if`, `match`, `&&` and `||` are not stable in const fn
+error[E0723]: loops and conditional expressions are not stable in const fn
   --> $DIR/min_const_fn.rs:104:44
    |
 LL | const fn foo36(a: bool, b: bool) -> bool { a && b }
@@ -187,7 +187,7 @@ LL | const fn foo36(a: bool, b: bool) -> bool { a && b }
    = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563
    = help: add #![feature(const_fn)] to the crate attributes to enable
 
-error[E0723]: `if`, `match`, `&&` and `||` are not stable in const fn
+error[E0723]: loops and conditional expressions are not stable in const fn
   --> $DIR/min_const_fn.rs:106:44
    |
 LL | const fn foo37(a: bool, b: bool) -> bool { a || b }
index 96b6057c8fd2d571f3e7e144961a9c503774e866..40e7107e4a15e1654309a068a612819d59d0e576 100644 (file)
@@ -98,13 +98,13 @@ const fn foo30_2(x: *mut u32) -> usize { x as usize }
 const fn foo30_2_with_unsafe(x: *mut u32) -> usize { unsafe { x as usize } }
 //~^ ERROR casting pointers to ints is unstable
 const fn foo30_4(b: bool) -> usize { if b { 1 } else { 42 } }
-//~^ ERROR `if`, `match`, `&&` and `||` are not stable in const fn
+//~^ ERROR loops and conditional expressions are not stable in const fn
 const fn foo30_5(b: bool) { while b { } } //~ ERROR not stable in const fn
 const fn foo30_6() -> bool { let x = true; x }
 const fn foo36(a: bool, b: bool) -> bool { a && b }
-//~^ ERROR `if`, `match`, `&&` and `||` are not stable in const fn
+//~^ ERROR loops and conditional expressions are not stable in const fn
 const fn foo37(a: bool, b: bool) -> bool { a || b }
-//~^ ERROR `if`, `match`, `&&` and `||` are not stable in const fn
+//~^ ERROR loops and conditional expressions are not stable in const fn
 const fn inc(x: &mut i32) { *x += 1 }
 //~^ ERROR mutable references in const fn are unstable
 
index e388b443d23445d95f3e40a1de8278649d894c64..28a5ffb2015945ecefd3c7aea04d668b614c004e 100644 (file)
@@ -160,7 +160,7 @@ LL | const fn foo30_2_with_unsafe(x: *mut u32) -> usize { unsafe { x as usize }
    = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563
    = help: add #![feature(const_fn)] to the crate attributes to enable
 
-error[E0723]: `if`, `match`, `&&` and `||` are not stable in const fn
+error[E0723]: loops and conditional expressions are not stable in const fn
   --> $DIR/min_const_fn.rs:100:38
    |
 LL | const fn foo30_4(b: bool) -> usize { if b { 1 } else { 42 } }
@@ -169,7 +169,7 @@ LL | const fn foo30_4(b: bool) -> usize { if b { 1 } else { 42 } }
    = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563
    = help: add #![feature(const_fn)] to the crate attributes to enable
 
-error[E0723]: `if`, `match`, `&&` and `||` are not stable in const fn
+error[E0723]: loops and conditional expressions are not stable in const fn
   --> $DIR/min_const_fn.rs:102:29
    |
 LL | const fn foo30_5(b: bool) { while b { } }
@@ -178,7 +178,7 @@ LL | const fn foo30_5(b: bool) { while b { } }
    = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563
    = help: add #![feature(const_fn)] to the crate attributes to enable
 
-error[E0723]: `if`, `match`, `&&` and `||` are not stable in const fn
+error[E0723]: loops and conditional expressions are not stable in const fn
   --> $DIR/min_const_fn.rs:104:44
    |
 LL | const fn foo36(a: bool, b: bool) -> bool { a && b }
@@ -187,7 +187,7 @@ LL | const fn foo36(a: bool, b: bool) -> bool { a && b }
    = note: for more information, see issue https://github.com/rust-lang/rust/issues/57563
    = help: add #![feature(const_fn)] to the crate attributes to enable
 
-error[E0723]: `if`, `match`, `&&` and `||` are not stable in const fn
+error[E0723]: loops and conditional expressions are not stable in const fn
   --> $DIR/min_const_fn.rs:106:44
    |
 LL | const fn foo37(a: bool, b: bool) -> bool { a || b }
index 79dde3c18e8fa995ed58414fb85beb8dec9a39b1..6002506689e12c8cb3a0a55e57d1637bd7db0643 100644 (file)
@@ -15,7 +15,7 @@ pub const fn as_val(&self) -> u8 {
         use self::Foo::*;
 
         match *self {
-            Prob => 0x1, //~ ERROR `if`, `match`, `&&` and `||` are not stable in const fn
+            Prob => 0x1, //~ ERROR loops and conditional expressions are not stable in const fn
         }
     }
 }
index b8ad775f1c34fb2c6025e82fd351439d1b045637..1e092c8af99674bdc8ddaa7468ead797dd74a0af 100644 (file)
@@ -10,7 +10,7 @@ error[E0019]: constant contains unimplemented expression type
 LL |     x => 42,
    |     ^
 
-error[E0723]: `if`, `match`, `&&` and `||` are not stable in const fn
+error[E0723]: loops and conditional expressions are not stable in const fn
   --> $DIR/single_variant_match_ice.rs:18:13
    |
 LL |             Prob => 0x1,
index 5fba8002e1c488ca4bba2616eff19fb21c47efbc..93cc97d45830b2a9ae9a651c535eb272fb4be198 100644 (file)
@@ -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
 ...