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
TY&RES: implement hygiene & infer types in macros #4094
Conversation
c8d6d47
to
c01cd05
Compare
dba24a9
to
15f945b
Compare
Fixed tests |
9ff5e3c
to
794179e
Compare
val tailExpr = expandedStmts.lastOrNull() | ||
?.let { it as? RsExpr } | ||
?.takeIf { e -> | ||
e.expandedFromSequence.all { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Comment why we need this.
As we discussed in person it's very unclear place
protected inline fun <reified T : PsiElement> findElementInEditor(marker: String = "^"): T = | ||
findElementInEditor(T::class.java, marker) | ||
|
||
protected fun <T : PsiElement> findElementInEditor(psiClass: Class<T>, marker: String): T { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we really need these changes?
I remember your concerns about performance when too large code is inlined but it's still test code
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It makes debugging & stack trace analyzing more complicated. As I remember, I made these changes exactly when I too tired to debug findElementsWithDataAndOffsetInEditor
function (you can see some changes there) when it is inlined. I think that we really need these changes, especially in tests, because it's a something that usually fails and we are often forced to analyze stack traces from there or debug it, so it should be as simple as possible.
@@ -1176,14 +1180,15 @@ private fun processLexicalDeclarations( | |||
scope: RsElement, | |||
cameFrom: PsiElement, | |||
ns: Set<Namespace>, | |||
hygieneFilter: (RsPatBinding) -> Boolean, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's add a comment/javadoc why and when we need this filter
@@ -1343,6 +1359,33 @@ fun processNestedScopesUpwards( | |||
return false | |||
} | |||
|
|||
private fun makeHygieneFilter(anchor: PsiElement): (RsPatBinding) -> Boolean { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the main explanation what we want to archive by hygiene filter should be located in javadoc here
val nameIdentifier = element.nameIdentifier ?: return false | ||
val hygienicScope2 = (nameIdentifier.findElementExpandedFrom() ?: nameIdentifier).containingFile | ||
.unwrapCodeFragments() | ||
return hygienicScope == hygienicScope2 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it possible to come up with more self-explained names for these variables?
@@ -256,14 +275,25 @@ abstract class RsTestBase : LightPlatformCodeInsightFixtureTestCase(), RsTestCas | |||
val previousLine = LogicalPosition(markerPosition.line - 1, markerPosition.column) | |||
val elementOffset = myFixture.editor.logicalPositionToOffset(previousLine) | |||
val elementAtMarker = myFixture.file.findElementAt(elementOffset)!! | |||
val element = elementAtMarker.ancestorOrSelf<T>() | |||
|
|||
if (followMacroExpansions) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we really need this property?
Can we always follow macro expansions if it's possible?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can't follow expansions at least in RsMacroCallReferenceDelegationTest
. We can either turn off followMacroExpansions
for this test (and turn on by default) or turn it on where it is needed. For now, I decided to turn it on explicitly
* macro call, i.e. outside of any expansion. | ||
*/ | ||
fun PsiElement.findElementExpandedFromChecked(): PsiElement? { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hm, change looks quite suspicious
Previous findElementExpandedFrom
became findElementExpandedFromChecked
(if take into account javadoc) but not all previous usages of findElementExpandedFrom
replaced by findElementExpandedFromChecked
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, I think the previous name was better
Let's keep old name and come up with a better name for new function
} | ||
|
||
/** | ||
* If receiver element is inside a macro expansion, returns the leaf element inside the macro call |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What this function should return if element
is not inside macro expansion?
@@ -84,3 +89,7 @@ abstract class RsTypificationTestBase : RsTestBase() { | |||
} | |||
} | |||
} | |||
|
|||
private val BUILTIN_MACRO_NAMES = listOf( | |||
"env", "option_env", "concat", "line", "column", "file", "stringify", "module_path", "cfg" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do I understand correctly that this list consists of builtin macros except some ones that have special rules in our grammar?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
looks like compile_error
is not in this list
Also, check concat
- we have special grammar rule for it now
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's exactly this list: https://github.com/intellij-rust/intellij-rust/blob/master/src/main/kotlin/org/rust/lang/core/types/infer/TypeInferenceWalker.kt#L1077
We need it because such built-in macros actually resolve to dummy definitions that expand to empty block expr ({ }
) that we don't take into account during type inference.
2780687
to
88bf672
Compare
bors r=undin |
Build failed |
bors retry |
3996: INT & ANN: Implement intention and fix for struct fields expansion instead of `..` r=vlad20012 a=shevtsiv <!-- Hello and thank you for the pull request! We don't have any strict rules about pull requests, but you might check https://github.com/intellij-rust/intellij-rust/blob/master/CONTRIBUTING.md for some hints! Note that we need an electronic CLA for contributions: https://github.com/intellij-rust/intellij-rust/blob/master/CONTRIBUTING.md#cla After you sign the CLA, please add your name to https://github.com/intellij-rust/intellij-rust/blob/master/CONTRIBUTORS.txt :) --> In this pull request I intend to do the following: 1) Create E0023 and E0027 error classes and implement analysis for them. 2) Create fix for those errors. 3) Create intention for struct fields expansion. 4) Create a module with shared code for using it in the fix and intention. Once these steps are complete I will squash all the commits and #3928 should be closed after merge. 4094: TY&RES: implement hygiene & infer types in macros r=undin a=vlad20012 Now we take into account any custom macros in type inference Co-authored-by: shevtsiv <rostykshevtsiv@gmail.com> Co-authored-by: vlad20012 <beskvlad@gmail.com>
Build failed (retrying...) |
4330: TY: fix random type inference fails caused by STUB usage instead of AST r=vlad20012 a=vlad20012 The bug was introduced in #4094 (because we used a stubbed statement list) and led to the fact that sometimes all types in some file was not inferred until you type some text there Co-authored-by: vlad20012 <beskvlad@gmail.com>
Now we take into account any custom macros in type inference