about summary refs log tree commit diff
path: root/src/libsyntax_ext
diff options
context:
space:
mode:
authorVadim Petrochenkov <vadim.petrochenkov@gmail.com>2019-06-20 11:52:31 +0300
committerVadim Petrochenkov <vadim.petrochenkov@gmail.com>2019-07-26 13:09:54 +0300
commit8eaf17bca2674293eba0ea10056d5c77b6352086 (patch)
treea726739d50e26b0142be28425b154446f43e4fe5 /src/libsyntax_ext
parent4268e7ee22935f086b856ef0063a9e22b49aeddb (diff)
downloadrust-8eaf17bca2674293eba0ea10056d5c77b6352086.tar.gz
rust-8eaf17bca2674293eba0ea10056d5c77b6352086.zip
Introduce built-in macros through libcore
Diffstat (limited to 'src/libsyntax_ext')
-rw-r--r--src/libsyntax_ext/deriving/mod.rs86
-rw-r--r--src/libsyntax_ext/lib.rs194
-rw-r--r--src/libsyntax_ext/plugin_macro_defs.rs64
-rw-r--r--src/libsyntax_ext/proc_macro_decls.rs6
4 files changed, 129 insertions, 221 deletions
diff --git a/src/libsyntax_ext/deriving/mod.rs b/src/libsyntax_ext/deriving/mod.rs
index e491e93256d..1a865099288 100644
--- a/src/libsyntax_ext/deriving/mod.rs
+++ b/src/libsyntax_ext/deriving/mod.rs
@@ -1,11 +1,7 @@
 //! The compiler code necessary to implement the `#[derive]` extensions.
 
-use rustc_data_structures::sync::Lrc;
 use syntax::ast::{self, MetaItem};
-use syntax::attr::Deprecation;
-use syntax::edition::Edition;
-use syntax::ext::base::{Annotatable, ExtCtxt, Resolver, MultiItemModifier};
-use syntax::ext::base::{SyntaxExtension, SyntaxExtensionKind};
+use syntax::ext::base::{Annotatable, ExtCtxt, MultiItemModifier};
 use syntax::ext::build::AstBuilder;
 use syntax::ptr::P;
 use syntax::symbol::{Symbol, sym};
@@ -43,8 +39,8 @@ pub mod ord;
 
 pub mod generic;
 
