Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rustc stack overflow with self-recursive concat! macro #84632

Closed
Nemo157 opened this issue Apr 27, 2021 · 7 comments · Fixed by #86484
Closed

rustc stack overflow with self-recursive concat! macro #84632

Nemo157 opened this issue Apr 27, 2021 · 7 comments · Fixed by #86484
Labels
A-macros Area: All kinds of macros (custom derive, macro_rules!, proc macros, ..) C-bug Category: This is a bug. glacier ICE tracked in rust-lang/glacier. I-crash Issue: The compiler crashes (SIGSEGV, SIGABRT, etc). Use I-ICE instead when the compiler panics. P-medium Medium priority regression-from-stable-to-stable Performance or correctness regression from one stable version to another.

Comments

@Nemo157
Copy link
Member

Nemo157 commented Apr 27, 2021

I tried this code:

#[macro_export]
macro_rules! n {() => (concat!("", n!()))}

fn main () {
    n!();
}

I expected to see this happen: An error message about exceeding some recursion limit

Instead, this happened:

thread 'rustc' has overflowed its stack
fatal runtime error: stack overflow

Meta

Tested on stable 1.51.0 + 1.53.0-nightly (2021-04-26 9684258936dabda2ba49)

@Nemo157 Nemo157 added I-crash Issue: The compiler crashes (SIGSEGV, SIGABRT, etc). Use I-ICE instead when the compiler panics. A-macros Area: All kinds of macros (custom derive, macro_rules!, proc macros, ..) C-bug Category: This is a bug. labels Apr 27, 2021
@jonas-schievink jonas-schievink added the I-prioritize Issue: Indicates that prioritization has been requested for this issue. label Apr 27, 2021
@camelid
Copy link
Member

camelid commented Apr 28, 2021

Note that the crash also occurs without #[macro_export].

Based on testing with Godbolt, this doesn't seem to be a regression, or at least not a recent one.

@hameerabbasi
Copy link
Contributor

Assigning P-medium as part of the prioritization working group discussion on Zulip and removing I-prioritize.

@rustbot modify labels -I-prioritize +P-medium

@rustbot rustbot added P-medium Medium priority and removed I-prioritize Issue: Indicates that prioritization has been requested for this issue. labels Apr 28, 2021
@rust-lang-glacier-bot rust-lang-glacier-bot added the glacier ICE tracked in rust-lang/glacier. label Apr 28, 2021
@fee1-dead
Copy link
Member

Issue might be in this line:

