From fd271a903a8ca36c890a4421e4f511d82433f34c Mon Sep 17 00:00:00 2001 From: Jeong YunWon Date: Fri, 26 Jul 2024 00:25:18 +0900 Subject: [PATCH] Fix nested cfg_if if-statement not to hang --- src/parse/macros/cfg_if.rs | 20 ++++++++++++-------- tests/source/issue-4442.rs | 6 ++++++ tests/target/issue-4442.rs | 6 ++++++ 3 files changed, 24 insertions(+), 8 deletions(-) create mode 100644 tests/source/issue-4442.rs create mode 100644 tests/target/issue-4442.rs diff --git a/src/parse/macros/cfg_if.rs b/src/parse/macros/cfg_if.rs index 0b7b6c4d361..88b5ad5c26f 100644 --- a/src/parse/macros/cfg_if.rs +++ b/src/parse/macros/cfg_if.rs @@ -4,6 +4,7 @@ use rustc_ast::ast; use rustc_ast::token::{Delimiter, TokenKind}; use rustc_parse::exp; use rustc_parse::parser::ForceCollect; +use rustc_parse::parser::Parser; use rustc_span::symbol::kw; use crate::parse::macros::build_stream_parser; @@ -13,7 +14,10 @@ pub(crate) fn parse_cfg_if<'a>( psess: &'a ParseSess, mac: &'a ast::MacCall, ) -> Result, &'static str> { - match catch_unwind(AssertUnwindSafe(|| parse_cfg_if_inner(psess, mac))) { + let ts = mac.args.tokens.clone(); + let mut parser = build_stream_parser(psess.inner(), ts); + + match catch_unwind(AssertUnwindSafe(|| parse_cfg_if_inner(&mut parser, vec![]))) { Ok(Ok(items)) => Ok(items), Ok(err @ Err(_)) => err, Err(..) => Err("failed to parse cfg_if!"), @@ -21,13 +25,9 @@ pub(crate) fn parse_cfg_if<'a>( } fn parse_cfg_if_inner<'a>( - psess: &'a ParseSess, - mac: &'a ast::MacCall, + parser: &mut Parser<'a>, + mut items: Vec, ) -> Result, &'static str> { - let ts = mac.args.tokens.clone(); - let mut parser = build_stream_parser(psess.inner(), ts); - - let mut items = vec![]; let mut process_if_cfg = true; while parser.token.kind != TokenKind::Eof { @@ -65,7 +65,11 @@ fn parse_cfg_if_inner<'a>( { let item = match parser.parse_item(ForceCollect::No) { Ok(Some(item_ptr)) => item_ptr.into_inner(), - Ok(None) => continue, + Ok(None) => { + // maybe recursive if + items = parse_cfg_if_inner(parser, items)?; + continue; + } Err(err) => { err.cancel(); parser.psess.dcx().reset_err_count(); diff --git a/tests/source/issue-4442.rs b/tests/source/issue-4442.rs new file mode 100644 index 00000000000..d01e3d6b29e --- /dev/null +++ b/tests/source/issue-4442.rs @@ -0,0 +1,6 @@ +cfg_if! { + if #[cfg()] { + if #[cfg()] { + } + } +} diff --git a/tests/target/issue-4442.rs b/tests/target/issue-4442.rs new file mode 100644 index 00000000000..d01e3d6b29e --- /dev/null +++ b/tests/target/issue-4442.rs @@ -0,0 +1,6 @@ +cfg_if! { + if #[cfg()] { + if #[cfg()] { + } + } +}