-struct BuiltinDerive(
-    fn(&mut ExtCtxt<'_>, Span, &MetaItem, &Annotatable, &mut dyn FnMut(Annotatable))
+crate struct BuiltinDerive(
+    crate fn(&mut ExtCtxt<'_>, Span, &MetaItem, &Annotatable, &mut dyn FnMut(Annotatable))
 );
 
 impl MultiItemModifier for BuiltinDerive {
@@ -60,82 +56,6 @@ impl MultiItemModifier for BuiltinDerive {
     }
 }
 
-macro_rules! derive_traits {
-    ($( [$deprecation:expr] $name:ident => $func:path, )+) => {
-        pub fn is_builtin_trait(name: ast::Name) -> bool {
-            match name {
-                $( sym::$name )|+ => true,
-                _ => false,
-            }
-        }
-
-        pub fn register_builtin_derives(resolver: &mut dyn Resolver, edition: Edition) {
-            let allow_internal_unstable = Some([
-                sym::core_intrinsics,
-                sym::rustc_attrs,
-                Symbol::intern("derive_clone_copy"),
-                Symbol::intern("derive_eq"),
-                Symbol::intern("libstd_sys_internals"), // RustcDeserialize and RustcSerialize
-            ][..].into());
-
-            $(
-                resolver.add_builtin(
-                    ast::Ident::with_empty_ctxt(sym::$name),
-                    Lrc::new(SyntaxExtension {
-                        deprecation: $deprecation.map(|msg| Deprecation {
-                            since: Some(Symbol::intern("1.0.0")),
-                            note: Some(Symbol::intern(msg)),
-                        }),
-                        allow_internal_unstable: allow_internal_unstable.clone(),
-                        ..SyntaxExtension::default(
-                            SyntaxExtensionKind::LegacyDerive(Box::new(BuiltinDerive($func))),
-                            edition,
-                        )
-                    }),
-                );
-            )+
-        }
-    }
-}
-
-derive_traits! {
-    [None]
-    Clone => clone::expand_deriving_clone,
-
-    [None]
-    Hash => hash::expand_deriving_hash,
-
-    [None]
-    RustcEncodable => encodable::expand_deriving_rustc_encodable,
-
-    [None]
-    RustcDecodable => decodable::expand_deriving_rustc_decodable,
-
-    [None]
-    PartialEq => partial_eq::expand_deriving_partial_eq,
-    [None]
-    Eq => eq::expand_deriving_eq,
-    [None]
-    PartialOrd => partial_ord::expand_deriving_partial_ord,
-    [None]
-    Ord => ord::expand_deriving_ord,
-
-    [None]
-    Debug => debug::expand_deriving_debug,
-
-    [None]
-    Default => default::expand_deriving_default,
-
-    [None]
-    Copy => bounds::expand_deriving_copy,
-
-    // deprecated
-    [Some("derive(Encodable) is deprecated in favor of derive(RustcEncodable)")]
-    Encodable => encodable::expand_deriving_encodable,
-    [Some("derive(Decodable) is deprecated in favor of derive(RustcDecodable)")]
-    Decodable => decodable::expand_deriving_decodable,
-}
-
 /// Construct a name for the inner type parameter that can't collide with any type parameters of
 /// the item. This is achieved by starting with a base and then concatenating the names of all
 /// other type parameters.
diff --git a/src/libsyntax_ext/lib.rs b/src/libsyntax_ext/lib.rs
index 400bfe796bb..7940abed245 100644
--- a/src/libsyntax_ext/lib.rs
+++ b/src/libsyntax_ext/lib.rs
@@ -5,19 +5,25 @@
 #![deny(rust_2018_idioms)]
 #![deny(unused_lifetimes)]
 
-#![feature(in_band_lifetimes)]
+#![feature(crate_visibility_modifier)]
+#![feature(decl_macro)]
+#![feature(nll)]
 #![feature(proc_macro_diagnostic)]
 #![feature(proc_macro_internals)]
 #![feature(proc_macro_span)]
-#![feature(decl_macro)]
-#![feature(nll)]
 #![feature(rustc_diagnostic_macros)]
 #![feature(unicode_internals)]
 
-#![recursion_limit="256"]
-
 extern crate proc_macro;
 
+use crate::deriving::*;
+
+use syntax::ast::Ident;
+use syntax::edition::Edition;
+use syntax::ext::base::{SyntaxExtension, SyntaxExtensionKind, MacroExpanderFn};
+use syntax::ext::source_util;
+use syntax::symbol::sym;
+
 mod error_codes;
 
 mod asm;
@@ -38,147 +44,71 @@ mod test_case;
 mod trace_macros;
 
 pub mod deriving;
+pub mod plugin_macro_defs;
 pub mod proc_macro_decls;
 pub mod proc_macro_impl;
 
-use rustc_data_structures::sync::Lrc;
-use syntax::ast;
-use syntax::attr::Stability;
-use syntax::ext::base::MacroExpanderFn;
-use syntax::ext::base::{NamedSyntaxExtension, SyntaxExtension, SyntaxExtensionKind};
-use syntax::edition::Edition;
-use syntax::symbol::{sym, Symbol};
-
-const EXPLAIN_ASM: &str =
-    "inline assembly is not stable enough for use and is subject to change";
-const EXPLAIN_GLOBAL_ASM: &str =
-    "`global_asm!` is not stable enough for use and is subject to change";
-const EXPLAIN_CUSTOM_TEST_FRAMEWORKS: &str =
-    "custom test frameworks are an unstable feature";
-const EXPLAIN_LOG_SYNTAX: &str =
-    "`log_syntax!` is not stable enough for use and is subject to change";
-const EXPLAIN_CONCAT_IDENTS: &str =
-    "`concat_idents` is not stable enough for use and is subject to change";
-const EXPLAIN_FORMAT_ARGS_NL: &str =
-    "`format_args_nl` is only for internal language use and is subject to change";
-const EXPLAIN_TRACE_MACROS: &str =
-    "`trace_macros` is not stable enough for use and is subject to change";
-const EXPLAIN_UNSTABLE_COLUMN: &str =
-    "internal implementation detail of the `column` macro";
-
-pub fn register_builtins(resolver: &mut dyn syntax::ext::base::Resolver,
-                         user_exts: Vec<NamedSyntaxExtension>,
-                         edition: Edition) {
-    deriving::register_builtin_derives(resolver, edition);
-
-    let mut register = |name, ext| {
-        resolver.add_builtin(ast::Ident::with_empty_ctxt(name), Lrc::new(ext));
-    };
-
-    macro_rules! register {
-        ($( $name:ident: $f:expr, )*) => { $(
-            register(sym::$name, SyntaxExtension::default(
-                SyntaxExtensionKind::LegacyBang(Box::new($f as MacroExpanderFn)), edition
-            ));
-        )* }
+pub fn register_builtin_macros(resolver: &mut dyn syntax::ext::base::Resolver, edition: Edition) {
+    let mut register = |name, kind| resolver.register_builtin_macro(
+        Ident::with_empty_ctxt(name), SyntaxExtension {
+            is_builtin: true, ..SyntaxExtension::default(kind, edition)
+        },
+    );
+    macro register_bang($($name:ident: $f:expr,)*) {
+        $(register(sym::$name, SyntaxExtensionKind::LegacyBang(Box::new($f as MacroExpanderFn)));)*
+    }
+    macro register_attr($($name:ident: $f:expr,)*) {
+        $(register(sym::$name, SyntaxExtensionKind::LegacyAttr(Box::new($f)));)*
     }
-    macro_rules! register_unstable {
-        ($( [$feature:expr, $reason:expr, $issue:expr] $name:ident: $f:expr, )*) => { $(
-            register(sym::$name, SyntaxExtension {
-                stability: Some(Stability::unstable(
-                    $feature, Some(Symbol::intern($reason)), $issue
-                )),
-                ..SyntaxExtension::default(
-                    SyntaxExtensionKind::LegacyBang(Box::new($f as MacroExpanderFn)), edition
-                )
-            });
-        )* }
+    macro register_derive($($name:ident: $f:expr,)*) {
+        $(register(sym::$name, SyntaxExtensionKind::LegacyDerive(Box::new(BuiltinDerive($f))));)*
     }
 
-    use syntax::ext::source_util::*;
-    register! {
-        line: expand_line,
-        column: expand_column,
-        file: expand_file,
-        stringify: expand_stringify,
-        include: expand_include,
-        include_str: expand_include_str,
-        include_bytes: expand_include_bytes,
-        module_path: expand_mod,
+    register_bang! {
+        __rust_unstable_column: source_util::expand_column,
+        asm: asm::expand_asm,
+        assert: assert::expand_assert,
         cfg: cfg::expand_cfg,
+        column: source_util::expand_column,
+        compile_error: compile_error::expand_compile_error,
+        concat_idents: concat_idents::expand_syntax_ext,
         concat: concat::expand_syntax_ext,
         env: env::expand_env,
-        option_env: env::expand_option_env,
-        compile_error: compile_error::expand_compile_error,
-        assert: assert::expand_assert,
-    }
-
-    register_unstable! {
-        [sym::__rust_unstable_column, EXPLAIN_UNSTABLE_COLUMN, 0]
-        __rust_unstable_column: expand_column,
-        [sym::asm, EXPLAIN_ASM, 29722]
-        asm: asm::expand_asm,
-        [sym::global_asm, EXPLAIN_GLOBAL_ASM, 35119]
+        file: source_util::expand_file,
+        format_args_nl: format::expand_format_args_nl,
+        format_args: format::expand_format_args,
         global_asm: global_asm::expand_global_asm,
-        [sym::concat_idents, EXPLAIN_CONCAT_IDENTS, 29599]
-        concat_idents: concat_idents::expand_syntax_ext,
-        [sym::log_syntax, EXPLAIN_LOG_SYNTAX, 29598]
+        include_bytes: source_util::expand_include_bytes,
+        include_str: source_util::expand_include_str,
+        include: source_util::expand_include,
+        line: source_util::expand_line,
         log_syntax: log_syntax::expand_syntax_ext,
-        [sym::trace_macros, EXPLAIN_TRACE_MACROS, 29598]
+        module_path: source_util::expand_mod,
+        option_env: env::expand_option_env,
+        stringify: source_util::expand_stringify,
         trace_macros: trace_macros::expand_trace_macros,
     }
 
-    let allow_internal_unstable = Some([sym::test, sym::rustc_attrs][..].into());
-    register(sym::test_case, SyntaxExtension {
-        stability: Some(Stability::unstable(
-            sym::custom_test_frameworks,
-            Some(Symbol::intern(EXPLAIN_CUSTOM_TEST_FRAMEWORKS)),
-            50297,
-        )),
-        allow_internal_unstable: allow_internal_unstable.clone(),
-        ..SyntaxExtension::default(
-            SyntaxExtensionKind::LegacyAttr(Box::new(test_case::expand)), edition
-        )
-    });
-    register(sym::test, SyntaxExtension {
-        allow_internal_unstable: allow_internal_unstable.clone(),
-        ..SyntaxExtension::default(
-            SyntaxExtensionKind::LegacyAttr(Box::new(test::expand_test)), edition
-        )
-    });
-    register(sym::bench, SyntaxExtension {
-        allow_internal_unstable,
-        ..SyntaxExtension::default(
-            SyntaxExtensionKind::LegacyAttr(Box::new(test::expand_bench)), edition
-        )
-    });
-    register(sym::global_allocator, SyntaxExtension {
-        allow_internal_unstable: Some([sym::rustc_attrs][..].into()),
-        ..SyntaxExtension::default(
-            SyntaxExtensionKind::LegacyAttr(Box::new(global_allocator::expand)), edition
-        )
-    });
-
-    let allow_internal_unstable = Some([sym::fmt_internals][..].into());
-    register(sym::format_args, SyntaxExtension {
-        allow_internal_unstable: allow_internal_unstable.clone(),
-        ..SyntaxExtension::default(
-            SyntaxExtensionKind::LegacyBang(Box::new(format::expand_format_args)), edition
-        )
-    });
-    register(sym::format_args_nl, SyntaxExtension {
-        stability: Some(Stability::unstable(
-            sym::format_args_nl,
-            Some(Symbol::intern(EXPLAIN_FORMAT_ARGS_NL)),
-            0,
-        )),
-        allow_internal_unstable,
-        ..SyntaxExtension::default(
-            SyntaxExtensionKind::LegacyBang(Box::new(format::expand_format_args_nl)), edition
-        )
-    });
+    register_attr! {
+        bench: test::expand_bench,
+        global_allocator: global_allocator::expand,
+        test: test::expand_test,
+        test_case: test_case::expand,
+    }
 
-    for (name, ext) in user_exts {
-        register(name, ext);
+    register_derive! {
+        Clone: clone::expand_deriving_clone,
+        Copy: bounds::expand_deriving_copy,
+        Debug: debug::expand_deriving_debug,
+        Decodable: decodable::expand_deriving_decodable,
+        Default: default::expand_deriving_default,
+        Encodable: encodable::expand_deriving_encodable,
+        Eq: eq::expand_deriving_eq,
+        Hash: hash::expand_deriving_hash,
+        Ord: ord::expand_deriving_ord,
+        PartialEq: partial_eq::expand_deriving_partial_eq,
+        PartialOrd: partial_ord::expand_deriving_partial_ord,
+        RustcDecodable: decodable::expand_deriving_rustc_decodable,
+        RustcEncodable: encodable::expand_deriving_rustc_encodable,
     }
 }
diff --git a/src/libsyntax_ext/plugin_macro_defs.rs b/src/libsyntax_ext/plugin_macro_defs.rs
new file mode 100644
index 00000000000..2fd1a42db95
--- /dev/null
+++ b/src/libsyntax_ext/plugin_macro_defs.rs
@@ -0,0 +1,64 @@
+//! Each macro must have a definition, so `#[plugin]` attributes
+//! inject a dummy `macro_rules` item for each macro they define.
+
+use syntax::ast::*;
+use syntax::attr;
+use syntax::edition::Edition;
+use syntax::ext::base::{Resolver, NamedSyntaxExtension};
+use syntax::parse::token;
+use syntax::ptr::P;
+use syntax::source_map::respan;
+use syntax::symbol::sym;
+use syntax::tokenstream::*;
+use syntax_pos::{Span, DUMMY_SP};
+use syntax_pos::hygiene::{ExpnId, ExpnInfo, ExpnKind, MacroKind};
+
+use std::mem;
+
+fn plugin_macro_def(name: Name, span: Span) -> P<Item> {
+    let rustc_builtin_macro = Attribute {
+        id: attr::mk_attr_id(),
+        style: AttrStyle::Outer,
+        path: Path::from_ident(Ident::new(sym::rustc_builtin_macro, span)),
+        tokens: TokenStream::empty(),
+        is_sugared_doc: false,
+        span,
+    };
+
+    let parens: TreeAndJoint = TokenTree::Delimited(
+        DelimSpan::from_single(span), token::Paren, TokenStream::empty()
+    ).into();
+    let trees = vec![parens.clone(), TokenTree::token(token::FatArrow, span).into(), parens];
+
+    P(Item {
+        ident: Ident::new(name, span),
+        attrs: vec![rustc_builtin_macro],
+        id: DUMMY_NODE_ID,
+        node: ItemKind::MacroDef(MacroDef { tokens: TokenStream::new(trees), legacy: true }),
+        vis: respan(span, VisibilityKind::Inherited),
+        span: span,
+        tokens: None,
+    })
+}
+
+pub fn inject(
+    krate: &mut Crate,
+    resolver: &mut dyn Resolver,
+    named_exts: Vec<NamedSyntaxExtension>,
+    edition: Edition,
+) {
+    if !named_exts.is_empty() {
+        let mut extra_items = Vec::new();
+        let span = DUMMY_SP.fresh_expansion(ExpnId::root(), ExpnInfo::allow_unstable(
+            ExpnKind::Macro(MacroKind::Attr, sym::plugin), DUMMY_SP, edition,
+            [sym::rustc_attrs][..].into(),
+        ));
+        for (name, ext) in named_exts {
+            resolver.register_builtin_macro(Ident::with_empty_ctxt(name), ext);
+            extra_items.push(plugin_macro_def(name, span));
+        }
+        // The `macro_rules` items must be inserted before any other items.
+        mem::swap(&mut extra_items, &mut krate.module.items);
+        krate.module.items.append(&mut extra_items);
+    }
+}
diff --git a/src/libsyntax_ext/proc_macro_decls.rs b/src/libsyntax_ext/proc_macro_decls.rs
index 08c40dde56c..303d5f00deb 100644
--- a/src/libsyntax_ext/proc_macro_decls.rs
+++ b/src/libsyntax_ext/proc_macro_decls.rs
@@ -1,7 +1,5 @@
 use std::mem;
 
-use crate::deriving;
-
 use syntax::ast::{self, Ident};
 use syntax::attr;
 use syntax::source_map::{ExpnInfo, ExpnKind, respan};
@@ -136,10 +134,6 @@ impl<'a> CollectProcMacros<'a> {
             self.handler.span_err(trait_attr.span,
                                   &format!("`{}` cannot be a name of derive macro", trait_ident));
         }
-        if deriving::is_builtin_trait(trait_ident.name) {
-            self.handler.span_err(trait_attr.span,
-                                  "cannot override a built-in derive macro");
-        }
 
         let attributes_attr = list.get(1);
         let proc_attrs: Vec<_> = if let Some(attr) = attributes_attr {