let es = match base::get_exprs_from_tts(cx, sp, tts) {

Calls get_exprs_from_tts, which then calls fully_expand_fragment:

let expr = cx.expander().fully_expand_fragment(AstFragment::Expr(expr)).make_expr();

And sets current_expansion.depth to 0, which would result in stack overflow because the recursion limit is never reached.

self.cx.current_expansion.depth = 0;

@fee1-dead

This comment has been minimized.

@fee1-dead
Copy link
Member

Bug is confusing to track down, so I am no longer working on this.

For people who are interested, here is the log when the loop is encountered:

DEBUG rustc_resolve resolve_crate_root($crate#105)
DEBUG rustc_span::hygiene marks: getting parent of #105
DEBUG rustc_resolve resolve_crate_root: marks=[(ExpnData { kind: Macro(Bang, "n"), parent: ExpnId(2), call_site: issue-84632-recursive-builtin-macro.rs:1:36: 1:40 (#104), def_site: issue-84632-recursive-builtin-macro.rs:1:1: 1:43 (#0), allow_internal_unstable: None, allow_internal_unsafe: false, local_inner_macros: false, edition: Edition2015, macro_def_id: Some(DefId(0:3)), krate: crate0, orig_id: Some(206), disambiguator: 0 }, SemiTransparent)]
DEBUG rustc_span::hygiene marks: getting parent of #105
DEBUG rustc_resolve resolve_crate_root: found opaque mark None None
DEBUG rustc_resolve resolve_crate_root: found semi-transparent mark Some(ExpnId(206)) Some(ExpnData { kind: Macro(Bang, "n"), parent: ExpnId(2), call_site: issue-84632-recursive-builtin-macro.rs:1:36: 1:40 (#104), def_site: issue-84632-recursive-builtin-macro.rs:1:1: 1:43 (#0), allow_internal_unstable: None, allow_internal_unsafe: false, local_inner_macros: false, edition: Edition2015, macro_def_id: Some(DefId(0:3)), krate: crate0, orig_id: Some(206), disambiguator: 0 })
DEBUG rustc_resolve resolve_crate_root($crate#105): got module Some(Def(Mod, DefId(0:0))) (Some("")) (ident.span = issue-84632-recursive-builtin-macro.rs:1:1: 1:1 (#105))
DEBUG rustc_metadata::rmeta::table Table::lookup: index=DefIndex(18) len=192232
DEBUG rustc_parse::parser::attr parse_outer_attributes: self.token=Token { kind: Literal(Lit { kind: Str, symbol: "", suffix: None }), span: issue-84632-recursive-builtin-macro.rs:1:32: 1:34 (#105) }
DEBUG rustc_parse::parser::attr parse_outer_attributes: self.token=Token { kind: Ident("n", false), span: issue-84632-recursive-builtin-macro.rs:1:36: 1:37 (#105) }
DEBUG rustc_parse::parser::diagnostics check_trailing_angle_brackets: parsed_angle_bracket_args=false
DEBUG rustc_parse::parser::attr parse_outer_attributes: self.token=Token { kind: Ident("concat", false), span: issue-84632-recursive-builtin-macro.rs:1:24: 1:30 (#106) }
DEBUG rustc_parse::parser::diagnostics check_trailing_angle_brackets: parsed_angle_bracket_args=false
DEBUG rustc_resolve resolve_crate_root($crate#106)
DEBUG rustc_span::hygiene marks: getting parent of #106
DEBUG rustc_resolve resolve_crate_root: marks=[(ExpnData { kind: Macro(Bang, "n"), parent: ExpnId(2), call_site: issue-84632-recursive-builtin-macro.rs:1:36: 1:40 (#105), def_site: issue-84632-recursive-builtin-macro.rs:1:1: 1:43 (#0), allow_internal_unstable: None, allow_internal_unsafe: false, local_inner_macros: false, edition: Edition2015, macro_def_id: Some(DefId(0:3)), krate: crate0, orig_id: Some(208), disambiguator: 0 }, SemiTransparent)]
DEBUG rustc_span::hygiene marks: getting parent of #106
DEBUG rustc_resolve resolve_crate_root: found opaque mark None None
DEBUG rustc_resolve resolve_crate_root: found semi-transparent mark Some(ExpnId(208)) Some(ExpnData { kind: Macro(Bang, "n"), parent: ExpnId(2), call_site: issue-84632-recursive-builtin-macro.rs:1:36: 1:40 (#105), def_site: issue-84632-recursive-builtin-macro.rs:1:1: 1:43 (#0), allow_internal_unstable: None, allow_internal_unsafe: false, local_inner_macros: false, edition: Edition2015, macro_def_id: Some(DefId(0:3)), krate: crate0, orig_id: Some(208), disambiguator: 0 })
DEBUG rustc_resolve resolve_crate_root($crate#106): got module Some(Def(Mod, DefId(0:0))) (Some("")) (ident.span = issue-84632-recursive-builtin-macro.rs:1:1: 1:1 (#106))
DEBUG rustc_metadata::rmeta::table Table::lookup: index=DefIndex(18) len=192232
DEBUG rustc_parse::parser::attr parse_outer_attributes: self.token=Token { kind: Literal(Lit { kind: Str, symbol: "", suffix: None }), span: issue-84632-recursive-builtin-macro.rs:1:32: 1:34 (#106) }
DEBUG rustc_parse::parser::attr parse_outer_attributes: self.token=Token { kind: Ident("n", false), span: issue-84632-recursive-builtin-macro.rs:1:36: 1:37 (#106) }
DEBUG rustc_parse::parser::diagnostics check_trailing_angle_brackets: parsed_angle_bracket_args=false
DEBUG rustc_parse::parser::attr parse_outer_attributes: self.token=Token { kind: Ident("concat", false), span: issue-84632-recursive-builtin-macro.rs:1:24: 1:30 (#107) }
DEBUG rustc_parse::parser::diagnostics check_trailing_angle_brackets: parsed_angle_bracket_args=false
DEBUG rustc_resolve resolve_crate_root($crate#107)
DEBUG rustc_span::hygiene marks: getting parent of #107
DEBUG rustc_resolve resolve_crate_root: marks=[(ExpnData { kind: Macro(Bang, "n"), parent: ExpnId(2), call_site: issue-84632-recursive-builtin-macro.rs:1:36: 1:40 (#106), def_site: issue-84632-recursive-builtin-macro.rs:1:1: 1:43 (#0), allow_internal_unstable: None, allow_internal_unsafe: false, local_inner_macros: false, edition: Edition2015, macro_def_id: Some(DefId(0:3)), krate: crate0, orig_id: Some(210), disambiguator: 0 }, SemiTransparent)]
DEBUG rustc_span::hygiene marks: getting parent of #107

@rustbot release-assignment

@fee1-dead
Copy link
Member

fee1-dead commented May 7, 2021

The issue is part of a bigger problem, that concat! seems to ignore the recursion limit.
This snippet below compiles successfully instead of reporting an error: Playground

#![recursion_limit = "5"]
macro_rules! a {
    () => ("");
    (A) => (concat!("", a!()));
    (A, $($A:ident),*) => (concat!("", a!($($A),*)))
}

fn main() { 
    a! (A, A, A, A, A, A, A, A, A, A);
}

@fee1-dead
Copy link
Member

Seems to be a regression between 1.12.0 and 1.13.0 by testing on Godbolt.

I suspect this commit from blame caused the regression, but I'm not sure.

@rustbot label regression-untriaged

@rustbot rustbot added the regression-untriaged Untriaged performance or correctness regression. label May 7, 2021
@camelid camelid added regression-from-stable-to-stable Performance or correctness regression from one stable version to another. and removed regression-untriaged Untriaged performance or correctness regression. labels May 7, 2021
JohnTitor added a commit to JohnTitor/rust that referenced this issue Jun 21, 2021
…r=petrochenkov

Do not set depth to 0 in fully_expand_fragment

Fixes rust-lang#84632.
@bors bors closed this as completed in e5ecded Jun 21, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-macros Area: All kinds of macros (custom derive, macro_rules!, proc macros, ..) C-bug Category: This is a bug. glacier ICE tracked in rust-lang/glacier. I-crash Issue: The compiler crashes (SIGSEGV, SIGABRT, etc). Use I-ICE instead when the compiler panics. P-medium Medium priority regression-from-stable-to-stable Performance or correctness regression from one stable version to another.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants