about summary refs log tree commit diff
diff options
context:
space:
mode:
authorLukas Wirth <lukastw97@gmail.com>2022-01-07 14:19:11 +0100
committerLukas Wirth <lukastw97@gmail.com>2022-01-07 14:20:27 +0100
commitca4baa6e55258bc2a358b2ba4fbceb119342459f (patch)
tree84153402f8c7161db280bbadde339c64c1e60acc
parent08adce61a1874a725f2682c887392d5a325cab01 (diff)
downloadrust-ca4baa6e55258bc2a358b2ba4fbceb119342459f.tar.gz
rust-ca4baa6e55258bc2a358b2ba4fbceb119342459f.zip
Use `FileAstId<ast::Adt>` in nameres where appropriate instead
-rw-r--r--crates/hir/src/lib.rs8
-rw-r--r--crates/hir/src/semantics.rs20
-rw-r--r--crates/hir/src/semantics/source_to_def.rs23
-rw-r--r--crates/hir_def/src/child_by_source.rs15
-rw-r--r--crates/hir_def/src/item_scope.rs12
-rw-r--r--crates/hir_def/src/keys.rs7
-rw-r--r--crates/hir_def/src/lib.rs2
-rw-r--r--crates/hir_def/src/nameres/collector.rs19
-rw-r--r--crates/hir_def/src/nameres/diagnostics.rs4
-rw-r--r--crates/hir_expand/src/lib.rs21
-rw-r--r--crates/ide/src/syntax_highlighting/html.rs1
-rw-r--r--crates/ide/src/syntax_highlighting/test_data/highlight_assoc_functions.html1
-rw-r--r--crates/ide/src/syntax_highlighting/test_data/highlight_crate_root.html1
-rw-r--r--crates/ide/src/syntax_highlighting/test_data/highlight_default_library.html1
-rw-r--r--crates/ide/src/syntax_highlighting/test_data/highlight_doctest.html1
-rw-r--r--crates/ide/src/syntax_highlighting/test_data/highlight_extern_crate.html1
-rw-r--r--crates/ide/src/syntax_highlighting/test_data/highlight_injection.html1
-rw-r--r--crates/ide/src/syntax_highlighting/test_data/highlight_strings.html1
-rw-r--r--crates/ide/src/syntax_highlighting/test_data/highlight_unsafe.html1
-rw-r--r--crates/ide/src/syntax_highlighting/test_data/highlighting.html11
-rw-r--r--crates/ide/src/syntax_highlighting/test_data/injection.html1
-rw-r--r--crates/ide/src/syntax_highlighting/test_data/rainbow_highlighting.html1
-rw-r--r--crates/ide/src/syntax_highlighting/tests.rs10
23 files changed, 98 insertions, 65 deletions
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs
index ee423573d5c..c6d401a6d65 100644
--- a/crates/hir/src/lib.rs
+++ b/crates/hir/src/lib.rs
@@ -649,8 +649,12 @@ impl Module {
                             let node = ast_id.to_node(db.upcast());
                             ast_id.with_value(SyntaxNodePtr::from(AstPtr::new(&node)))
                         }
