aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/hir_def/src/nameres/collector.rs12
-rw-r--r--crates/hir_expand/src/builtin_macro.rs25
-rw-r--r--crates/hir_expand/src/name.rs2
-rw-r--r--crates/hir_expand/src/quote.rs1
-rw-r--r--crates/mbe/src/lib.rs6
-rw-r--r--crates/mbe/src/tests/expand.rs15
-rw-r--r--crates/mbe/src/tt_iter.rs11
7 files changed, 67 insertions, 5 deletions
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<'_, '_> {
1402 1402
1403 // Case 1: builtin macros 1403 // Case 1: builtin macros
1404 if attrs.by_key("rustc_builtin_macro").exists() { 1404 if attrs.by_key("rustc_builtin_macro").exists() {
1405 // `#[rustc_builtin_macro = "builtin_name"]` overrides the `macro_rules!` name.
1406 let name;
1407 let name = match attrs.by_key("rustc_builtin_macro").string_value() {
1408 Some(it) => {
1409 // FIXME: a hacky way to create a Name from string.
1410 name = tt::Ident { text: it.clone(), id: tt::TokenId::unspecified() }.as_name();
1411 &name
1412 }
1413 None => &mac.name,
1414 };
1405 let krate = self.def_collector.def_map.krate; 1415 let krate = self.def_collector.def_map.krate;
1406 if let Some(macro_id) = find_builtin_macro(&mac.name, krate, ast_id) { 1416 if let Some(macro_id) = find_builtin_macro(name, krate, ast_id) {
1407 self.def_collector.define_macro_rules( 1417 self.def_collector.define_macro_rules(
1408 self.module_id, 1418 self.module_id,
1409 mac.name.clone(), 1419 mac.name.clone(),
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 @@
1//! Builtin macro 1//! Builtin macro
2use crate::{ 2use crate::{
3 db::AstDatabase, name, quote, AstId, CrateId, EagerMacroId, LazyMacroId, MacroCallId, 3 db::AstDatabase, name, quote, AstId, CrateId, EagerMacroId, LazyMacroId, MacroCallId,
4 MacroDefId, MacroDefKind, TextSize, 4 MacroCallLoc, MacroDefId, MacroDefKind, TextSize,
5}; 5};
6 6
7use base_db::{AnchoredPath, FileId}; 7use base_db::{AnchoredPath, Edition, FileId};
8use cfg::CfgExpr; 8use cfg::CfgExpr;
9use either::Either; 9use either::Either;
10use mbe::{parse_exprs_with_sep, parse_to_token_tree, ExpandResult}; 10use mbe::{parse_exprs_with_sep, parse_to_token_tree, ExpandResult};
@@ -111,6 +111,8 @@ register_builtin! {
111 (llvm_asm, LlvmAsm) => asm_expand, 111 (llvm_asm, LlvmAsm) => asm_expand,
112 (asm, Asm) => asm_expand, 112 (asm, Asm) => asm_expand,
113 (cfg, Cfg) => cfg_expand, 113 (cfg, Cfg) => cfg_expand,
114 (core_panic, CorePanic) => panic_expand,
115 (std_panic, StdPanic) => panic_expand,
114 116
115 EAGER: 117 EAGER:
116 (compile_error, CompileError) => compile_error_expand, 118 (compile_error, CompileError) => compile_error_expand,
@@ -284,6 +286,25 @@ fn cfg_expand(
284 ExpandResult::ok(expanded) 286 ExpandResult::ok(expanded)
285} 287}
286 288
289fn panic_expand(
290 db: &dyn AstDatabase,
291 id: LazyMacroId,
292 tt: &tt::Subtree,
293) -> ExpandResult<tt::Subtree> {
294 let loc: MacroCallLoc = db.lookup_intern_macro(id);
295 // Expand to a macro call `$crate::panic::panic_{edition}`
296 let krate = tt::Ident { text: "$crate".into(), id: tt::TokenId::unspecified() };
297 let mut call = if db.crate_graph()[loc.krate].edition == Edition::Edition2021 {
298 quote!(#krate::panic::panic_2021!)
299 } else {
300 quote!(#krate::panic::panic_2015!)
301 };
302
303 // Pass the original arguments
304 call.token_trees.push(tt::TokenTree::Subtree(tt.clone()));
305 ExpandResult::ok(call)
306}
307
287fn unquote_str(lit: &tt::Literal) -> Option<String> { 308fn unquote_str(lit: &tt::Literal) -> Option<String> {
288 let lit = ast::make::tokens::literal(&lit.to_string()); 309 let lit = ast::make::tokens::literal(&lit.to_string());
289 let token = ast::String::cast(lit)?; 310 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 {
208 line, 208 line,
209 module_path, 209 module_path,
210 assert, 210 assert,
211 core_panic,
212 std_panic,
211 stringify, 213 stringify,
212 concat, 214 concat,
213 include, 215 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 {
104 ( . ) => {$crate::__quote!(@PUNCT '.')}; 104 ( . ) => {$crate::__quote!(@PUNCT '.')};
105 ( < ) => {$crate::__quote!(@PUNCT '<')}; 105 ( < ) => {$crate::__quote!(@PUNCT '<')};
106 ( > ) => {$crate::__quote!(@PUNCT '>')}; 106 ( > ) => {$crate::__quote!(@PUNCT '>')};
107 ( ! ) => {$crate::__quote!(@PUNCT '!')};
107 108
108 ( $first:tt $($tail:tt)+ ) => { 109 ( $first:tt $($tail:tt)+ ) => {
109 { 110 {
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 {
220 while src.len() > 0 { 220 while src.len() > 0 {
221 let rule = Rule::parse(&mut src, true)?; 221 let rule = Rule::parse(&mut src, true)?;
222 rules.push(rule); 222 rules.push(rule);
223 if let Err(()) = src.expect_char(';') { 223 if let Err(()) = src.expect_any_char(&[';', ',']) {
224 if src.len() > 0 { 224 if src.len() > 0 {
225 return Err(ParseError::Expected("expected `;`".to_string())); 225 return Err(ParseError::Expected(
226 "expected `;` or `,` to delimit rules".to_string(),
227 ));
226 } 228 }
227 break; 229 break;
228 } 230 }
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
@@ -663,6 +663,21 @@ macro foo {
663} 663}
664 664
665#[test] 665#[test]
666fn test_macro_2_0_panic_2015() {
667 parse_macro2(
668 r#"
669macro panic_2015 {
670 () => (
671 ),
672 (bar) => (
673 ),
674}
675"#,
676 )
677 .assert_expand_items("panic_2015!(bar);", "");
678}
679
680#[test]
666fn test_path() { 681fn test_path() {
667 parse_macro( 682 parse_macro(
668 r#" 683 r#"
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> {
34 } 34 }
35 } 35 }
36 36
37 pub(crate) fn expect_any_char(&mut self, chars: &[char]) -> Result<(), ()> {
38 match self.next() {
39 Some(tt::TokenTree::Leaf(tt::Leaf::Punct(tt::Punct { char: c, .. })))
40 if chars.contains(c) =>
41 {
42 Ok(())
43 }
44 _ => Err(()),
45 }
46 }
47
37 pub(crate) fn expect_subtree(&mut self) -> Result<&'a tt::Subtree, ()> { 48 pub(crate) fn expect_subtree(&mut self) -> Result<&'a tt::Subtree, ()> {
38 match self.next() { 49 match self.next() {
39 Some(tt::TokenTree::Subtree(it)) => Ok(it), 50 Some(tt::TokenTree::Subtree(it)) => Ok(it),