Merge pull request #21100 from xdBronch/deprecated-tokens

add semantic tokens for deprecated items
diff --git a/crates/ide/src/syntax_highlighting/highlight.rs b/crates/ide/src/syntax_highlighting/highlight.rs
index 829d127..43594cc 100644
--- a/crates/ide/src/syntax_highlighting/highlight.rs
+++ b/crates/ide/src/syntax_highlighting/highlight.rs
@@ -3,7 +3,7 @@
 use std::ops::ControlFlow;
 
 use either::Either;
-use hir::{AsAssocItem, HasVisibility, Semantics};
+use hir::{AsAssocItem, HasAttrs, HasVisibility, Semantics, sym};
 use ide_db::{
     FxHashMap, RootDatabase, SymbolKind,
     defs::{Definition, IdentClass, NameClass, NameRefClass},
@@ -483,20 +483,25 @@
     is_ref: bool,
 ) -> Highlight {
     let db = sema.db;
-    let mut h = match def {
-        Definition::Macro(m) => Highlight::new(HlTag::Symbol(m.kind(sema.db).into())),
-        Definition::Field(_) | Definition::TupleField(_) => {
-            Highlight::new(HlTag::Symbol(SymbolKind::Field))
+    let (mut h, attrs) = match def {
+        Definition::Macro(m) => {
+            (Highlight::new(HlTag::Symbol(m.kind(sema.db).into())), Some(m.attrs(sema.db)))
         }
-        Definition::Crate(_) => {
-            Highlight::new(HlTag::Symbol(SymbolKind::Module)) | HlMod::CrateRoot
+        Definition::Field(field) => {
+            (Highlight::new(HlTag::Symbol(SymbolKind::Field)), Some(field.attrs(sema.db)))
         }
+        Definition::TupleField(_) => (Highlight::new(HlTag::Symbol(SymbolKind::Field)), None),
+        Definition::Crate(krate) => (
+            Highlight::new(HlTag::Symbol(SymbolKind::Module)) | HlMod::CrateRoot,
+            Some(krate.attrs(sema.db)),
+        ),
         Definition::Module(module) => {
             let mut h = Highlight::new(HlTag::Symbol(SymbolKind::Module));
             if module.is_crate_root() {
                 h |= HlMod::CrateRoot;
             }
-            h
+
+            (h, Some(module.attrs(sema.db)))
         }
         Definition::Function(func) => {
             let mut h = Highlight::new(HlTag::Symbol(SymbolKind::Function));
@@ -544,7 +549,7 @@
                 h |= HlMod::Const;
             }
 
-            h
+            (h, Some(func.attrs(sema.db)))
         }
         Definition::Adt(adt) => {
             let h = match adt {
@@ -553,9 +558,11 @@
                 hir::Adt::Union(_) => HlTag::Symbol(SymbolKind::Union),
             };
 
-            Highlight::new(h)
+            (Highlight::new(h), Some(adt.attrs(sema.db)))
         }
-        Definition::Variant(_) => Highlight::new(HlTag::Symbol(SymbolKind::Variant)),
+        Definition::Variant(variant) => {
+            (Highlight::new(HlTag::Symbol(SymbolKind::Variant)), Some(variant.attrs(sema.db)))
+        }
         Definition::Const(konst) => {
             let mut h = Highlight::new(HlTag::Symbol(SymbolKind::Const)) | HlMod::Const;
             if let Some(item) = konst.as_assoc_item(db) {
@@ -573,9 +580,11 @@
                 }
             }
 
-            h
+            (h, Some(konst.attrs(sema.db)))
         }
-        Definition::Trait(_) => Highlight::new(HlTag::Symbol(SymbolKind::Trait)),
+        Definition::Trait(trait_) => {
+            (Highlight::new(HlTag::Symbol(SymbolKind::Trait)), Some(trait_.attrs(sema.db)))
+        }
         Definition::TypeAlias(type_) => {
             let mut h = Highlight::new(HlTag::Symbol(SymbolKind::TypeAlias));
 
@@ -594,10 +603,12 @@
                 }
             }
 
-            h
+            (h, Some(type_.attrs(sema.db)))
         }
-        Definition::BuiltinType(_) => Highlight::new(HlTag::BuiltinType),
-        Definition::BuiltinLifetime(_) => Highlight::new(HlTag::Symbol(SymbolKind::LifetimeParam)),
+        Definition::BuiltinType(_) => (Highlight::new(HlTag::BuiltinType), None),
+        Definition::BuiltinLifetime(_) => {
+            (Highlight::new(HlTag::Symbol(SymbolKind::LifetimeParam)), None)
+        }
         Definition::Static(s) => {
             let mut h = Highlight::new(HlTag::Symbol(SymbolKind::Static));
 
@@ -608,18 +619,23 @@
                 }
             }
 
-            h
+            (h, Some(s.attrs(sema.db)))
         }
