Skip to content

Commit

Permalink
MACRO: check macro expansion depth during type inference
Browse files Browse the repository at this point in the history
Prevents infinite recursive macros
  • Loading branch information
vlad20012 committed Sep 12, 2019
1 parent e453c6c commit 00edaf1
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 0 deletions.
Expand Up @@ -31,6 +31,7 @@ class RsTypeInferenceWalker(
) {
private var tryTy: Ty? = returnTy
private var yieldTy: Ty? = null
private var macroExprDepth: Int = 0
private val lookup get() = ctx.lookup
private val items get() = ctx.items
private val fulfill get() = ctx.fulfill
Expand Down Expand Up @@ -1046,6 +1047,16 @@ class RsTypeInferenceWalker(
}

private fun inferMacroExprType(macroExpr: RsMacroExpr, expected: Ty?): Ty {
if (macroExprDepth > DEFAULT_RECURSION_LIMIT) return TyUnknown
macroExprDepth++
try {
return inferMacroExprType0(macroExpr, expected)
} finally {
macroExprDepth--
}
}

private fun inferMacroExprType0(macroExpr: RsMacroExpr, expected: Ty?): Ty {
val macroCall = macroExpr.macroCall
val name = macroCall.macroName
val exprArg = macroCall.exprMacroArgument
Expand Down
Expand Up @@ -124,4 +124,12 @@ class RsMacroTypeInferenceTest : RsTypificationTestBase() {
b;
} //^ <unknown>
""")

fun `test infinite recursion`() = testExpr("""
macro_rules! foo { () => { foo!(); }; }
fn main() {
let a = foo!();
a;
} //^ <unknown>
""")
}

0 comments on commit 00edaf1

Please sign in to comment.