Repository: intellij-rust/intellij-rust (language: rust)

Issue:
#[proc_macro_attribute] field injection is not supported by syntax highlighter
<!--
Hello and thank you for the issue!
If you would like to report a bug, we have added some points below that you can fill out.
Feel free to remove all the irrelevant text to request a new feature.
-->

## Environment

* **IntelliJ Rust plugin version:** 0.4.185.5086-223
* **Rust toolchain version:** 1.63.0 (4b91a6ea7 2022-08-08) x86_64-pc-windows-msvc
* **IDE name and version:** CLion 2022.3.1 (CL-223.8214.51)
* **Operating system:** Windows 10 10.0
* **Macro expansion:** enabled

## Problem description
`#[proc_macro_attribute]` does not inform syntax highlighting correctly in this [proc macro example for struct field injection](https://github.com/eonm-abes/proc-macro-issue-minimal-example). Opening this same files with `rust-analyzer` in VSCode does not have this issue.

## Steps to reproduce
1. Open the above Github project in CLion with the Rust IntelliJ plugin activated
2. Turn on Cargo check (on the fly calculation)
3. Navigate to tests/01-shoud-add-struct-field.rs
4. Observe that field `a` is linted with the error message `No such field`
5. ![image](https://user-images.githubusercontent.com/36089408/212391940-af6db393-4365-46fb-b0b1-f8a18db6b2d0.png)
6. Navigate to tests/02-parse-attributes.rs
7. Observe that field `a` is linted with the error message `No such field`
8. Update  `#[add_field2("a")]` to  `#[add_field2("b")]`
9. Observe a new linting error stating 
```
struct `tests::add_field::Foo` has no field named `a` [E0560] Help: a field with a similar name exists
```
10. ![image](https://user-images.githubusercontent.com/36089408/212392215-954943e2-c0f8-4797-9645-c0737f170ad1.png)

<!--
Please include as much of your codebase as needed to reproduce the error.
If the relevant files are large, please provide a link to a public repository or a [Gist](https://gist.github.com/).
-->

All code to reproduce this issue can be found in this github repository: https://github.com/eonm-abes/proc-macro-issue-minimal-example


Discussion / hints:
Try to enable `org.rust.macros.proc.attr` experimental feature via the corresponding dialog. To open the dialog, just invoke `Help | Find Action` action and type `Experimental features`. Then refresh the cargo project or restart the IDE.
Thanks for the pointer! I just set the experimental feature now:

![image](https://user-images.githubusercontent.com/36089408/212393282-c28ea745-fb6d-4d39-b079-f1a1a83e83fb.png)

It didn't seem to work just by activating the setting (there didn't seem to be a `apply` button or any restart dialog). I went ahead and invalidated the cache and reopened the IDE. This seemed to work! 

![image](https://user-images.githubusercontent.com/36089408/212393745-5908b7cc-a25e-4b2a-be8a-442566d43294.png)

Thanks for the help!

Let's keep it open since `org.rust.macros.proc.attr` is not enabled by default yet

Fix patch:
diff --git a/src/main/resources-nightly/META-INF/experiments.xml b/src/main/resources-nightly/META-INF/experiments.xml
index c2fd916d5bc..19f55c08582 100644
--- a/src/main/resources-nightly/META-INF/experiments.xml
+++ b/src/main/resources-nightly/META-INF/experiments.xml
@@ -15,7 +15,7 @@
         <experimentalFeature id="org.rust.macros.proc.derive" percentOfUsers="100">
             <description>Enables derive procedural macro expansion</description>
         </experimentalFeature>
-        <experimentalFeature id="org.rust.macros.proc.attr" percentOfUsers="0">
+        <experimentalFeature id="org.rust.macros.proc.attr" percentOfUsers="100">
             <description>Enables attribute procedural macro expansion</description>
         </experimentalFeature>
         <experimentalFeature id="org.rust.crates.local.index" percentOfUsers="100">
diff --git a/src/main/resources-stable/META-INF/experiments.xml b/src/main/resources-stable/META-INF/experiments.xml
index 6a918660170..9dd16993697 100644
--- a/src/main/resources-stable/META-INF/experiments.xml
+++ b/src/main/resources-stable/META-INF/experiments.xml
@@ -15,7 +15,7 @@
         <experimentalFeature id="org.rust.macros.proc.derive" percentOfUsers="100">
             <description>Enables derive procedural macro expansion</description>
         </experimentalFeature>
-        <experimentalFeature id="org.rust.macros.proc.attr" percentOfUsers="0">
+        <experimentalFeature id="org.rust.macros.proc.attr" percentOfUsers="100">
             <description>Enables attribute procedural macro expansion</description>
         </experimentalFeature>
         <experimentalFeature id="org.rust.crates.local.index" percentOfUsers="100">


Test patch:
diff --git a/src/test/kotlin/org/rust/ide/annotator/RsHighlightingAnnotatorTest.kt b/src/test/kotlin/org/rust/ide/annotator/RsHighlightingAnnotatorTest.kt
index 413c24fd2f6..1e69f1caf4a 100644
--- a/src/test/kotlin/org/rust/ide/annotator/RsHighlightingAnnotatorTest.kt
+++ b/src/test/kotlin/org/rust/ide/annotator/RsHighlightingAnnotatorTest.kt
@@ -21,8 +21,7 @@ class RsHighlightingAnnotatorTest : RsAnnotatorTestBase(RsHighlightingAnnotator:
     }
 
     fun `test attributes`() = checkHighlighting("""
-        <ATTRIBUTE>#[foo(foo)]</ATTRIBUTE>
-        <ATTRIBUTE>#[foo(<STRING>"bar"</STRING>)]</ATTRIBUTE>
+        <ATTRIBUTE>#[doc = <STRING>"bar"</STRING>]</ATTRIBUTE>
         fn <FUNCTION>main</FUNCTION>() {
             <ATTRIBUTE>#![crate_type = <STRING>"lib"</STRING>]</ATTRIBUTE>
         }
diff --git a/src/test/kotlin/org/rust/ide/annotator/RsMacroExpansionHighlightingPassTest.kt b/src/test/kotlin/org/rust/ide/annotator/RsMacroExpansionHighlightingPassTest.kt
index 4699817192b..9527083a99f 100644
--- a/src/test/kotlin/org/rust/ide/annotator/RsMacroExpansionHighlightingPassTest.kt
+++ b/src/test/kotlin/org/rust/ide/annotator/RsMacroExpansionHighlightingPassTest.kt
@@ -16,7 +16,7 @@ import org.rust.lang.core.macros.MacroExpansionManager
 class RsMacroExpansionHighlightingPassTest : RsAnnotationTestBase() {
 
     fun `test attributes inside macro call`() = checkHighlightingInsideMacro("""
-        <ATTRIBUTE>#[foo(foo)]</ATTRIBUTE>
+        <ATTRIBUTE>#[doc = ""]</ATTRIBUTE>
         fn <FUNCTION>main</FUNCTION>() {
             <ATTRIBUTE>#![crate_type = <STRING>"lib"</STRING>]</ATTRIBUTE>
         }
diff --git a/src/test/kotlin/org/rust/ide/inspections/import/AutoImportFixTest.kt b/src/test/kotlin/org/rust/ide/inspections/import/AutoImportFixTest.kt
index 3be6ec1faea..6fb7d692ca6 100644
--- a/src/test/kotlin/org/rust/ide/inspections/import/AutoImportFixTest.kt
+++ b/src/test/kotlin/org/rust/ide/inspections/import/AutoImportFixTest.kt
@@ -2329,7 +2329,7 @@ class AutoImportFixTest : AutoImportFixTestBase() {
     """)
 
     fun `test group imports only if the other import doesn't have an attribute`() = checkAutoImportFixByText("""
-        #[attribute = "value"]
+        #[doc = "value"]
         use crate::foo::Foo;
 
         mod foo {
@@ -2342,7 +2342,7 @@ class AutoImportFixTest : AutoImportFixTestBase() {
         }
     """, """
         use crate::foo::Bar;
-        #[attribute = "value"]
+        #[doc = "value"]
         use crate::foo::Foo;
 
         mod foo {
diff --git a/src/test/kotlin/org/rust/ide/intentions/ToggleFeatureIntentionTest.kt b/src/test/kotlin/org/rust/ide/intentions/ToggleFeatureIntentionTest.kt
index 9f5e51d8cbe..c62bf0672a3 100644
--- a/src/test/kotlin/org/rust/ide/intentions/ToggleFeatureIntentionTest.kt
+++ b/src/test/kotlin/org/rust/ide/intentions/ToggleFeatureIntentionTest.kt
@@ -6,18 +6,17 @@
 package org.rust.ide.intentions
 
 import org.intellij.lang.annotations.Language
-import org.rust.MockCargoFeatures
-import org.rust.SkipTestWrapping
+import org.rust.*
 import org.rust.cargo.project.model.cargoProjects
 import org.rust.cargo.project.workspace.FeatureState
 import org.rust.cargo.project.workspace.PackageOrigin
-import org.rust.singleProject
-import org.rust.workspaceOrFail
+import org.rust.ide.experiments.RsExperiments
 
 class ToggleFeatureIntentionTest : RsIntentionTestBase(ToggleFeatureIntention::class) {
 
     override val previewExpected: Boolean get() = false
 
+    @WithoutExperimentalFeatures(RsExperiments.PROC_MACROS, RsExperiments.ATTR_PROC_MACROS)
     @SkipTestWrapping // TODO fix `PsiElement.findExpansionElementsNonRecursive` for `cfg_attr` condition
     @MockCargoFeatures("foo")
     fun `test availability range`() = checkAvailableInSelectionOnly("""
diff --git a/src/test/kotlin/org/rust/lang/core/completion/RsCompletionSortingTest.kt b/src/test/kotlin/org/rust/lang/core/completion/RsCompletionSortingTest.kt
index 5f7a98de985..135d79e3914 100644
--- a/src/test/kotlin/org/rust/lang/core/completion/RsCompletionSortingTest.kt
+++ b/src/test/kotlin/org/rust/lang/core/completion/RsCompletionSortingTest.kt
@@ -7,6 +7,8 @@ package org.rust.lang.core.completion
 
 import org.intellij.lang.annotations.Language
 import org.rust.RsTestBase
+import org.rust.WithoutExperimentalFeatures
+import org.rust.ide.experiments.RsExperiments
 import org.rust.lang.core.psi.*
 import org.rust.lang.core.psi.ext.RsFieldDecl
 import kotlin.reflect.KClass
@@ -499,6 +501,7 @@ class RsCompletionSortingTest : RsTestBase() {
         Int::class to "1"
     ))
 
+    @WithoutExperimentalFeatures(RsExperiments.PROC_MACROS, RsExperiments.ATTR_PROC_MACROS)
     fun `test expected types priority (vec macro)`() = doTest("""
         #[lang = "alloc::vec::Vec"]
         struct Vec<T>(T);
diff --git a/src/test/kotlin/org/rust/lang/core/macros/proc/RsProcMacroErrorTest.kt b/src/test/kotlin/org/rust/lang/core/macros/proc/RsProcMacroErrorTest.kt
index 05fdd39143d..aaf18a9ef43 100644
--- a/src/test/kotlin/org/rust/lang/core/macros/proc/RsProcMacroErrorTest.kt
+++ b/src/test/kotlin/org/rust/lang/core/macros/proc/RsProcMacroErrorTest.kt
@@ -23,7 +23,7 @@ import org.rust.lang.core.macros.errors.GetMacroExpansionError
 @ProjectDescriptor(WithProcMacroRustProjectDescriptor::class)
 @WithExperimentalFeatures(EVALUATE_BUILD_SCRIPTS, PROC_MACROS)
 class RsProcMacroErrorTest : RsMacroExpansionErrorTestBase() {
-    @WithExperimentalFeatures()
+    @WithoutExperimentalFeatures(PROC_MACROS, ATTR_PROC_MACROS)
     fun `test macro expansion is disabled`() = checkError<GetMacroExpansionError.ExpansionError>("""
         use test_proc_macros::attr_as_is;
 
@@ -62,7 +62,7 @@ class RsProcMacroErrorTest : RsMacroExpansionErrorTestBase() {
     """)
 
     @ProjectDescriptor(WithDependencyRustProjectDescriptor::class)
-    @WithExperimentalFeatures()
+    @WithoutExperimentalFeatures(PROC_MACROS, ATTR_PROC_MACROS)
     fun `test macro expansion is disabled with unsuccessfully compiled proc macro crate`() = checkErrorByTree<GetMacroExpansionError.ExpansionError>("""
     //- dep-proc-macro-unsuccessfully-compiled/lib.rs
         extern crate proc_macro;
diff --git a/src/test/kotlin/org/rust/lang/core/psi/ProcMacroAttributeTest.kt b/src/test/kotlin/org/rust/lang/core/psi/ProcMacroAttributeTest.kt
index 96eee9bd62c..ab2b6121a19 100644
--- a/src/test/kotlin/org/rust/lang/core/psi/ProcMacroAttributeTest.kt
+++ b/src/test/kotlin/org/rust/lang/core/psi/ProcMacroAttributeTest.kt
@@ -397,15 +397,13 @@ class ProcMacroAttributeTest : RsTestBase() {
     """, Attr("attr_hardcoded_not_a_macro", 0))
 
     @WithExperimentalFeatures(EVALUATE_BUILD_SCRIPTS)
-    fun `test not a macro if proc macro expansion is disabled`() {
-        setExperimentalFeatureEnabled(PROC_MACROS, false, testRootDisposable)
-        doTest("""
-            use test_proc_macros::attr_as_is;
+    @WithoutExperimentalFeatures(PROC_MACROS, ATTR_PROC_MACROS)
+    fun `test not a macro if proc macro expansion is disabled`() = doTest("""
+        use test_proc_macros::attr_as_is;
 
-            #[attr_as_is]
-            mod foo {}
-        """, None)
-    }
+        #[attr_as_is]
+        mod foo {}
+    """, None)
 
     @WithExperimentalFeatures(EVALUATE_BUILD_SCRIPTS)
     fun `test not a macro if attr macro expansion is disabled 1`() {