Skip to content

Commit

Permalink
Merge #9552
Browse files Browse the repository at this point in the history
9552: TY: properly infer type of custom macros which shadow built-in macros r=vlad20012 a=Undin

Fixes #9201
Fixes #9542

changelog: Properly infer type of custom macros which shadow built-in macros


Co-authored-by: Arseniy Pendryak <a.pendryak@yandex.ru>
  • Loading branch information
bors[bot] and Undin committed Oct 17, 2022
2 parents 20dde19 + e162636 commit 8c9d70b
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ package org.rust.lang.core.types.infer

import com.intellij.openapi.progress.ProgressManager
import com.intellij.psi.PsiElement
import org.rust.cargo.project.workspace.PackageOrigin
import org.rust.lang.core.macros.MacroExpansion
import org.rust.lang.core.psi.*
import org.rust.lang.core.psi.ext.*
Expand Down Expand Up @@ -1261,6 +1262,14 @@ class RsTypeInferenceWalker(

private fun inferMacroExprType0(macroExpr: RsMacroExpr, expected: Expectation): Ty {
val macroCall = macroExpr.macroCall

val definition = macroCall.resolveToMacro()
val origin = definition?.containingCrate?.origin
if (origin != null && origin != PackageOrigin.STDLIB) {
inferChildExprsRecursively(macroCall)
return inferMacroAsExpr(macroCall)
}

val name = macroCall.macroName
val exprArg = macroCall.exprMacroArgument
if (exprArg != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1024,4 +1024,66 @@ class RsStdlibExpressionTypeInferenceTest : RsTypificationTestBase() {
a;
} //^ !
""")

fun `test custom macros with stdlib names`() {
// name -> argument count
val macros = mapOf(
"dbg" to 1,
"format" to 1,
"format_args" to 1,
"format_args_nl" to 1,
"write" to 1,
"writeln" to 1,
"print" to 1,
"println" to 1,
"eprint" to 1,
"eprintln" to 1,
"panic" to 1,
"unimplemented" to 1,
"unreachable" to 1,
"todo" to 1,
"assert" to 1,
"debug_assert" to 1,
"assert_eq" to 2,
"assert_ne" to 2,
"debug_assert_eq" to 2,
"debug_assert_ne" to 2,
"vec" to 1,
"include_str" to 1,
"include_bytes" to 1,
// `MacroExpansionManagerImpl.getExpansionFor` always processes `include!` call as if `include!` is from stdlib.
// As a result, the expansion is null in this test and the plugin can't infer the proper type.
//
//"include" to 1,
"concat" to 1,
"env" to 1,
"option_env" to 1,
"line" to 0,
"column" to 0,
"file" to 0,
"stringify" to 1,
"cfg" to 1,
"module_path" to 0
)

for ((name, argsCount) in macros) {
val argsDefinition = (0..argsCount).joinToString(", ") { "$ x$it:expr" }
val args = (0..argsCount).joinToString(", ") { "\"it\"" }
// We try to construct custom macro definition in a way to trigger the same parser rules
// as if it would be a macro from stdlib
stubOnlyTypeInfer("""
//- main.rs
struct S;
macro_rules! $name {
($argsDefinition) => { S };
}
fn main() {
let a = $name!($args);
a;
//^ S
}
""", description = "Macro `$name`")
}
}
}

0 comments on commit 8c9d70b

Please sign in to comment.