From eaffdae3006ed0386f21dc31c499ffea24c32c98 Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Sat, 3 Apr 2021 03:08:31 +0200 Subject: Allow `,` to delimit macro 2.0 rules --- crates/mbe/src/lib.rs | 6 ++++-- crates/mbe/src/tests/expand.rs | 15 +++++++++++++++ crates/mbe/src/tt_iter.rs | 11 +++++++++++ 3 files changed, 30 insertions(+), 2 deletions(-) (limited to 'crates') diff --git a/crates/mbe/src/lib.rs b/crates/mbe/src/lib.rs index e74f8cf3f..3af5bc18b 100644 --- a/crates/mbe/src/lib.rs +++ b/crates/mbe/src/lib.rs @@ -220,9 +220,11 @@ impl MacroDef { while src.len() > 0 { let rule = Rule::parse(&mut src, true)?; rules.push(rule); - if let Err(()) = src.expect_char(';') { + if let Err(()) = src.expect_any_char(&[';', ',']) { if src.len() > 0 { - return Err(ParseError::Expected("expected `;`".to_string())); + return Err(ParseError::Expected( + "expected `;` or `,` to delimit rules".to_string(), + )); } break; } diff --git a/crates/mbe/src/tests/expand.rs b/crates/mbe/src/tests/expand.rs index 8951f3813..e02d038b6 100644 --- a/crates/mbe/src/tests/expand.rs +++ b/crates/mbe/src/tests/expand.rs @@ -662,6 +662,21 @@ macro foo { .assert_expand_items("foo!(bar);", "fn bar () {}"); } +#[test] +fn test_macro_2_0_panic_2015() { + parse_macro2( + r#" +macro panic_2015 { + () => ( + ), + (bar) => ( + ), +} +"#, + ) + .assert_expand_items("panic_2015!(bar);", ""); +} + #[test] fn test_path() { parse_macro( diff --git a/crates/mbe/src/tt_iter.rs b/crates/mbe/src/tt_iter.rs index 319a40f2a..195b8cf30 100644 --- a/crates/mbe/src/tt_iter.rs +++ b/crates/mbe/src/tt_iter.rs @@ -34,6 +34,17 @@ impl<'a> TtIter<'a> { } } + pub(crate) fn expect_any_char(&mut self, chars: &[char]) -> Result<(), ()> { + match self.next() { + Some(tt::TokenTree::Leaf(tt::Leaf::Punct(tt::Punct { char: c, .. }))) + if chars.contains(c) => + { + Ok(()) + } + _ => Err(()), + } + } + pub(crate) fn expect_subtree(&mut self) -> Result<&'a tt::Subtree, ()> { match self.next() { Some(tt::TokenTree::Subtree(it)) => Ok(it), -- cgit v1.2.3 From 6198eb74b2947deffa00dcd2e9e38a70f9fe6284 Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Sat, 3 Apr 2021 03:12:55 +0200 Subject: Implement edition-dependent builtin `panic!` macro --- crates/hir_expand/src/builtin_macro.rs | 25 +++++++++++++++++++++++-- crates/hir_expand/src/name.rs | 2 ++ crates/hir_expand/src/quote.rs | 1 + 3 files changed, 26 insertions(+), 2 deletions(-) (limited to 'crates') diff --git a/crates/hir_expand/src/builtin_macro.rs b/crates/hir_expand/src/builtin_macro.rs index 4d52904b9..3aa3d8997 100644 --- a/crates/hir_expand/src/builtin_macro.rs +++ b/crates/hir_expand/src/builtin_macro.rs @@ -1,10 +1,10 @@ //! Builtin macro use crate::{ db::AstDatabase, name, quote, AstId, CrateId, EagerMacroId, LazyMacroId, MacroCallId, - MacroDefId, MacroDefKind, TextSize, + MacroCallLoc, MacroDefId, MacroDefKind, TextSize, }; -use base_db::{AnchoredPath, FileId}; +use base_db::{AnchoredPath, Edition, FileId}; use cfg::CfgExpr; use either::Either; use mbe::{parse_exprs_with_sep, parse_to_token_tree, ExpandResult}; @@ -111,6 +111,8 @@ register_builtin! { (llvm_asm, LlvmAsm) => asm_expand, (asm, Asm) => asm_expand, (cfg, Cfg) => cfg_expand, + (core_panic, CorePanic) => panic_expand, + (std_panic, StdPanic) => panic_expand, EAGER: (compile_error, CompileError) => compile_error_expand, @@ -284,6 +286,25 @@ fn cfg_expand( ExpandResult::ok(expanded) } +fn panic_expand( + db: &dyn AstDatabase, + id: LazyMacroId, + tt: &tt::Subtree, +) -> ExpandResult { + let loc: MacroCallLoc = db.lookup_intern_macro(id); + // Expand to a macro call `$crate::panic::panic_{edition}` + let krate = tt::Ident { text: "$crate".into(), id: tt::TokenId::unspecified() }; + let mut call = if db.crate_graph()[loc.krate].edition == Edition::Edition2021 { + quote!(#krate::panic::panic_2021!) + } else { + quote!(#krate::panic::panic_2015!) + }; + + // Pass the original arguments + call.token_trees.push(tt::TokenTree::Subtree(tt.clone())); + ExpandResult::ok(call) +} + fn unquote_str(lit: &tt::Literal) -> Option { let lit = ast::make::tokens::literal(&lit.to_string()); let token = ast::String::cast(lit)?; diff --git a/crates/hir_expand/src/name.rs b/crates/hir_expand/src/name.rs index 203ebbe85..a0f8766b0 100644 --- a/crates/hir_expand/src/name.rs +++ b/crates/hir_expand/src/name.rs @@ -208,6 +208,8 @@ pub mod known { line, module_path, assert, + core_panic, + std_panic, stringify, concat, include, diff --git a/crates/hir_expand/src/quote.rs b/crates/hir_expand/src/quote.rs index 08bc5aa49..c82487ef0 100644 --- a/crates/hir_expand/src/quote.rs +++ b/crates/hir_expand/src/quote.rs @@ -104,6 +104,7 @@ macro_rules! __quote { ( . ) => {$crate::__quote!(@PUNCT '.')}; ( < ) => {$crate::__quote!(@PUNCT '<')}; ( > ) => {$crate::__quote!(@PUNCT '>')}; + ( ! ) => {$crate::__quote!(@PUNCT '!')}; ( $first:tt $($tail:tt)+ ) => { { -- cgit v1.2.3 From 5742cdf3f1c591709e68d65c5701257cb77583db Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Sat, 3 Apr 2021 03:13:04 +0200 Subject: Support `#[rustc_builtin_macro = "builtin_name"]` --- crates/hir_def/src/nameres/collector.rs | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'crates') diff --git a/crates/hir_def/src/nameres/collector.rs b/crates/hir_def/src/nameres/collector.rs index 6f946a6dd..c8f494707 100644 --- a/crates/hir_def/src/nameres/collector.rs +++ b/crates/hir_def/src/nameres/collector.rs @@ -1402,8 +1402,18 @@ impl ModCollector<'_, '_> { // Case 1: builtin macros if attrs.by_key("rustc_builtin_macro").exists() { + // `#[rustc_builtin_macro = "builtin_name"]` overrides the `macro_rules!` name. + let name; + let name = match attrs.by_key("rustc_builtin_macro").string_value() { + Some(it) => { + // FIXME: a hacky way to create a Name from string. + name = tt::Ident { text: it.clone(), id: tt::TokenId::unspecified() }.as_name(); + &name + } + None => &mac.name, + }; let krate = self.def_collector.def_map.krate; - if let Some(macro_id) = find_builtin_macro(&mac.name, krate, ast_id) { + if let Some(macro_id) = find_builtin_macro(name, krate, ast_id) { self.def_collector.define_macro_rules( self.module_id, mac.name.clone(), -- cgit v1.2.3