mirror of
https://github.com/rust-lang/rust.git
synced 2025-01-06 12:54:51 +00:00
Merge #3425
3425: Fix a bug for single dollar sign macro r=matklad a=edwin0cheng This PR fixed a bug to allow the following valid `macro_rules!` : ```rust macro_rules! m { ($) => ($) } ``` Co-authored-by: Edwin Cheng <edwin0cheng@gmail.com>
This commit is contained in:
commit
cebb995d21
@ -86,10 +86,13 @@ pub(crate) fn macro_def(
|
|||||||
log::warn!("fail on macro_def to token tree: {:#?}", arg);
|
log::warn!("fail on macro_def to token tree: {:#?}", arg);
|
||||||
None
|
None
|
||||||
})?;
|
})?;
|
||||||
let rules = MacroRules::parse(&tt).ok().or_else(|| {
|
let rules = match MacroRules::parse(&tt) {
|
||||||
log::warn!("fail on macro_def parse: {:#?}", tt);
|
Ok(it) => it,
|
||||||
None
|
Err(err) => {
|
||||||
})?;
|
log::warn!("fail on macro_def parse: error: {:#?} {:#?}", err, tt);
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
};
|
||||||
Some(Arc::new((TokenExpander::MacroRules(rules), tmap)))
|
Some(Arc::new((TokenExpander::MacroRules(rules), tmap)))
|
||||||
}
|
}
|
||||||
MacroDefKind::BuiltIn(expander) => {
|
MacroDefKind::BuiltIn(expander) => {
|
||||||
@ -150,7 +153,9 @@ pub(crate) fn parse_macro(
|
|||||||
// Note:
|
// Note:
|
||||||
// The final goal we would like to make all parse_macro success,
|
// The final goal we would like to make all parse_macro success,
|
||||||
// such that the following log will not call anyway.
|
// such that the following log will not call anyway.
|
||||||
log::warn!("fail on macro_parse: (reason: {})", err,);
|
let loc: MacroCallLoc = db.lookup_intern_macro(macro_call_id);
|
||||||
|
let node = loc.kind.node(db);
|
||||||
|
log::warn!("fail on macro_parse: (reason: {} macro_call: {:#})", err, node.value);
|
||||||
})
|
})
|
||||||
.ok()?;
|
.ok()?;
|
||||||
|
|
||||||
|
@ -90,7 +90,11 @@ fn next_op<'a>(
|
|||||||
) -> Result<Op<'a>, ExpandError> {
|
) -> Result<Op<'a>, ExpandError> {
|
||||||
let res = match first {
|
let res = match first {
|
||||||
tt::TokenTree::Leaf(tt::Leaf::Punct(tt::Punct { char: '$', .. })) => {
|
tt::TokenTree::Leaf(tt::Leaf::Punct(tt::Punct { char: '$', .. })) => {
|
||||||
let second = src.next().ok_or_else(|| err!("bad var 1"))?;
|
// Note that the '$' itself is a valid token inside macro_rules.
|
||||||
|
let second = match src.next() {
|
||||||
|
None => return Ok(Op::TokenTree(first)),
|
||||||
|
Some(it) => it,
|
||||||
|
};
|
||||||
match second {
|
match second {
|
||||||
tt::TokenTree::Subtree(subtree) => {
|
tt::TokenTree::Subtree(subtree) => {
|
||||||
let (separator, kind) = parse_repeat(src)?;
|
let (separator, kind) = parse_repeat(src)?;
|
||||||
|
@ -23,6 +23,7 @@ mod rule_parsing {
|
|||||||
check("($($i:ident)*) => ($_)");
|
check("($($i:ident)*) => ($_)");
|
||||||
check("($($true:ident)*) => ($true)");
|
check("($($true:ident)*) => ($true)");
|
||||||
check("($($false:ident)*) => ($false)");
|
check("($($false:ident)*) => ($false)");
|
||||||
|
check("($) => ($)");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
Loading…
Reference in New Issue
Block a user