-        Definition::SelfType(_) => Highlight::new(HlTag::Symbol(SymbolKind::Impl)),
-        Definition::GenericParam(it) => match it {
-            hir::GenericParam::TypeParam(_) => Highlight::new(HlTag::Symbol(SymbolKind::TypeParam)),
-            hir::GenericParam::ConstParam(_) => {
-                Highlight::new(HlTag::Symbol(SymbolKind::ConstParam)) | HlMod::Const
-            }
-            hir::GenericParam::LifetimeParam(_) => {
-                Highlight::new(HlTag::Symbol(SymbolKind::LifetimeParam))
-            }
-        },
+        Definition::SelfType(_) => (Highlight::new(HlTag::Symbol(SymbolKind::Impl)), None),
+        Definition::GenericParam(it) => (
+            match it {
+                hir::GenericParam::TypeParam(_) => {
+                    Highlight::new(HlTag::Symbol(SymbolKind::TypeParam))
+                }
+                hir::GenericParam::ConstParam(_) => {
+                    Highlight::new(HlTag::Symbol(SymbolKind::ConstParam)) | HlMod::Const
+                }
+                hir::GenericParam::LifetimeParam(_) => {
+                    Highlight::new(HlTag::Symbol(SymbolKind::LifetimeParam))
+                }
+            },
+            None,
+        ),
         Definition::Local(local) => {
             let tag = if local.is_self(db) {
                 HlTag::Symbol(SymbolKind::SelfParam)
@@ -639,7 +655,7 @@
             if ty.as_callable(db).is_some() || ty.impls_fnonce(db) {
                 h |= HlMod::Callable;
             }
-            h
+            (h, None)
         }
         Definition::ExternCrateDecl(extern_crate) => {
             let mut highlight =
@@ -647,16 +663,20 @@
             if extern_crate.alias(db).is_none() {
                 highlight |= HlMod::Library;
             }
-            highlight
+            (highlight, Some(extern_crate.attrs(sema.db)))
         }
-        Definition::Label(_) => Highlight::new(HlTag::Symbol(SymbolKind::Label)),
-        Definition::BuiltinAttr(_) => Highlight::new(HlTag::Symbol(SymbolKind::BuiltinAttr)),
-        Definition::ToolModule(_) => Highlight::new(HlTag::Symbol(SymbolKind::ToolModule)),
-        Definition::DeriveHelper(_) => Highlight::new(HlTag::Symbol(SymbolKind::DeriveHelper)),
+        Definition::Label(_) => (Highlight::new(HlTag::Symbol(SymbolKind::Label)), None),
+        Definition::BuiltinAttr(_) => {
+            (Highlight::new(HlTag::Symbol(SymbolKind::BuiltinAttr)), None)
+        }
+        Definition::ToolModule(_) => (Highlight::new(HlTag::Symbol(SymbolKind::ToolModule)), None),
+        Definition::DeriveHelper(_) => {
+            (Highlight::new(HlTag::Symbol(SymbolKind::DeriveHelper)), None)
+        }
         Definition::InlineAsmRegOrRegClass(_) => {
-            Highlight::new(HlTag::Symbol(SymbolKind::InlineAsmRegOrRegClass))
+            (Highlight::new(HlTag::Symbol(SymbolKind::InlineAsmRegOrRegClass)), None)
         }
-        Definition::InlineAsmOperand(_) => Highlight::new(HlTag::Symbol(SymbolKind::Local)),
+        Definition::InlineAsmOperand(_) => (Highlight::new(HlTag::Symbol(SymbolKind::Local)), None),
     };
 
     let def_crate = def.krate(db);
@@ -676,6 +696,12 @@
         h |= HlMod::DefaultLibrary;
     }
 
+    if let Some(attrs) = attrs
+        && attrs.by_key(sym::deprecated).exists()
+    {
+        h |= HlMod::Deprecated;
+    }
+
     h
 }
 
@@ -721,6 +747,7 @@
     let is_from_other_crate = krate.as_ref().map_or(false, |krate| def_crate != *krate);
     let is_from_builtin_crate = def_crate.is_builtin(sema.db);
     let is_public = func.visibility(sema.db) == hir::Visibility::Public;
+    let is_deprecated = func.attrs(sema.db).by_key(sym::deprecated).exists();
 
     if is_from_other_crate {
         h |= HlMod::Library;
@@ -732,6 +759,10 @@
         h |= HlMod::DefaultLibrary;
     }
 
