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

MACRO: check macro expansion depth during type inference #4383

Merged
merged 1 commit into from Sep 15, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -814,4 +814,5 @@ object TypeInferenceMarks {
val methodPickDerefOrder = Testmark("methodPickDerefOrder")
val methodPickCollapseTraits = Testmark("methodPickCollapseTraits")
val traitSelectionSpecialization = Testmark("traitSelectionSpecialization")
val macroExprDepthLimitReached = Testmark("reachMacroExprDepthLimit")
}
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,19 @@ class RsTypeInferenceWalker(
}

private fun inferMacroExprType(macroExpr: RsMacroExpr, expected: Ty?): Ty {
if (macroExprDepth > DEFAULT_RECURSION_LIMIT) {
TypeInferenceMarks.macroExprDepthLimitReached.hit()
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 @@ -5,6 +5,8 @@

package org.rust.lang.core.type

import org.rust.lang.core.types.infer.TypeInferenceMarks

class RsMacroTypeInferenceTest : RsTypificationTestBase() {
override val followMacroExpansions: Boolean get() = true

Expand Down Expand Up @@ -124,4 +126,12 @@ class RsMacroTypeInferenceTest : RsTypificationTestBase() {
b;
} //^ <unknown>
""")

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