diff --git a/src/main/kotlin/org/rust/lang/core/types/infer/TypeInferenceWalker.kt b/src/main/kotlin/org/rust/lang/core/types/infer/TypeInferenceWalker.kt index e43e358eef5..130c6e3d982 100644 --- a/src/main/kotlin/org/rust/lang/core/types/infer/TypeInferenceWalker.kt +++ b/src/main/kotlin/org/rust/lang/core/types/infer/TypeInferenceWalker.kt @@ -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 @@ -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 diff --git a/src/test/kotlin/org/rust/lang/core/type/RsMacroTypeInferenceTest.kt b/src/test/kotlin/org/rust/lang/core/type/RsMacroTypeInferenceTest.kt index 34a92366767..30ccbf69f86 100644 --- a/src/test/kotlin/org/rust/lang/core/type/RsMacroTypeInferenceTest.kt +++ b/src/test/kotlin/org/rust/lang/core/type/RsMacroTypeInferenceTest.kt @@ -124,4 +124,12 @@ class RsMacroTypeInferenceTest : RsTypificationTestBase() { b; } //^ """) + + fun `test infinite recursion`() = testExpr(""" + macro_rules! foo { () => { foo!(); }; } + fn main() { + let a = foo!(); + a; + } //^ + """) }