Skip to content

Commit bf695c4

Browse files
Merge #8304
8304: Support the new `panic!()` macro r=jonas-schievink a=jonas-schievink Includes a minor fixup to macro 2.0 parsing. bors r+ Co-authored-by: Jonas Schievink <[email protected]>
2 parents eb264fb + 5742cdf commit bf695c4

File tree

7 files changed

+67
-5
lines changed

7 files changed

+67
-5
lines changed

crates/hir_def/src/nameres/collector.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1402,8 +1402,18 @@ impl ModCollector<'_, '_> {
14021402

14031403
// Case 1: builtin macros
14041404
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+
};
14051415
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) {
14071417
self.def_collector.define_macro_rules(
14081418
self.module_id,
14091419
mac.name.clone(),

crates/hir_expand/src/builtin_macro.rs

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
//! Builtin macro
22
use crate::{
33
db::AstDatabase, name, quote, AstId, CrateId, EagerMacroId, LazyMacroId, MacroCallId,
4-
MacroDefId, MacroDefKind, TextSize,
4+
MacroCallLoc, MacroDefId, MacroDefKind, TextSize,
55
};
66

7-
use base_db::{AnchoredPath, FileId};
7+
use base_db::{AnchoredPath, Edition, FileId};
88
use cfg::CfgExpr;
99
use either::Either;
1010
use mbe::{parse_exprs_with_sep, parse_to_token_tree, ExpandResult};
@@ -111,6 +111,8 @@ register_builtin! {
111111
(llvm_asm, LlvmAsm) => asm_expand,
112112
(asm, Asm) => asm_expand,
113113
(cfg, Cfg) => cfg_expand,
114+
(core_panic, CorePanic) => panic_expand,
115+
(std_panic, StdPanic) => panic_expand,
114116

115117
EAGER:
116118
(compile_error, CompileError) => compile_error_expand,
@@ -284,6 +286,25 @@ fn cfg_expand(
284286
ExpandResult::ok(expanded)
285287
}
286288

289+
fn 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+
287308
fn unquote_str(lit: &tt::Literal) -> Option<String> {
288309
let lit = ast::make::tokens::literal(&lit.to_string());
289310
let token = ast::String::cast(lit)?;

crates/hir_expand/src/name.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,8 @@ pub mod known {
208208
line,
209209
module_path,
210210
assert,
211+
core_panic,
212+
std_panic,
211213
stringify,
212214
concat,
213215
include,

crates/hir_expand/src/quote.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ macro_rules! __quote {
104104
( . ) => {$crate::__quote!(@PUNCT '.')};
105105
( < ) => {$crate::__quote!(@PUNCT '<')};
106106
( > ) => {$crate::__quote!(@PUNCT '>')};
107+
( ! ) => {$crate::__quote!(@PUNCT '!')};
107108

108109
( $first:tt $($tail:tt)+ ) => {
109110
{

crates/mbe/src/lib.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -220,9 +220,11 @@ impl MacroDef {
220220
while src.len() > 0 {
221221
let rule = Rule::parse(&mut src, true)?;
222222
rules.push(rule);
223-
if let Err(()) = src.expect_char(';') {
223+
if let Err(()) = src.expect_any_char(&[';', ',']) {
224224
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+
));
226228
}
227229
break;
228230
}

crates/mbe/src/tests/expand.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -662,6 +662,21 @@ macro foo {
662662
.assert_expand_items("foo!(bar);", "fn bar () {}");
663663
}
664664

665+
#[test]
666+
fn test_macro_2_0_panic_2015() {
667+
parse_macro2(
668+
r#"
669+
macro panic_2015 {
670+
() => (
671+
),
672+
(bar) => (
673+
),
674+
}
675+
"#,
676+
)
677+
.assert_expand_items("panic_2015!(bar);", "");
678+
}
679+
665680
#[test]
666681
fn test_path() {
667682
parse_macro(

crates/mbe/src/tt_iter.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,17 @@ impl<'a> TtIter<'a> {
3434
}
3535
}
3636

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+
3748
pub(crate) fn expect_subtree(&mut self) -> Result<&'a tt::Subtree, ()> {
3849
match self.next() {
3950
Some(tt::TokenTree::Subtree(it)) => Ok(it),

0 commit comments

Comments
 (0)