-                        MacroCallKind::Derive { ast_id, .. }
-                        | MacroCallKind::Attr { ast_id, .. } => {
+                        MacroCallKind::Derive { ast_id, .. } => {
+                            // FIXME: point to the attribute instead, this creates very large diagnostics
+                            let node = ast_id.to_node(db.upcast());
+                            ast_id.with_value(SyntaxNodePtr::from(AstPtr::new(&node)))
+                        }
+                        MacroCallKind::Attr { ast_id, .. } => {
                             // FIXME: point to the attribute instead, this creates very large diagnostics
                             let node = ast_id.to_node(db.upcast());
                             ast_id.with_value(SyntaxNodePtr::from(AstPtr::new(&node)))
diff --git a/crates/hir/src/semantics.rs b/crates/hir/src/semantics.rs
index b685d260815..444fb4ea54c 100644
--- a/crates/hir/src/semantics.rs
+++ b/crates/hir/src/semantics.rs
@@ -18,7 +18,7 @@ use rustc_hash::{FxHashMap, FxHashSet};
 use smallvec::{smallvec, SmallVec};
 use syntax::{
     algo::skip_trivia_token,
-    ast::{self, HasAttrs, HasGenericParams, HasLoopBody},
+    ast::{self, HasAttrs as _, HasGenericParams, HasLoopBody},
     match_ast, AstNode, AstToken, Direction, SyntaxElement, SyntaxNode, SyntaxNodePtr, SyntaxToken,
     TextSize, T,
 };
@@ -27,9 +27,9 @@ use crate::{
     db::HirDatabase,
     semantics::source_to_def::{ChildContainer, SourceToDefCache, SourceToDefCtx},
     source_analyzer::{resolve_hir_path, SourceAnalyzer},
-    Access, AssocItem, BuiltinAttr, Callable, ConstParam, Crate, Field, Function, HasSource,
-    HirFileId, Impl, InFile, Label, LifetimeParam, Local, MacroDef, Module, ModuleDef, Name, Path,
-    ScopeDef, ToolModule, Trait, Type, TypeAlias, TypeParam, VariantDef,
+    Access, AssocItem, BuiltinAttr, Callable, ConstParam, Crate, Field, Function, HasAttrs as _,
+    HasSource, HirFileId, Impl, InFile, Label, LifetimeParam, Local, MacroDef, Module, ModuleDef,
+    Name, Path, ScopeDef, ToolModule, Trait, Type, TypeAlias, TypeParam, VariantDef,
 };
 
 #[derive(Debug, Clone, PartialEq, Eq)]
@@ -486,7 +486,7 @@ impl<'db> SemanticsImpl<'db> {
         let adt = InFile::new(file_id, &adt);
         let src = InFile::new(file_id, attr.clone());
         self.with_ctx(|ctx| {
-            let res = ctx.attr_to_derive_macro_call(adt, src)?;
+            let (_, res) = ctx.attr_to_derive_macro_call(adt, src)?;
             Some(res.to_vec())
         })
     }
@@ -917,15 +917,14 @@ impl<'db> SemanticsImpl<'db> {
         let tt = derive.token_tree()?;
         let file = self.find_file(derive.syntax());
         let adt = derive.syntax().parent().and_then(ast::Adt::cast)?;
-
+        let adt_def = ToDef::to_def(self, file.with_value(adt.clone()))?;
         let res = self.with_ctx(|ctx| {
-            let attr_def = ctx.attr_to_def(file.with_value(derive.clone()))?;
-            let derives = ctx.attr_to_derive_macro_call(
+            let (attr_id, derives) = ctx.attr_to_derive_macro_call(
                 file.with_value(&adt),
                 file.with_value(derive.clone()),
             )?;
-
-            let mut derive_paths = attr_def.parse_path_comma_token_tree()?;
+            let attrs = adt_def.attrs(self.db);
+            let mut derive_paths = attrs[attr_id].parse_path_comma_token_tree()?;
 
             let derive_idx = tt
                 .syntax()
@@ -1225,7 +1224,6 @@ to_def_impls![
     (crate::Local, ast::SelfParam, self_param_to_def),
     (crate::Label, ast::Label, label_to_def),
     (crate::Adt, ast::Adt, adt_to_def),
-    (crate::Attr, ast::Attr, attr_to_def),
 ];
 
 fn find_root(node: &SyntaxNode) -> SyntaxNode {
diff --git a/crates/hir/src/semantics/source_to_def.rs b/crates/hir/src/semantics/source_to_def.rs
index fbce53eb166..f9c6564d01f 100644
--- a/crates/hir/src/semantics/source_to_def.rs
+++ b/crates/hir/src/semantics/source_to_def.rs
@@ -87,6 +87,7 @@
 
 use base_db::FileId;
 use hir_def::{
+    attr::AttrId,
     child_by_source::ChildBySource,
     dyn_map::DynMap,
     expr::{LabelId, PatId},
@@ -210,19 +211,6 @@ impl SourceToDefCtx<'_, '_> {
             ast::Adt::Union(it) => self.union_to_def(InFile::new(file_id, it)).map(AdtId::UnionId),
         }
     }
-    pub(super) fn attr_to_def(
-        &mut self,
-        InFile { file_id, value }: InFile<ast::Attr>,
-    ) -> Option<crate::Attr> {
-        // FIXME: Use dynmap?
-        let adt = value.syntax().parent().and_then(ast::Adt::cast)?;
-        let attr_pos = ast::HasAttrs::attrs(&adt).position(|it| it == value)?;
-        let attrs = {
-            let def = self.adt_to_def(InFile::new(file_id, adt))?;
-            self.db.attrs(def.into())
-        };
-        attrs.get(attr_pos).cloned()
-    }
     pub(super) fn bind_pat_to_def(
         &mut self,
         src: InFile<ast::IdentPat>,
@@ -254,16 +242,16 @@ impl SourceToDefCtx<'_, '_> {
 
     pub(super) fn item_to_macro_call(&mut self, src: InFile<ast::Item>) -> Option<MacroCallId> {
         let map = self.dyn_map(src.as_ref())?;
-        map[keys::ATTR_MACRO].get(&src).copied()
+        map[keys::ATTR_MACRO_CALL].get(&src).copied()
     }
 
     pub(super) fn attr_to_derive_macro_call(
         &mut self,
         item: InFile<&ast::Adt>,
         src: InFile<ast::Attr>,
-    ) -> Option<&[Option<MacroCallId>]> {
+    ) -> Option<(AttrId, &[Option<MacroCallId>])> {
         let map = self.dyn_map(item)?;
-        map[keys::DERIVE_MACRO].get(&src).map(AsRef::as_ref)
+        map[keys::DERIVE_MACRO_CALL].get(&src).map(|(id, ids)| (*id, &**ids))
     }
 
     fn to_def<Ast: AstNode + 'static, ID: Copy + 'static>(
@@ -328,7 +316,8 @@ impl SourceToDefCtx<'_, '_> {
     }
 
     pub(super) fn macro_to_def(&mut self, src: InFile<ast::Macro>) -> Option<MacroDefId> {
-        let makro = self.dyn_map(src.as_ref()).and_then(|it| it[keys::MACRO].get(&src).copied());
+        let makro =
+            self.dyn_map(src.as_ref()).and_then(|it| it[keys::MACRO_CALL].get(&src).copied());
         if let res @ Some(_) = makro {
             return res;
         }
diff --git a/crates/hir_def/src/child_by_source.rs b/crates/hir_def/src/child_by_source.rs
index 7a9e414ece5..d314b7fc015 100644
--- a/crates/hir_def/src/child_by_source.rs
+++ b/crates/hir_def/src/child_by_source.rs
@@ -6,7 +6,7 @@
 
 use either::Either;
 use hir_expand::HirFileId;
-use syntax::ast::HasAttrs;
+use syntax::ast::HasDocComments;
 
 use crate::{
     db::DefDatabase,
@@ -110,7 +110,7 @@ impl ChildBySource for ItemScope {
                     // FIXME: Do we need to add proc-macros into a PROCMACRO dynmap here?
                     Either::Right(_fn) => return,
                 };
-                res[keys::MACRO].insert(src, makro);
+                res[keys::MACRO_CALL].insert(src, makro);
             }
         });
         self.unnamed_consts().for_each(|konst| {
@@ -120,13 +120,16 @@ impl ChildBySource for ItemScope {
         self.impls().for_each(|imp| add_impl(db, file_id, res, imp));
         self.attr_macro_invocs().for_each(|(ast_id, call_id)| {
             let item = ast_id.with_value(ast_id.to_node(db.upcast()));
-            res[keys::ATTR_MACRO].insert(item, call_id);
+            res[keys::ATTR_MACRO_CALL].insert(item, call_id);
         });
         self.derive_macro_invocs().for_each(|(ast_id, calls)| {
-            let item = ast_id.to_node(db.upcast());
+            let adt = ast_id.to_node(db.upcast());
             for (attr_id, calls) in calls {
-                if let Some(attr) = item.attrs().nth(attr_id.ast_index as usize) {
-                    res[keys::DERIVE_MACRO].insert(ast_id.with_value(attr), calls.into());
+                if let Some(Either::Right(attr)) =
+                    adt.doc_comments_and_attrs().nth(attr_id.ast_index as usize)
+                {
+                    res[keys::DERIVE_MACRO_CALL]
+                        .insert(ast_id.with_value(attr), (attr_id, calls.into()));
                 }
             }
         });
diff --git a/crates/hir_def/src/item_scope.rs b/crates/hir_def/src/item_scope.rs
index 25369fdb268..258d1e0f6c5 100644
--- a/crates/hir_def/src/item_scope.rs
+++ b/crates/hir_def/src/item_scope.rs
@@ -67,7 +67,7 @@ pub struct ItemScope {
     /// The derive macro invocations in this scope, keyed by the owner item over the actual derive attributes
     /// paired with the derive macro invocations for the specific attribute.
     derive_macros:
-        FxHashMap<AstId<ast::Item>, SmallVec<[(AttrId, SmallVec<[Option<MacroCallId>; 1]>); 1]>>,
+        FxHashMap<AstId<ast::Adt>, SmallVec<[(AttrId, SmallVec<[Option<MacroCallId>; 1]>); 1]>>,
 }
 
 pub(crate) static BUILTIN_SCOPE: Lazy<FxHashMap<Name, PerNs>> = Lazy::new(|| {
@@ -204,12 +204,12 @@ impl ItemScope {
 
     pub(crate) fn set_derive_macro_invoc(
         &mut self,
-        item: AstId<ast::Item>,
+        adt: AstId<ast::Adt>,
         call: MacroCallId,
         attr_id: AttrId,
         idx: usize,
     ) {
-        if let Some(derives) = self.derive_macros.get_mut(&item) {
+        if let Some(derives) = self.derive_macros.get_mut(&adt) {
             if let Some((_, invocs)) = derives.iter_mut().find(|&&mut (id, _)| id == attr_id) {
                 invocs[idx] = Some(call);
             }
@@ -221,17 +221,17 @@ impl ItemScope {
     /// independent of their indices.
     pub(crate) fn init_derive_attribute(
         &mut self,
-        item: AstId<ast::Item>,
+        adt: AstId<ast::Adt>,
         attr_id: AttrId,
         len: usize,
     ) {
-        self.derive_macros.entry(item).or_default().push((attr_id, smallvec![None; len]));
+        self.derive_macros.entry(adt).or_default().push((attr_id, smallvec![None; len]));
     }
 
     pub(crate) fn derive_macro_invocs(
         &self,
     ) -> impl Iterator<
-        Item = (AstId<ast::Item>, impl Iterator<Item = (AttrId, &[Option<MacroCallId>])>),
+        Item = (AstId<ast::Adt>, impl Iterator<Item = (AttrId, &[Option<MacroCallId>])>),
     > + '_ {
         self.derive_macros
             .iter()
diff --git a/crates/hir_def/src/keys.rs b/crates/hir_def/src/keys.rs
index 6a7dc13ff17..3a9cf6eb812 100644
--- a/crates/hir_def/src/keys.rs
+++ b/crates/hir_def/src/keys.rs
@@ -7,6 +7,7 @@ use rustc_hash::FxHashMap;
 use syntax::{ast, AstNode, AstPtr};
 
 use crate::{
+    attr::AttrId,
     dyn_map::{DynMap, Policy},
     ConstId, ConstParamId, EnumId, EnumVariantId, FieldId, FunctionId, ImplId, LifetimeParamId,
     StaticId, StructId, TraitId, TypeAliasId, TypeParamId, UnionId,
@@ -31,9 +32,9 @@ pub const TYPE_PARAM: Key<ast::TypeParam, TypeParamId> = Key::new();
 pub const LIFETIME_PARAM: Key<ast::LifetimeParam, LifetimeParamId> = Key::new();
 pub const CONST_PARAM: Key<ast::ConstParam, ConstParamId> = Key::new();
 
-pub const MACRO: Key<ast::Macro, MacroDefId> = Key::new();
-pub const ATTR_MACRO: Key<ast::Item, MacroCallId> = Key::new();
-pub const DERIVE_MACRO: Key<ast::Attr, Box<[Option<MacroCallId>]>> = Key::new();
+pub const MACRO_CALL: Key<ast::Macro, MacroDefId> = Key::new();
+pub const ATTR_MACRO_CALL: Key<ast::Item, MacroCallId> = Key::new();
+pub const DERIVE_MACRO_CALL: Key<ast::Attr, (AttrId, Box<[Option<MacroCallId>]>)> = Key::new();
 
 /// XXX: AST Nodes and SyntaxNodes have identity equality semantics: nodes are
 /// equal if they point to exactly the same object.
diff --git a/crates/hir_def/src/lib.rs b/crates/hir_def/src/lib.rs
index 730523252cf..c38b498b9c6 100644
--- a/crates/hir_def/src/lib.rs
+++ b/crates/hir_def/src/lib.rs
@@ -751,7 +751,7 @@ fn macro_call_as_call_id(
 }
 
 fn derive_macro_as_call_id(
-    item_attr: &AstIdWithPath<ast::Item>,
+    item_attr: &AstIdWithPath<ast::Adt>,
     derive_attr: AttrId,
     db: &dyn db::DefDatabase,
     krate: CrateId,
diff --git a/crates/hir_def/src/nameres/collector.rs b/crates/hir_def/src/nameres/collector.rs
index e8246d4fb9a..dc75dc4d91a 100644
--- a/crates/hir_def/src/nameres/collector.rs
+++ b/crates/hir_def/src/nameres/collector.rs
@@ -8,6 +8,7 @@ use std::iter;
 use base_db::{CrateId, Edition, FileId, ProcMacroId};
 use cfg::{CfgExpr, CfgOptions};
 use hir_expand::{
+    ast_id_map::FileAstId,
     builtin_attr_macro::find_builtin_attr,
     builtin_derive_macro::find_builtin_derive,
     builtin_fn_macro::find_builtin_macro,
@@ -30,8 +31,8 @@ use crate::{
     intern::Interned,
     item_scope::{ImportType, PerNsGlobImports},
     item_tree::{
-        self, Fields, FileItemTreeId, ImportKind, ItemTree, ItemTreeId, MacroCall, MacroDef,
-        MacroRules, Mod, ModItem, ModKind, TreeId,
+        self, Fields, FileItemTreeId, ImportKind, ItemTree, ItemTreeId, ItemTreeNode, MacroCall,
+        MacroDef, MacroRules, Mod, ModItem, ModKind, TreeId,
     },
     macro_call_as_call_id,
     nameres::{
@@ -217,7 +218,7 @@ struct MacroDirective {
 #[derive(Clone, Debug, Eq, PartialEq)]
 enum MacroDirectiveKind {
     FnLike { ast_id: AstIdWithPath<ast::MacroCall>, expand_to: ExpandTo },
-    Derive { ast_id: AstIdWithPath<ast::Item>, derive_attr: AttrId, derive_pos: usize },
+    Derive { ast_id: AstIdWithPath<ast::Adt>, derive_attr: AttrId, derive_pos: usize },
     Attr { ast_id: AstIdWithPath<ast::Item>, attr: Attr, mod_item: ModItem, tree: TreeId },
 }
 
@@ -1129,8 +1130,11 @@ impl DefCollector<'_> {
                     ) {
                         // Resolved to `#[derive]`
 
-                        match mod_item {
-                            ModItem::Struct(_) | ModItem::Union(_) | ModItem::Enum(_) => (),
+                        let item_tree = tree.item_tree(self.db);
+                        let ast_adt_id: FileAstId<ast::Adt> = match *mod_item {
+                            ModItem::Struct(strukt) => item_tree[strukt].ast_id().upcast(),
+                            ModItem::Union(union) => item_tree[union].ast_id().upcast(),
+                            ModItem::Enum(enum_) => item_tree[enum_].ast_id().upcast(),
                             _ => {
                                 let diag = DefDiagnostic::invalid_derive_target(
                                     directive.module_id,
@@ -1140,7 +1144,8 @@ impl DefCollector<'_> {
                                 self.def_map.diagnostics.push(diag);
                                 return recollect_without(self);
                             }
-                        }
+                        };
+                        let ast_id = ast_id.with_value(ast_adt_id);
 
                         match attr.parse_path_comma_token_tree() {
                             Some(derive_macros) => {
@@ -1274,7 +1279,7 @@ impl DefCollector<'_> {
                 if let Some(def) = def_map.exported_proc_macros.get(&loc.def) {
                     if let ProcMacroKind::CustomDerive { helpers } = &def.kind {
                         self.derive_helpers_in_scope
-                            .entry(*ast_id)
+                            .entry(ast_id.map(|it| it.upcast()))
                             .or_default()
                             .extend(helpers.iter().cloned());
                     }
diff --git a/crates/hir_def/src/nameres/diagnostics.rs b/crates/hir_def/src/nameres/diagnostics.rs
index 51e3f18c111..60b8601bdd6 100644
--- a/crates/hir_def/src/nameres/diagnostics.rs
+++ b/crates/hir_def/src/nameres/diagnostics.rs
@@ -33,7 +33,7 @@ pub enum DefDiagnosticKind {
 
     InvalidDeriveTarget { ast: AstId<ast::Item>, id: u32 },
 
-    MalformedDerive { ast: AstId<ast::Item>, id: u32 },
+    MalformedDerive { ast: AstId<ast::Adt>, id: u32 },
 }
 
 #[derive(Debug, PartialEq, Eq)]
@@ -121,7 +121,7 @@ impl DefDiagnostic {
 
     pub(super) fn malformed_derive(
         container: LocalModuleId,
-        ast: AstId<ast::Item>,
+        ast: AstId<ast::Adt>,
         id: AttrId,
     ) -> Self {
         Self {
diff --git a/crates/hir_expand/src/lib.rs b/crates/hir_expand/src/lib.rs
index fe9f7ef2749..3e2e1ba630c 100644
--- a/crates/hir_expand/src/lib.rs
+++ b/crates/hir_expand/src/lib.rs
@@ -121,7 +121,7 @@ pub enum MacroCallKind {
         expand_to: ExpandTo,
     },
     Derive {
-        ast_id: AstId<ast::Item>,
+        ast_id: AstId<ast::Adt>,
         derive_name: Box<str>,
         /// Syntactical index of the invoking `#[derive]` attribute.
         ///
@@ -328,11 +328,10 @@ impl MacroDefId {
 impl MacroCallKind {
     /// Returns the file containing the macro invocation.
     fn file_id(&self) -> HirFileId {
-        match self {
-            MacroCallKind::FnLike { ast_id, .. } => ast_id.file_id,
-            MacroCallKind::Derive { ast_id, .. } | MacroCallKind::Attr { ast_id, .. } => {
-                ast_id.file_id
-            }
+        match *self {
+            MacroCallKind::FnLike { ast_id: InFile { file_id, .. }, .. }
+            | MacroCallKind::Derive { ast_id: InFile { file_id, .. }, .. }
+            | MacroCallKind::Attr { ast_id: InFile { file_id, .. }, .. } => file_id,
         }
     }
 
@@ -341,7 +340,10 @@ impl MacroCallKind {
             MacroCallKind::FnLike { ast_id, .. } => {
                 ast_id.with_value(ast_id.to_node(db).syntax().clone())
             }
-            MacroCallKind::Derive { ast_id, .. } | MacroCallKind::Attr { ast_id, .. } => {
+            MacroCallKind::Derive { ast_id, .. } => {
+                ast_id.with_value(ast_id.to_node(db).syntax().clone())
+            }
+            MacroCallKind::Attr { ast_id, .. } => {
                 ast_id.with_value(ast_id.to_node(db).syntax().clone())
             }
         }
@@ -352,9 +354,8 @@ impl MacroCallKind {
             MacroCallKind::FnLike { ast_id, .. } => {
                 Some(ast_id.to_node(db).token_tree()?.syntax().clone())
             }
-            MacroCallKind::Derive { ast_id, .. } | MacroCallKind::Attr { ast_id, .. } => {
-                Some(ast_id.to_node(db).syntax().clone())
-            }
+            MacroCallKind::Derive { ast_id, .. } => Some(ast_id.to_node(db).syntax().clone()),
+            MacroCallKind::Attr { ast_id, .. } => Some(ast_id.to_node(db).syntax().clone()),
         }
     }
 
diff --git a/crates/ide/src/syntax_highlighting/html.rs b/crates/ide/src/syntax_highlighting/html.rs
index 5af73e6976d..46c55da1f98 100644
--- a/crates/ide/src/syntax_highlighting/html.rs
+++ b/crates/ide/src/syntax_highlighting/html.rs
@@ -80,6 +80,7 @@ pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
 .numeric_literal    { color: #BFEBBF; }
 .bool_literal       { color: #BFE6EB; }
 .macro              { color: #94BFF3; }
+.derive             { color: #94BFF3; font-style: italic; }
 .module             { color: #AFD8AF; }
 .value_param        { color: #DCDCCC; }
 .variable           { color: #DCDCCC; }
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 bf3f1616ac1..645e6c589dd 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
@@ -28,6 +28,7 @@ pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
 .numeric_literal    { color: #BFEBBF; }
 .bool_literal       { color: #BFE6EB; }
 .macro              { color: #94BFF3; }
+.derive             { color: #94BFF3; font-style: italic; }
 .module             { color: #AFD8AF; }
 .value_param        { color: #DCDCCC; }
 .variable           { color: #DCDCCC; }
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 8b4a76453b4..37c8b566829 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
@@ -28,6 +28,7 @@ pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
 .numeric_literal    { color: #BFEBBF; }
 .bool_literal       { color: #BFE6EB; }
 .macro              { color: #94BFF3; }
+.derive             { color: #94BFF3; font-style: italic; }
 .module             { color: #AFD8AF; }
 .value_param        { color: #DCDCCC; }
 .variable           { color: #DCDCCC; }
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 ea68f5f14a5..2f96a1be85c 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
@@ -28,6 +28,7 @@ pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
 .numeric_literal    { color: #BFEBBF; }
 .bool_literal       { color: #BFE6EB; }
 .macro              { color: #94BFF3; }
+.derive             { color: #94BFF3; font-style: italic; }
 .module             { color: #AFD8AF; }
 .value_param        { color: #DCDCCC; }
 .variable           { color: #DCDCCC; }
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 50013c06a75..6e87147e8b3 100644
--- a/crates/ide/src/syntax_highlighting/test_data/highlight_doctest.html
+++ b/crates/ide/src/syntax_highlighting/test_data/highlight_doctest.html
@@ -28,6 +28,7 @@ pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
 .numeric_literal    { color: #BFEBBF; }
 .bool_literal       { color: #BFE6EB; }
 .macro              { color: #94BFF3; }
+.derive             { color: #94BFF3; font-style: italic; }
 .module             { color: #AFD8AF; }
 .value_param        { color: #DCDCCC; }
 .variable           { color: #DCDCCC; }
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 ca869c78be2..3208770d7f1 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
@@ -28,6 +28,7 @@ pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
 .numeric_literal    { color: #BFEBBF; }
 .bool_literal       { color: #BFE6EB; }
 .macro              { color: #94BFF3; }
+.derive             { color: #94BFF3; font-style: italic; }
 .module             { color: #AFD8AF; }
 .value_param        { color: #DCDCCC; }
 .variable           { color: #DCDCCC; }
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 f4134fee4aa..1713306dae2 100644
--- a/crates/ide/src/syntax_highlighting/test_data/highlight_injection.html
+++ b/crates/ide/src/syntax_highlighting/test_data/highlight_injection.html
@@ -28,6 +28,7 @@ pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
 .numeric_literal    { color: #BFEBBF; }
 .bool_literal       { color: #BFE6EB; }
 .macro              { color: #94BFF3; }
+.derive             { color: #94BFF3; font-style: italic; }
 .module             { color: #AFD8AF; }
 .value_param        { color: #DCDCCC; }
 .variable           { color: #DCDCCC; }
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 41cb3903d67..07c7881a1f7 100644
--- a/crates/ide/src/syntax_highlighting/test_data/highlight_strings.html
+++ b/crates/ide/src/syntax_highlighting/test_data/highlight_strings.html
@@ -28,6 +28,7 @@ pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
 .numeric_literal    { color: #BFEBBF; }
 .bool_literal       { color: #BFE6EB; }
 .macro              { color: #94BFF3; }
+.derive             { color: #94BFF3; font-style: italic; }
 .module             { color: #AFD8AF; }
 .value_param        { color: #DCDCCC; }
 .variable           { color: #DCDCCC; }
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 04494283d5d..25bfcb6482f 100644
--- a/crates/ide/src/syntax_highlighting/test_data/highlight_unsafe.html
+++ b/crates/ide/src/syntax_highlighting/test_data/highlight_unsafe.html
@@ -28,6 +28,7 @@ pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
 .numeric_literal    { color: #BFEBBF; }
 .bool_literal       { color: #BFE6EB; }
 .macro              { color: #94BFF3; }
+.derive             { color: #94BFF3; font-style: italic; }
 .module             { color: #AFD8AF; }
 .value_param        { color: #DCDCCC; }
 .variable           { color: #DCDCCC; }
diff --git a/crates/ide/src/syntax_highlighting/test_data/highlighting.html b/crates/ide/src/syntax_highlighting/test_data/highlighting.html
index 3ec6b6a77d3..793f554c637 100644
--- a/crates/ide/src/syntax_highlighting/test_data/highlighting.html
+++ b/crates/ide/src/syntax_highlighting/test_data/highlighting.html
@@ -28,6 +28,7 @@ pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
 .numeric_literal    { color: #BFEBBF; }
 .bool_literal       { color: #BFE6EB; }
 .macro              { color: #94BFF3; }
+.derive             { color: #94BFF3; font-style: italic; }
 .module             { color: #AFD8AF; }
 .value_param        { color: #DCDCCC; }
 .variable           { color: #DCDCCC; }
@@ -89,7 +90,17 @@ pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
 <span class="brace">}</span>
 
 <span class="keyword">use</span> <span class="self_keyword crate_root">self</span><span class="operator">::</span><span class="struct">FooCopy</span><span class="operator">::</span><span class="brace">{</span><span class="self_keyword">self</span> <span class="keyword">as</span> <span class="struct declaration">BarCopy</span><span class="brace">}</span><span class="semicolon">;</span>
+
+<span class="attribute_bracket attribute">#</span><span class="attribute_bracket attribute">[</span><span class="attribute attribute default_library library">derive</span><span class="parenthesis attribute">(</span><span class="derive attribute default_library library">Copy</span><span class="parenthesis attribute">)</span><span class="attribute_bracket attribute">]</span>
+<span class="comment documentation">/// This is a doc comment</span>
+<span class="comment">// This is a normal comment</span>
+<span class="comment documentation">/// This is a doc comment</span>
+<span class="attribute_bracket attribute">#</span><span class="attribute_bracket attribute">[</span><span class="attribute attribute default_library library">derive</span><span class="parenthesis attribute">(</span><span class="derive attribute default_library library">Copy</span><span class="parenthesis attribute">)</span><span class="attribute_bracket attribute">]</span>
+<span class="comment">// This is another normal comment</span>
+<span class="comment documentation">/// This is another doc comment</span>
+<span class="comment">// This is another normal comment</span>
 <span class="attribute_bracket attribute">#</span><span class="attribute_bracket attribute">[</span><span class="attribute attribute default_library library">derive</span><span class="parenthesis attribute">(</span><span class="derive attribute default_library library">Copy</span><span class="parenthesis attribute">)</span><span class="attribute_bracket attribute">]</span>
+<span class="comment">// The reason for these being here is to test AttrIds</span>
 <span class="keyword">struct</span> <span class="struct declaration">FooCopy</span> <span class="brace">{</span>
     <span class="field declaration">x</span><span class="colon">:</span> <span class="builtin_type">u32</span><span class="comma">,</span>
 <span class="brace">}</span>
diff --git a/crates/ide/src/syntax_highlighting/test_data/injection.html b/crates/ide/src/syntax_highlighting/test_data/injection.html
index 28c2bed768a..2e9ad144f19 100644
--- a/crates/ide/src/syntax_highlighting/test_data/injection.html
+++ b/crates/ide/src/syntax_highlighting/test_data/injection.html
@@ -28,6 +28,7 @@ pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
 .numeric_literal    { color: #BFEBBF; }
 .bool_literal       { color: #BFE6EB; }
 .macro              { color: #94BFF3; }
+.derive             { color: #94BFF3; font-style: italic; }
 .module             { color: #AFD8AF; }
 .value_param        { color: #DCDCCC; }
 .variable           { color: #DCDCCC; }
diff --git a/crates/ide/src/syntax_highlighting/test_data/rainbow_highlighting.html b/crates/ide/src/syntax_highlighting/test_data/rainbow_highlighting.html
index 30c4bf40f4e..e0287f11858 100644
--- a/crates/ide/src/syntax_highlighting/test_data/rainbow_highlighting.html
+++ b/crates/ide/src/syntax_highlighting/test_data/rainbow_highlighting.html
@@ -28,6 +28,7 @@ pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
 .numeric_literal    { color: #BFEBBF; }
 .bool_literal       { color: #BFE6EB; }
 .macro              { color: #94BFF3; }
+.derive             { color: #94BFF3; font-style: italic; }
 .module             { color: #AFD8AF; }
 .value_param        { color: #DCDCCC; }
 .variable           { color: #DCDCCC; }
diff --git a/crates/ide/src/syntax_highlighting/tests.rs b/crates/ide/src/syntax_highlighting/tests.rs
index 4e62edc7c16..c9c23318f59 100644
--- a/crates/ide/src/syntax_highlighting/tests.rs
+++ b/crates/ide/src/syntax_highlighting/tests.rs
@@ -62,7 +62,17 @@ impl Foo {
 }
 
 use self::FooCopy::{self as BarCopy};
+
+#[derive(Copy)]
+/// This is a doc comment
+// This is a normal comment
+/// This is a doc comment
+#[derive(Copy)]
+// This is another normal comment
+/// This is another doc comment
+// This is another normal comment
 #[derive(Copy)]
+// The reason for these being here is to test AttrIds
 struct FooCopy {
     x: u32,
 }