+    if is_deprecated {
+        h |= HlMod::Deprecated;
+    }
+
     if let Some(self_param) = func.self_param(sema.db) {
         match self_param.access(sema.db) {
             hir::Access::Shared => h |= HlMod::Reference,
diff --git a/crates/ide/src/syntax_highlighting/html.rs b/crates/ide/src/syntax_highlighting/html.rs
index 75e46b8..ff617b3 100644
--- a/crates/ide/src/syntax_highlighting/html.rs
+++ b/crates/ide/src/syntax_highlighting/html.rs
@@ -121,6 +121,7 @@
 .reference          { font-style: italic; font-weight: bold; }
 .const              { font-weight: bolder; }
 .unsafe             { color: #BC8383; }
+.deprecated         { text-decoration: line-through; }
 
 .invalid_escape_sequence { color: #FC5555; text-decoration: wavy underline; }
 .unresolved_reference    { color: #FC5555; text-decoration: wavy underline; }
diff --git a/crates/ide/src/syntax_highlighting/tags.rs b/crates/ide/src/syntax_highlighting/tags.rs
index 456a612..ca3c3e3 100644
--- a/crates/ide/src/syntax_highlighting/tags.rs
+++ b/crates/ide/src/syntax_highlighting/tags.rs
@@ -67,6 +67,8 @@
     /// `foo` in `fn foo(x: i32)` is a definition, `foo` in `foo(90 + 2)` is
     /// not.
     Definition,
+    /// Used for things with the `#[deprecated]` attribute.
+    Deprecated,
     /// Doc-strings like this one.
     Documentation,
     /// Highlighting injection like rust code in doc strings or ra_fixture.
@@ -224,6 +226,7 @@
         HlMod::CrateRoot,
         HlMod::DefaultLibrary,
         HlMod::Definition,
+        HlMod::Deprecated,
         HlMod::Documentation,
         HlMod::Injected,
         HlMod::IntraDocLink,
@@ -250,6 +253,7 @@
             HlMod::CrateRoot => "crate_root",
             HlMod::DefaultLibrary => "default_library",
             HlMod::Definition => "declaration",
+            HlMod::Deprecated => "deprecated",
             HlMod::Documentation => "documentation",
             HlMod::Injected => "injected",
             HlMod::IntraDocLink => "intra_doc_link",
diff --git a/crates/ide/src/syntax_highlighting/test_data/highlight_asm.html b/crates/ide/src/syntax_highlighting/test_data/highlight_asm.html
index c8ffa9e..100fdd2 100644
--- a/crates/ide/src/syntax_highlighting/test_data/highlight_asm.html
+++ b/crates/ide/src/syntax_highlighting/test_data/highlight_asm.html
@@ -36,6 +36,7 @@
 .reference          { font-style: italic; font-weight: bold; }
 .const              { font-weight: bolder; }
 .unsafe             { color: #BC8383; }
+.deprecated         { text-decoration: line-through; }
 
 .invalid_escape_sequence { color: #FC5555; text-decoration: wavy underline; }
 .unresolved_reference    { color: #FC5555; text-decoration: wavy underline; }
diff --git a/crates/ide/src/syntax_highlighting/test_data/highlight_assoc_functions.html b/crates/ide/src/syntax_highlighting/test_data/highlight_assoc_functions.html
index faace6e..b619138 100644
--- a/crates/ide/src/syntax_highlighting/test_data/highlight_assoc_functions.html
+++ b/crates/ide/src/syntax_highlighting/test_data/highlight_assoc_functions.html
@@ -36,6 +36,7 @@
 .reference          { font-style: italic; font-weight: bold; }
 .const              { font-weight: bolder; }
 .unsafe             { color: #BC8383; }
+.deprecated         { text-decoration: line-through; }
 
 .invalid_escape_sequence { color: #FC5555; text-decoration: wavy underline; }
 .unresolved_reference    { color: #FC5555; text-decoration: wavy underline; }
diff --git a/crates/ide/src/syntax_highlighting/test_data/highlight_attributes.html b/crates/ide/src/syntax_highlighting/test_data/highlight_attributes.html
index d59f4ca..b151ff4 100644
--- a/crates/ide/src/syntax_highlighting/test_data/highlight_attributes.html
+++ b/crates/ide/src/syntax_highlighting/test_data/highlight_attributes.html
@@ -36,6 +36,7 @@
 .reference          { font-style: italic; font-weight: bold; }
 .const              { font-weight: bolder; }
 .unsafe             { color: #BC8383; }
+.deprecated         { text-decoration: line-through; }
 
 .invalid_escape_sequence { color: #FC5555; text-decoration: wavy underline; }
 .unresolved_reference    { color: #FC5555; text-decoration: wavy underline; }
diff --git a/crates/ide/src/syntax_highlighting/test_data/highlight_block_mod_items.html b/crates/ide/src/syntax_highlighting/test_data/highlight_block_mod_items.html
index 711f534..e3daeef 100644
--- a/crates/ide/src/syntax_highlighting/test_data/highlight_block_mod_items.html
+++ b/crates/ide/src/syntax_highlighting/test_data/highlight_block_mod_items.html
@@ -36,6 +36,7 @@
 .reference          { font-style: italic; font-weight: bold; }
 .const              { font-weight: bolder; }
 .unsafe             { color: #BC8383; }
+.deprecated         { text-decoration: line-through; }
 
 .invalid_escape_sequence { color: #FC5555; text-decoration: wavy underline; }
 .unresolved_reference    { color: #FC5555; text-decoration: wavy underline; }
diff --git a/crates/ide/src/syntax_highlighting/test_data/highlight_comments_disabled.html b/crates/ide/src/syntax_highlighting/test_data/highlight_comments_disabled.html
index 4607448..b532630 100644
--- a/crates/ide/src/syntax_highlighting/test_data/highlight_comments_disabled.html
+++ b/crates/ide/src/syntax_highlighting/test_data/highlight_comments_disabled.html
@@ -36,6 +36,7 @@
 .reference          { font-style: italic; font-weight: bold; }
 .const              { font-weight: bolder; }
 .unsafe             { color: #BC8383; }
+.deprecated         { text-decoration: line-through; }
 
 .invalid_escape_sequence { color: #FC5555; text-decoration: wavy underline; }
 .unresolved_reference    { color: #FC5555; text-decoration: wavy underline; }
diff --git a/crates/ide/src/syntax_highlighting/test_data/highlight_const.html b/crates/ide/src/syntax_highlighting/test_data/highlight_const.html
index 9c7324e..5d89147 100644
--- a/crates/ide/src/syntax_highlighting/test_data/highlight_const.html
+++ b/crates/ide/src/syntax_highlighting/test_data/highlight_const.html
@@ -36,6 +36,7 @@
 .reference          { font-style: italic; font-weight: bold; }
 .const              { font-weight: bolder; }
 .unsafe             { color: #BC8383; }
+.deprecated         { text-decoration: line-through; }
 
 .invalid_escape_sequence { color: #FC5555; text-decoration: wavy underline; }
 .unresolved_reference    { color: #FC5555; text-decoration: wavy underline; }
diff --git a/crates/ide/src/syntax_highlighting/test_data/highlight_crate_root.html b/crates/ide/src/syntax_highlighting/test_data/highlight_crate_root.html
index 4613c65..a6e6b16 100644
--- a/crates/ide/src/syntax_highlighting/test_data/highlight_crate_root.html
+++ b/crates/ide/src/syntax_highlighting/test_data/highlight_crate_root.html
@@ -36,6 +36,7 @@
 .reference          { font-style: italic; font-weight: bold; }
 .const              { font-weight: bolder; }
 .unsafe             { color: #BC8383; }
+.deprecated         { text-decoration: line-through; }
 
 .invalid_escape_sequence { color: #FC5555; text-decoration: wavy underline; }
 .unresolved_reference    { color: #FC5555; text-decoration: wavy underline; }
diff --git a/crates/ide/src/syntax_highlighting/test_data/highlight_default_library.html b/crates/ide/src/syntax_highlighting/test_data/highlight_default_library.html
index b1b2c65..2f4a200 100644
--- a/crates/ide/src/syntax_highlighting/test_data/highlight_default_library.html
+++ b/crates/ide/src/syntax_highlighting/test_data/highlight_default_library.html
@@ -36,6 +36,7 @@
 .reference          { font-style: italic; font-weight: bold; }
 .const              { font-weight: bolder; }
 .unsafe             { color: #BC8383; }
+.deprecated         { text-decoration: line-through; }
 
 .invalid_escape_sequence { color: #FC5555; text-decoration: wavy underline; }
 .unresolved_reference    { color: #FC5555; text-decoration: wavy underline; }
diff --git a/crates/ide/src/syntax_highlighting/test_data/highlight_deprecated.html b/crates/ide/src/syntax_highlighting/test_data/highlight_deprecated.html
new file mode 100644
index 0000000..1bf127c
--- /dev/null
+++ b/crates/ide/src/syntax_highlighting/test_data/highlight_deprecated.html
@@ -0,0 +1,71 @@
+
+<style>
+body                { margin: 0; }
+pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padding: 0.4em; }
+
+.lifetime           { color: #DFAF8F; font-style: italic; }
+.label              { color: #DFAF8F; font-style: italic; }
+.comment            { color: #7F9F7F; }
+.documentation      { color: #629755; }
+.intra_doc_link     { font-style: italic; }
+.injected           { opacity: 0.65 ; }
+.struct, .enum      { color: #7CB8BB; }
+.enum_variant       { color: #BDE0F3; }
+.string_literal     { color: #CC9393; }
+.field              { color: #94BFF3; }
+.function           { color: #93E0E3; }
+.parameter          { color: #94BFF3; }
+.text               { color: #DCDCCC; }
+.type               { color: #7CB8BB; }
+.builtin_type       { color: #8CD0D3; }
+.type_param         { color: #DFAF8F; }
+.attribute          { color: #94BFF3; }
+.numeric_literal    { color: #BFEBBF; }
+.bool_literal       { color: #BFE6EB; }
+.macro              { color: #94BFF3; }
+.proc_macro         { color: #94BFF3; text-decoration: underline; }
+.derive             { color: #94BFF3; font-style: italic; }
+.module             { color: #AFD8AF; }
+.value_param        { color: #DCDCCC; }
+.variable           { color: #DCDCCC; }
+.format_specifier   { color: #CC696B; }
+.mutable            { text-decoration: underline; }
+.escape_sequence    { color: #94BFF3; }
+.keyword            { color: #F0DFAF; font-weight: bold; }
+.control            { font-style: italic; }
+.reference          { font-style: italic; font-weight: bold; }
+.const              { font-weight: bolder; }
+.unsafe             { color: #BC8383; }
+.deprecated         { text-decoration: line-through; }
+
+.invalid_escape_sequence { color: #FC5555; text-decoration: wavy underline; }
+.unresolved_reference    { color: #FC5555; text-decoration: wavy underline; }
+</style>
+<pre><code><span class="attribute_bracket attribute">#</span><span class="attribute_bracket attribute">!</span><span class="attribute_bracket attribute">[</span><span class="builtin_attr attribute">deprecated</span><span class="attribute_bracket attribute">]</span>
+<span class="keyword">use</span> <span class="keyword crate_root deprecated public">crate</span> <span class="keyword">as</span> <span class="punctuation">_</span><span class="semicolon">;</span>
+<span class="attribute_bracket attribute">#</span><span class="attribute_bracket attribute">[</span><span class="builtin_attr attribute">deprecated</span><span class="attribute_bracket attribute">]</span>
+<span class="keyword">macro_rules</span><span class="macro_bang">!</span> <span class="macro declaration deprecated public">macro_</span> <span class="brace">{</span>
+    <span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="operator">=</span><span class="operator">&gt;</span> <span class="brace">{</span><span class="brace">}</span><span class="semicolon">;</span>
+<span class="brace">}</span>
+<span class="attribute_bracket attribute">#</span><span class="attribute_bracket attribute">[</span><span class="builtin_attr attribute">deprecated</span><span class="attribute_bracket attribute">]</span>
+<span class="keyword">mod</span> <span class="module declaration deprecated">mod_</span> <span class="brace">{</span><span class="brace">}</span>
+<span class="attribute_bracket attribute">#</span><span class="attribute_bracket attribute">[</span><span class="builtin_attr attribute">deprecated</span><span class="attribute_bracket attribute">]</span>
+<span class="keyword">fn</span> <span class="function declaration deprecated">func</span><span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="brace">{</span><span class="brace">}</span>
+<span class="attribute_bracket attribute">#</span><span class="attribute_bracket attribute">[</span><span class="builtin_attr attribute">deprecated</span><span class="attribute_bracket attribute">]</span>
+<span class="keyword">struct</span> <span class="struct declaration deprecated">Struct</span> <span class="brace">{</span>
+    <span class="attribute_bracket attribute">#</span><span class="attribute_bracket attribute">[</span><span class="builtin_attr attribute">deprecated</span><span class="attribute_bracket attribute">]</span>
+    <span class="field declaration deprecated">field</span><span class="colon">:</span> <span class="builtin_type">u32</span>
+<span class="brace">}</span>
+<span class="attribute_bracket attribute">#</span><span class="attribute_bracket attribute">[</span><span class="builtin_attr attribute">deprecated</span><span class="attribute_bracket attribute">]</span>
+<span class="keyword">enum</span> <span class="enum declaration deprecated">Enum</span> <span class="brace">{</span>
+    <span class="attribute_bracket attribute">#</span><span class="attribute_bracket attribute">[</span><span class="builtin_attr attribute">deprecated</span><span class="attribute_bracket attribute">]</span>
+    <span class="enum_variant declaration deprecated">Variant</span>
+<span class="brace">}</span>
+<span class="attribute_bracket attribute">#</span><span class="attribute_bracket attribute">[</span><span class="builtin_attr attribute">deprecated</span><span class="attribute_bracket attribute">]</span>
+<span class="keyword const">const</span> <span class="constant const declaration deprecated">CONST</span><span class="colon">:</span> <span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="operator">=</span> <span class="parenthesis">(</span><span class="parenthesis">)</span><span class="semicolon">;</span>
+<span class="attribute_bracket attribute">#</span><span class="attribute_bracket attribute">[</span><span class="builtin_attr attribute">deprecated</span><span class="attribute_bracket attribute">]</span>
+<span class="keyword">trait</span> <span class="trait declaration deprecated">Trait</span> <span class="brace">{</span><span class="brace">}</span>
+<span class="attribute_bracket attribute">#</span><span class="attribute_bracket attribute">[</span><span class="builtin_attr attribute">deprecated</span><span class="attribute_bracket attribute">]</span>
+<span class="keyword">type</span> <span class="type_alias declaration deprecated">Alias</span> <span class="operator">=</span> <span class="parenthesis">(</span><span class="parenthesis">)</span><span class="semicolon">;</span>
+<span class="attribute_bracket attribute">#</span><span class="attribute_bracket attribute">[</span><span class="builtin_attr attribute">deprecated</span><span class="attribute_bracket attribute">]</span>
+<span class="keyword">static</span> <span class="static declaration deprecated">STATIC</span><span class="colon">:</span> <span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="operator">=</span> <span class="parenthesis">(</span><span class="parenthesis">)</span><span class="semicolon">;</span></code></pre>
\ No newline at end of file
diff --git a/crates/ide/src/syntax_highlighting/test_data/highlight_doctest.html b/crates/ide/src/syntax_highlighting/test_data/highlight_doctest.html
index d00f279..e1c45e9 100644
--- a/crates/ide/src/syntax_highlighting/test_data/highlight_doctest.html
+++ b/crates/ide/src/syntax_highlighting/test_data/highlight_doctest.html
@@ -36,6 +36,7 @@
 .reference          { font-style: italic; font-weight: bold; }
 .const              { font-weight: bolder; }
 .unsafe             { color: #BC8383; }
+.deprecated         { text-decoration: line-through; }
 
 .invalid_escape_sequence { color: #FC5555; text-decoration: wavy underline; }
 .unresolved_reference    { color: #FC5555; text-decoration: wavy underline; }
diff --git a/crates/ide/src/syntax_highlighting/test_data/highlight_extern_crate.html b/crates/ide/src/syntax_highlighting/test_data/highlight_extern_crate.html
index 5399f83..3a45182 100644
--- a/crates/ide/src/syntax_highlighting/test_data/highlight_extern_crate.html
+++ b/crates/ide/src/syntax_highlighting/test_data/highlight_extern_crate.html
@@ -36,6 +36,7 @@
 .reference          { font-style: italic; font-weight: bold; }
 .const              { font-weight: bolder; }
 .unsafe             { color: #BC8383; }
+.deprecated         { text-decoration: line-through; }
 
 .invalid_escape_sequence { color: #FC5555; text-decoration: wavy underline; }
 .unresolved_reference    { color: #FC5555; text-decoration: wavy underline; }
diff --git a/crates/ide/src/syntax_highlighting/test_data/highlight_general.html b/crates/ide/src/syntax_highlighting/test_data/highlight_general.html
index d058191..fd652f4 100644
--- a/crates/ide/src/syntax_highlighting/test_data/highlight_general.html
+++ b/crates/ide/src/syntax_highlighting/test_data/highlight_general.html
@@ -36,6 +36,7 @@
 .reference          { font-style: italic; font-weight: bold; }
 .const              { font-weight: bolder; }
 .unsafe             { color: #BC8383; }
+.deprecated         { text-decoration: line-through; }
 
 .invalid_escape_sequence { color: #FC5555; text-decoration: wavy underline; }
 .unresolved_reference    { color: #FC5555; text-decoration: wavy underline; }
diff --git a/crates/ide/src/syntax_highlighting/test_data/highlight_injection.html b/crates/ide/src/syntax_highlighting/test_data/highlight_injection.html
index 579c6ce..22f3ba9 100644
--- a/crates/ide/src/syntax_highlighting/test_data/highlight_injection.html
+++ b/crates/ide/src/syntax_highlighting/test_data/highlight_injection.html
@@ -36,6 +36,7 @@
 .reference          { font-style: italic; font-weight: bold; }
 .const              { font-weight: bolder; }
 .unsafe             { color: #BC8383; }
+.deprecated         { text-decoration: line-through; }
 
 .invalid_escape_sequence { color: #FC5555; text-decoration: wavy underline; }
 .unresolved_reference    { color: #FC5555; text-decoration: wavy underline; }
diff --git a/crates/ide/src/syntax_highlighting/test_data/highlight_injection_2.html b/crates/ide/src/syntax_highlighting/test_data/highlight_injection_2.html
index fc2d9a3..5a5d9bd 100644
--- a/crates/ide/src/syntax_highlighting/test_data/highlight_injection_2.html
+++ b/crates/ide/src/syntax_highlighting/test_data/highlight_injection_2.html
@@ -36,6 +36,7 @@
 .reference          { font-style: italic; font-weight: bold; }
 .const              { font-weight: bolder; }
 .unsafe             { color: #BC8383; }
+.deprecated         { text-decoration: line-through; }
 
 .invalid_escape_sequence { color: #FC5555; text-decoration: wavy underline; }
 .unresolved_reference    { color: #FC5555; text-decoration: wavy underline; }
diff --git a/crates/ide/src/syntax_highlighting/test_data/highlight_issue_18089.html b/crates/ide/src/syntax_highlighting/test_data/highlight_issue_18089.html
index 5ef6446..b28818e 100644
--- a/crates/ide/src/syntax_highlighting/test_data/highlight_issue_18089.html
+++ b/crates/ide/src/syntax_highlighting/test_data/highlight_issue_18089.html
@@ -36,6 +36,7 @@
 .reference          { font-style: italic; font-weight: bold; }
 .const              { font-weight: bolder; }
 .unsafe             { color: #BC8383; }
+.deprecated         { text-decoration: line-through; }
 
 .invalid_escape_sequence { color: #FC5555; text-decoration: wavy underline; }
 .unresolved_reference    { color: #FC5555; text-decoration: wavy underline; }
diff --git a/crates/ide/src/syntax_highlighting/test_data/highlight_issue_19357.html b/crates/ide/src/syntax_highlighting/test_data/highlight_issue_19357.html
index 36ed8c5..af27294 100644
--- a/crates/ide/src/syntax_highlighting/test_data/highlight_issue_19357.html
+++ b/crates/ide/src/syntax_highlighting/test_data/highlight_issue_19357.html
@@ -36,6 +36,7 @@
 .reference          { font-style: italic; font-weight: bold; }
 .const              { font-weight: bolder; }
 .unsafe             { color: #BC8383; }
+.deprecated         { text-decoration: line-through; }
 
 .invalid_escape_sequence { color: #FC5555; text-decoration: wavy underline; }
 .unresolved_reference    { color: #FC5555; text-decoration: wavy underline; }
diff --git a/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2015.html b/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2015.html
index 0407e68..d2a53b2 100644
--- a/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2015.html
+++ b/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2015.html
@@ -36,6 +36,7 @@
 .reference          { font-style: italic; font-weight: bold; }
 .const              { font-weight: bolder; }
 .unsafe             { color: #BC8383; }
+.deprecated         { text-decoration: line-through; }
 
 .invalid_escape_sequence { color: #FC5555; text-decoration: wavy underline; }
 .unresolved_reference    { color: #FC5555; text-decoration: wavy underline; }
diff --git a/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2018.html b/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2018.html
index f39d033..d309b47 100644
--- a/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2018.html
+++ b/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2018.html
@@ -36,6 +36,7 @@
 .reference          { font-style: italic; font-weight: bold; }
 .const              { font-weight: bolder; }
 .unsafe             { color: #BC8383; }
+.deprecated         { text-decoration: line-through; }
 
 .invalid_escape_sequence { color: #FC5555; text-decoration: wavy underline; }
 .unresolved_reference    { color: #FC5555; text-decoration: wavy underline; }
diff --git a/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2021.html b/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2021.html
index f39d033..d309b47 100644
--- a/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2021.html
+++ b/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2021.html
@@ -36,6 +36,7 @@
 .reference          { font-style: italic; font-weight: bold; }
 .const              { font-weight: bolder; }
 .unsafe             { color: #BC8383; }
+.deprecated         { text-decoration: line-through; }
 
 .invalid_escape_sequence { color: #FC5555; text-decoration: wavy underline; }
 .unresolved_reference    { color: #FC5555; text-decoration: wavy underline; }
diff --git a/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2024.html b/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2024.html
index 721185a..575c9a6 100644
--- a/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2024.html
+++ b/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2024.html
@@ -36,6 +36,7 @@
 .reference          { font-style: italic; font-weight: bold; }
 .const              { font-weight: bolder; }
 .unsafe             { color: #BC8383; }
+.deprecated         { text-decoration: line-through; }
 
 .invalid_escape_sequence { color: #FC5555; text-decoration: wavy underline; }
 .unresolved_reference    { color: #FC5555; text-decoration: wavy underline; }
diff --git a/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_macros.html b/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_macros.html
index b2c8205..caf66ac 100644
--- a/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_macros.html
+++ b/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_macros.html
@@ -36,6 +36,7 @@
 .reference          { font-style: italic; font-weight: bold; }
 .const              { font-weight: bolder; }
 .unsafe             { color: #BC8383; }
+.deprecated         { text-decoration: line-through; }
 
 .invalid_escape_sequence { color: #FC5555; text-decoration: wavy underline; }
 .unresolved_reference    { color: #FC5555; text-decoration: wavy underline; }
diff --git a/crates/ide/src/syntax_highlighting/test_data/highlight_lifetimes.html b/crates/ide/src/syntax_highlighting/test_data/highlight_lifetimes.html
index 618ea21..b90c962 100644
--- a/crates/ide/src/syntax_highlighting/test_data/highlight_lifetimes.html
+++ b/crates/ide/src/syntax_highlighting/test_data/highlight_lifetimes.html
@@ -36,6 +36,7 @@
 .reference          { font-style: italic; font-weight: bold; }
 .const              { font-weight: bolder; }
 .unsafe             { color: #BC8383; }
+.deprecated         { text-decoration: line-through; }
 
 .invalid_escape_sequence { color: #FC5555; text-decoration: wavy underline; }
 .unresolved_reference    { color: #FC5555; text-decoration: wavy underline; }
diff --git a/crates/ide/src/syntax_highlighting/test_data/highlight_macros.html b/crates/ide/src/syntax_highlighting/test_data/highlight_macros.html
index c314594..b63d5ce 100644
--- a/crates/ide/src/syntax_highlighting/test_data/highlight_macros.html
+++ b/crates/ide/src/syntax_highlighting/test_data/highlight_macros.html
@@ -36,6 +36,7 @@
 .reference          { font-style: italic; font-weight: bold; }
 .const              { font-weight: bolder; }
 .unsafe             { color: #BC8383; }
+.deprecated         { text-decoration: line-through; }
 
 .invalid_escape_sequence { color: #FC5555; text-decoration: wavy underline; }
 .unresolved_reference    { color: #FC5555; text-decoration: wavy underline; }
diff --git a/crates/ide/src/syntax_highlighting/test_data/highlight_module_docs_inline.html b/crates/ide/src/syntax_highlighting/test_data/highlight_module_docs_inline.html
index 9996a87..8d8c713 100644
--- a/crates/ide/src/syntax_highlighting/test_data/highlight_module_docs_inline.html
+++ b/crates/ide/src/syntax_highlighting/test_data/highlight_module_docs_inline.html
@@ -36,6 +36,7 @@
 .reference          { font-style: italic; font-weight: bold; }
 .const              { font-weight: bolder; }
 .unsafe             { color: #BC8383; }
+.deprecated         { text-decoration: line-through; }
 
 .invalid_escape_sequence { color: #FC5555; text-decoration: wavy underline; }
 .unresolved_reference    { color: #FC5555; text-decoration: wavy underline; }
diff --git a/crates/ide/src/syntax_highlighting/test_data/highlight_module_docs_outline.html b/crates/ide/src/syntax_highlighting/test_data/highlight_module_docs_outline.html
index dc9e1de..538f653 100644
--- a/crates/ide/src/syntax_highlighting/test_data/highlight_module_docs_outline.html
+++ b/crates/ide/src/syntax_highlighting/test_data/highlight_module_docs_outline.html
@@ -36,6 +36,7 @@
 .reference          { font-style: italic; font-weight: bold; }
 .const              { font-weight: bolder; }
 .unsafe             { color: #BC8383; }
+.deprecated         { text-decoration: line-through; }
 
 .invalid_escape_sequence { color: #FC5555; text-decoration: wavy underline; }
 .unresolved_reference    { color: #FC5555; text-decoration: wavy underline; }
diff --git a/crates/ide/src/syntax_highlighting/test_data/highlight_operators.html b/crates/ide/src/syntax_highlighting/test_data/highlight_operators.html
index cceb159..20b5065 100644
--- a/crates/ide/src/syntax_highlighting/test_data/highlight_operators.html
+++ b/crates/ide/src/syntax_highlighting/test_data/highlight_operators.html
@@ -36,6 +36,7 @@
 .reference          { font-style: italic; font-weight: bold; }
 .const              { font-weight: bolder; }
 .unsafe             { color: #BC8383; }
+.deprecated         { text-decoration: line-through; }
 
 .invalid_escape_sequence { color: #FC5555; text-decoration: wavy underline; }
 .unresolved_reference    { color: #FC5555; text-decoration: wavy underline; }
diff --git a/crates/ide/src/syntax_highlighting/test_data/highlight_rainbow.html b/crates/ide/src/syntax_highlighting/test_data/highlight_rainbow.html
index e1a8d87..d5401e7 100644
--- a/crates/ide/src/syntax_highlighting/test_data/highlight_rainbow.html
+++ b/crates/ide/src/syntax_highlighting/test_data/highlight_rainbow.html
@@ -36,6 +36,7 @@
 .reference          { font-style: italic; font-weight: bold; }
 .const              { font-weight: bolder; }
 .unsafe             { color: #BC8383; }
+.deprecated         { text-decoration: line-through; }
 
 .invalid_escape_sequence { color: #FC5555; text-decoration: wavy underline; }
 .unresolved_reference    { color: #FC5555; text-decoration: wavy underline; }
diff --git a/crates/ide/src/syntax_highlighting/test_data/highlight_strings.html b/crates/ide/src/syntax_highlighting/test_data/highlight_strings.html
index 47ee2ad..1b05129 100644
--- a/crates/ide/src/syntax_highlighting/test_data/highlight_strings.html
+++ b/crates/ide/src/syntax_highlighting/test_data/highlight_strings.html
@@ -36,6 +36,7 @@
 .reference          { font-style: italic; font-weight: bold; }
 .const              { font-weight: bolder; }
 .unsafe             { color: #BC8383; }
+.deprecated         { text-decoration: line-through; }
 
 .invalid_escape_sequence { color: #FC5555; text-decoration: wavy underline; }
 .unresolved_reference    { color: #FC5555; text-decoration: wavy underline; }
diff --git a/crates/ide/src/syntax_highlighting/test_data/highlight_unsafe.html b/crates/ide/src/syntax_highlighting/test_data/highlight_unsafe.html
index 8339daf..93513f5 100644
--- a/crates/ide/src/syntax_highlighting/test_data/highlight_unsafe.html
+++ b/crates/ide/src/syntax_highlighting/test_data/highlight_unsafe.html
@@ -36,6 +36,7 @@
 .reference          { font-style: italic; font-weight: bold; }
 .const              { font-weight: bolder; }
 .unsafe             { color: #BC8383; }
+.deprecated         { text-decoration: line-through; }
 
 .invalid_escape_sequence { color: #FC5555; text-decoration: wavy underline; }
 .unresolved_reference    { color: #FC5555; text-decoration: wavy underline; }
diff --git a/crates/ide/src/syntax_highlighting/test_data/regression_20952.html b/crates/ide/src/syntax_highlighting/test_data/regression_20952.html
index 2c0250c..fad1b41 100644
--- a/crates/ide/src/syntax_highlighting/test_data/regression_20952.html
+++ b/crates/ide/src/syntax_highlighting/test_data/regression_20952.html
@@ -36,6 +36,7 @@
 .reference          { font-style: italic; font-weight: bold; }
 .const              { font-weight: bolder; }
 .unsafe             { color: #BC8383; }
+.deprecated         { text-decoration: line-through; }
 
 .invalid_escape_sequence { color: #FC5555; text-decoration: wavy underline; }
 .unresolved_reference    { color: #FC5555; text-decoration: wavy underline; }
diff --git a/crates/ide/src/syntax_highlighting/tests.rs b/crates/ide/src/syntax_highlighting/tests.rs
index 58c613e..59e7a66 100644
--- a/crates/ide/src/syntax_highlighting/tests.rs
+++ b/crates/ide/src/syntax_highlighting/tests.rs
@@ -1511,3 +1511,41 @@
         false,
     );
 }
+
+#[test]
+fn test_deprecated_highlighting() {
+    check_highlighting(
+        r#"
+#![deprecated]
+use crate as _;
+#[deprecated]
+macro_rules! macro_ {
+    () => {};
+}
+#[deprecated]
+mod mod_ {}
+#[deprecated]
+fn func() {}
+#[deprecated]
+struct Struct {
+    #[deprecated]
+    field: u32
+}
+#[deprecated]
+enum Enum {
+    #[deprecated]
+    Variant
+}
+#[deprecated]
+const CONST: () = ();
+#[deprecated]
+trait Trait {}
+#[deprecated]
+type Alias = ();
+#[deprecated]
+static STATIC: () = ();
+        "#,
+        expect_file!["./test_data/highlight_deprecated.html"],
+        false,
+    );
+}
diff --git a/crates/rust-analyzer/src/lsp/semantic_tokens.rs b/crates/rust-analyzer/src/lsp/semantic_tokens.rs
index 828118a..9bfdea8 100644
--- a/crates/rust-analyzer/src/lsp/semantic_tokens.rs
+++ b/crates/rust-analyzer/src/lsp/semantic_tokens.rs
@@ -143,6 +143,7 @@
         DECLARATION,
         STATIC,
         DEFAULT_LIBRARY,
+        DEPRECATED,
     }
     custom {
         (ASSOCIATED, "associated"),
diff --git a/crates/rust-analyzer/src/lsp/to_proto.rs b/crates/rust-analyzer/src/lsp/to_proto.rs
index 995e6c4..e585c3f 100644
--- a/crates/rust-analyzer/src/lsp/to_proto.rs
+++ b/crates/rust-analyzer/src/lsp/to_proto.rs
@@ -882,6 +882,7 @@
             HlMod::ControlFlow => mods::CONTROL_FLOW,
             HlMod::CrateRoot => mods::CRATE_ROOT,
             HlMod::DefaultLibrary => mods::DEFAULT_LIBRARY,
+            HlMod::Deprecated => mods::DEPRECATED,
             HlMod::Definition => mods::DECLARATION,
             HlMod::Documentation => mods::DOCUMENTATION,
             HlMod::Injected => mods::INJECTED,