Repository: intellij-rust/intellij-rust
Issue: CLion Spell Checker incorrectly reports 'static as a typo.

## Environment

* **IntelliJ Rust plugin version:** 0.2.123.3132-201
* **Rust toolchain version:** 1.46.0-nightly (feb3536eb 2020-06-09) x86_64-pc-windows-msvc
* **IDE name and version:** CLion 2020.2 EAP (CL-202.5103.16)
* **Operating system:** Windows 10 10.0

## Problem description
'static is incorrectly reported as a typo.

## Steps to reproduce
```rust
impl<A, F> Future for Task<A, F>
where
    F: Future<Output = A> + Send + Sync + 'static,
{
}
```

The spell checker highlights 'static as having a typo. The ' is required by the Rust language.


Changed files:
src/test/kotlin/org/rust/ide/spellchecker/RsSpellCheckerTest.kt, src/main/kotlin/org/rust/ide/spelling/RsNameIdentifierOwnerTokenizer.kt

diff --git a/src/main/kotlin/org/rust/ide/spelling/RsNameIdentifierOwnerTokenizer.kt b/src/main/kotlin/org/rust/ide/spelling/RsNameIdentifierOwnerTokenizer.kt
index cc535dddd..ee9683863 100644
--- a/src/main/kotlin/org/rust/ide/spelling/RsNameIdentifierOwnerTokenizer.kt
+++ b/src/main/kotlin/org/rust/ide/spelling/RsNameIdentifierOwnerTokenizer.kt
@@ -11,7 +11,9 @@ import com.intellij.spellchecker.inspections.IdentifierSplitter
 import com.intellij.spellchecker.tokenizer.TokenConsumer
 import com.intellij.spellchecker.tokenizer.Tokenizer
 import org.rust.lang.core.psi.RS_RAW_PREFIX
+import org.rust.lang.core.psi.RsElementTypes
 import org.rust.lang.core.psi.ext.RsNameIdentifierOwner
+import org.rust.lang.core.psi.ext.elementType
 import org.rust.lang.core.psi.ext.startOffset
 import org.rust.lang.core.psi.unescapeIdentifier
 
@@ -32,10 +34,12 @@ object RsNameIdentifierOwnerTokenizer : Tokenizer<RsNameIdentifierOwner>() {
             element
         }
         val text = identifier.text
-        val unescapedText = text.unescapeIdentifier()
-        if (text.startsWith(RS_RAW_PREFIX)) {
-            offset += 2
+        val (unescapedText, offsetShift) = when {
+            identifier.elementType == RsElementTypes.QUOTE_IDENTIFIER -> text.removePrefix("'") to 1
+            text.startsWith(RS_RAW_PREFIX) -> text.unescapeIdentifier() to 2
+            else -> text to 0
         }
+        offset += offsetShift
         consumer.consumeToken(parent, unescapedText, true, offset, TextRange.allOf(unescapedText), IdentifierSplitter.getInstance())
     }
 }
diff --git a/src/test/kotlin/org/rust/ide/spellchecker/RsSpellCheckerTest.kt b/src/test/kotlin/org/rust/ide/spellchecker/RsSpellCheckerTest.kt
index cc97717c3..fb6dd37ac 100644
--- a/src/test/kotlin/org/rust/ide/spellchecker/RsSpellCheckerTest.kt
+++ b/src/test/kotlin/org/rust/ide/spellchecker/RsSpellCheckerTest.kt
@@ -7,9 +7,10 @@ package org.rust.ide.spellchecker
 
 import com.intellij.spellchecker.inspections.SpellCheckingInspection
 import org.intellij.lang.annotations.Language
-import org.rust.RsTestBase
+import org.rust.ide.inspections.RsInspectionsTestBase
+
+class RsSpellCheckerTest : RsInspectionsTestBase(SpellCheckingInspection::class) {
 
-class RsSpellCheckerTest : RsTestBase() {
     fun `test comments`() = doTest("""// Hello, <TYPO descr="Typo: In word 'Wodrl'">Wodrl</TYPO>!""")
 
     fun `test string literals`() = doTest("""
@@ -38,21 +39,22 @@ class RsSpellCheckerTest : RsTestBase() {
         fn r#<TYPO>wodrl</TYPO>() {}
     """)
 
+    fun `test lifetimes`() = doTest("""
+        const FOO: & 'static str = "123";
+        fn foo<'<TYPO>wodrl</TYPO>>(x: &'<TYPO>wodrl</TYPO> str) {}
+    """)
+
     fun `test do not highlight word from rust bundled dictionary`() = doTest("""
         pub struct Bar;
         impl<T> Deref for Bar {
             type Target = ();
             fn deref(&self) -> &Self::Target { unimplemented!() }
-        }         
+        }
     """)
 
     private fun doTest(@Language("Rust") text: String, processComments: Boolean = true, processLiterals: Boolean = true) {
-        val inspection = SpellCheckingInspection()
-        inspection.processLiterals = processLiterals
-        inspection.processComments = processComments
-
-        myFixture.configureByText("main.rs", text)
-        myFixture.enableInspections(inspection)
-        myFixture.testHighlighting(false, false, true, "main.rs")
+        (inspection as SpellCheckingInspection).processLiterals = processLiterals
+        (inspection as SpellCheckingInspection).processComments = processComments
+        checkByText(text, checkWarn = false, checkWeakWarn = true, checkInfo = false)
     }
 }