Repository: rust-lang/rust-analyzer
Pull request #12003 (2022-04-15 18:18:57)

internal: Remove duplicated crate id field from hir::Type


Patch:
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs
index df17b75c05..06056217fd 100644
--- a/crates/hir/src/lib.rs
+++ b/crates/hir/src/lib.rs
@@ -809,7 +809,7 @@ impl Field {
         };
         let substs = TyBuilder::placeholder_subst(db, generic_def_id);
         let ty = db.field_types(var_id)[self.id].clone().substitute(Interner, &substs);
-        Type::new(db, self.parent.module(db).id.krate(), var_id, ty)
+        Type::new(db, var_id, ty)
     }
 
     pub fn parent_def(&self, _db: &dyn HirDatabase) -> VariantDef {
@@ -850,7 +850,7 @@ impl Struct {
     }
 
     pub fn ty(self, db: &dyn HirDatabase) -> Type {
-        Type::from_def(db, self.id.lookup(db.upcast()).container.krate(), self.id)
+        Type::from_def(db, self.id)
     }
 
     pub fn repr(self, db: &dyn HirDatabase) -> Option<ReprKind> {
@@ -887,7 +887,7 @@ impl Union {
     }
 
     pub fn ty(self, db: &dyn HirDatabase) -> Type {
-        Type::from_def(db, self.id.lookup(db.upcast()).container.krate(), self.id)
+        Type::from_def(db, self.id)
     }
 
     pub fn fields(self, db: &dyn HirDatabase) -> Vec<Field> {
@@ -929,7 +929,7 @@ impl Enum {
     }
 
     pub fn ty(self, db: &dyn HirDatabase) -> Type {
-        Type::from_def(db, self.id.lookup(db.upcast()).container.krate(), self.id)
+        Type::from_def(db, self.id)
     }
 }
 
@@ -1005,7 +1005,7 @@ impl Adt {
     /// general set of completions, but will not look very nice when printed.
     pub fn ty(self, db: &dyn HirDatabase) -> Type {
         let id = AdtId::from(self);
-        Type::from_def(db, id.module(db.upcast()).krate(), id)
+        Type::from_def(db, id)
     }
 
     /// Turns this ADT into a type with the given type parameters. This isn't
@@ -1022,8 +1022,7 @@ impl Adt {
                 }
             })
             .build();
-        let krate = id.module(db.upcast()).krate();
-        Type::new(db, krate, id, ty)
+        Type::new(db, id, ty)
     }
 
     pub fn module(self, db: &dyn HirDatabase) -> Module {
@@ -1213,18 +1212,8 @@ impl DefWithBody {
             acc.push(
                 TypeMismatch {
                     expr,
-                    expected: Type::new(
-                        db,
-                        krate,
-                        DefWithBodyId::from(self),
-                        mismatch.expected.clone(),
-                    ),
-                    actual: Type::new(
-                        db,
-                        krate,
-                        DefWithBodyId::from(self),
-                        mismatch.actual.clone(),
-                    ),
+                    expected: Type::new(db, DefWithBodyId::from(self), mismatch.expected.clone()),
+                    actual: Type::new(db, DefWithBodyId::from(self), mismatch.actual.clone()),
                 }
                 .into(),
             );
@@ -1369,11 +1358,10 @@ impl Function {
     /// Get this function's return type
     pub fn ret_type(self, db: &dyn HirDatabase) -> Type {
         let resolver = self.id.resolver(db.upcast());
-        let krate = self.krate_id(db);
         let ret_type = &db.function_data(self.id).ret_type;
         let ctx = hir_ty::TyLoweringContext::new(db, &resolver);
         let ty = ctx.lower_ty(ret_type);
-        Type::new_with_resolver_inner(db, krate, &resolver, ty)
+        Type::new_with_resolver_inner(db, &resolver, ty)
     }
 
     pub fn self_param(self, db: &dyn HirDatabase) -> Option<SelfParam> {
@@ -1385,7 +1373,6 @@ impl Function {
 
     pub fn assoc_fn_params(self, db: &dyn HirDatabase) -> Vec<Param> {
         let resolver = self.id.resolver(db.upcast());
-        let krate = self.krate_id(db);
         let ctx = hir_ty::TyLoweringContext::new(db, &resolver);
         let environment = db.trait_environment(self.id.into());
         db.function_data(self.id)
@@ -1393,7 +1380,7 @@ impl Function {
             .iter()
             .enumerate()
             .map(|(idx, (_, type_ref))| {
-                let ty = Type { krate, env: environment.clone(), ty: ctx.lower_ty(type_ref) };
+                let ty = Type { env: environment.clone(), ty: ctx.lower_ty(type_ref) };
                 Param { func: self, ty, idx }
             })
             .collect()
@@ -1408,7 +1395,6 @@ impl Function {
 
     pub fn params_without_self(self, db: &dyn HirDatabase) -> Vec<Param> {
         let resolver = self.id.resolver(db.upcast());
-        let krate = self.krate_id(db);
         let ctx = hir_ty::TyLoweringContext::new(db, &resolver);
         let environment = db.trait_environment(self.id.into());
         let skip = if db.function_data(self.id).has_self_param() { 1 } else { 0 };
@@ -1418,7 +1404,7 @@ impl Function {
             .enumerate()
             .skip(skip)
             .map(|(idx, (_, type_ref))| {
-                let ty = Type { krate, env: environment.clone(), ty: ctx.lower_ty(type_ref) };
+                let ty = Type { env: environment.clone(), ty: ctx.lower_ty(type_ref) };
                 Param { func: self, ty, idx }
             })
             .collect()
@@ -1470,10 +1456,6 @@ impl Function {
 
         result
     }
-
-    fn krate_id(self, db: &dyn HirDatabase) -> CrateId {
-        self.id.lookup(db.upcast()).module(db.upcast()).krate()
-    }
 }
 
 // Note: logically, this belongs to `hir_ty`, but we are not using it there yet.
@@ -1575,11 +1557,10 @@ impl SelfParam {
 
     pub fn ty(&self, db: &dyn HirDatabase) -> Type {
         let resolver = self.func.resolver(db.upcast());
-        let krate = self.func.lookup(db.upcast()).container.module(db.upcast()).krate();
         let ctx = hir_ty::TyLoweringContext::new(db, &resolver);
         let environment = db.trait_environment(self.func.into());
 
-        Type { krate, env: environment, ty: ctx.lower_ty(&db.function_data(self.func).params[0].1) }
+        Type { env: environment, ty: ctx.lower_ty(&db.function_data(self.func).params[0].1) }
     }
 }
 
@@ -1610,10 +1591,9 @@ impl Const {
     pub fn ty(self, db: &dyn HirDatabase) -> Type {
         let data = db.const_data(self.id);
         let resolver = self.id.resolver(db.upcast());
-        let krate = self.id.lookup(db.upcast()).container.krate(db);
         let ctx = hir_ty::TyLoweringContext::new(db, &resolver);
         let ty = ctx.lower_ty(&data.type_ref);
-        Type::new_with_resolver_inner(db, krate.id, &resolver, ty)
+        Type::new_with_resolver_inner(db, &resolver, ty)
     }
 
     pub fn eval(self, db: &dyn HirDatabase) -> Result<ComputedExpr, ConstEvalError> {
@@ -1652,10 +1632,9 @@ impl Static {
     pub fn ty(self, db: &dyn HirDatabase) -> Type {
         let data = db.static_data(self.id);
         let resolver = self.id.resolver(db.upcast());
-        let krate = self.id.lookup(db.upcast()).container.module(db.upcast()).krate();
         let ctx = hir_ty::TyLoweringContext::new(db, &resolver);
         let ty = ctx.lower_ty(&data.type_ref);
-        Type::new_with_resolver_inner(db, krate, &resolver, ty)
+        Type::new_with_resolver_inner(db, &resolver, ty)
     }
 }
 
@@ -1727,7 +1706,7 @@ impl TypeAlias {
     }
 
     pub fn ty(self, db: &dyn HirDatabase) -> Type {
-        Type::from_def(db, self.id.lookup(db.upcast()).module(db.upcast()).krate(), self.id)
+        Type::from_def(db, self.id)
     }
 
     pub fn name(self, db: &dyn HirDatabase) -> Name {
@@ -2185,8 +2164,7 @@ impl Local {
         let def = self.parent;
         let infer = db.infer(def);
         let ty = infer[self.pat_id].clone();
-        let krate = def.module(db.upcast()).krate();
-        Type::new(db, krate, def, ty)
+        Type::new(db, def, ty)
     }
 
     pub fn associated_locals(self, db: &dyn HirDatabase) -> Box<[Local]> {
@@ -2373,10 +2351,9 @@ impl TypeParam {
 
     pub fn ty(self, db: &dyn HirDatabase) -> Type {
         let resolver = self.id.parent().resolver(db.upcast());
-        let krate = self.id.parent().module(db.upcast()).krate();
         let ty =
             TyKind::Placeholder(hir_ty::to_placeholder_idx(db, self.id.into())).intern(Interner);
-        Type::new_with_resolver_inner(db, krate, &resolver, ty)
+        Type::new_with_resolver_inner(db, &resolver, ty)
     }
 
     /// FIXME: this only lists trait bounds from the item defining the type
@@ -2398,14 +2375,11 @@ impl TypeParam {
         let params = db.generic_defaults(self.id.parent());
         let local_idx = hir_ty::param_idx(db, self.id.into())?;
         let resolver = self.id.parent().resolver(db.upcast());
-        let krate = self.id.parent().module(db.upcast()).krate();
         let ty = params.get(local_idx)?.clone();
         let subst = TyBuilder::placeholder_subst(db, self.id.parent());
         let ty = ty.substitute(Interner, &subst_prefix(&subst, local_idx));
         match ty.data(Interner) {
-            GenericArgData::Ty(x) => {
-                Some(Type::new_with_resolver_inner(db, krate, &resolver, x.clone()))
-            }
+            GenericArgData::Ty(x) => Some(Type::new_with_resolver_inner(db, &resolver, x.clone())),
             _ => None,
         }
     }
@@ -2461,9 +2435,7 @@ impl ConstParam {
     }
 
     pub fn ty(self, db: &dyn HirDatabase) -> Type {
-        let def = self.id.parent();
-        let krate = def.module(db.upcast()).krate();
-        Type::new(db, krate, def, db.const_param_ty(self.id))
+        Type::new(db, self.id.parent(), db.const_param_ty(self.id))
     }
 }
 
@@ -2522,8 +2494,8 @@ impl Impl {
         inherent.all_impls().chain(trait_.all_impls()).map(Self::from).collect()
     }
 
-    pub fn all_for_type(db: &dyn HirDatabase, Type { krate, ty, .. }: Type) -> Vec<Impl> {
-        let def_crates = match method_resolution::def_crates(db, &ty, krate) {
+    pub fn all_for_type(db: &dyn HirDatabase, Type { ty, env }: Type) -> Vec<Impl> {
+        let def_crates = match method_resolution::def_crates(db, &ty, env.krate) {
             Some(def_crates) => def_crates,
             None => return Vec::new(),
         };
@@ -2589,10 +2561,9 @@ impl Impl {
     pub fn self_ty(self, db: &dyn HirDatabase) -> Type {
         let impl_data = db.impl_data(self.id);
         let resolver = self.id.resolver(db.upcast());
-        let krate = self.id.lookup(db.upcast()).container.krate();
         let ctx = hir_ty::TyLoweringContext::new(db, &resolver);
         let ty = ctx.lower_ty(&impl_data.self_ty);
-        Type::new_with_resolver_inner(db, krate, &resolver, ty)
+        Type::new_with_resolver_inner(db, &resolver, ty)
     }
 
     pub fn items(self, db: &dyn HirDatabase) -> Vec<AssocItem> {
@@ -2615,31 +2586,29 @@ impl Impl {
 
 #[derive(Clone, PartialEq, Eq, Debug)]
 pub struct Type {
-    krate: CrateId, // FIXME this is probably redundant with the TraitEnvironment
     env: Arc<TraitEnvironment>,
     ty: Ty,
 }
 
 impl Type {
     pub(crate) fn new_with_resolver(db: &dyn HirDatabase, resolver: &Resolver, ty: Ty) -> Type {
-        let krate = resolver.krate();
-        Type::new_with_resolver_inner(db, krate, resolver, ty)
+        Type::new_with_resolver_inner(db, resolver, ty)
     }
 
     pub(crate) fn new_with_resolver_inner(
         db: &dyn HirDatabase,
-        krate: CrateId,
         resolver: &Resolver,
         ty: Ty,
     ) -> Type {
-        let environment = resolver
-            .generic_def()
-            .map_or_else(|| Arc::new(TraitEnvironment::empty(krate)), |d| db.trait_environment(d));
-        Type { krate, env: environment, ty }
+        let environment = resolver.generic_def().map_or_else(
+            || Arc::new(TraitEnvironment::empty(resolver.krate())),
+            |d| db.trait_environment(d),
+        );
+        Type { env: environment, ty }
     }
 
     pub(crate) fn new_for_crate(krate: CrateId, ty: Ty) -> Type {
-        Type { krate, env: Arc::new(TraitEnvironment::empty(krate)), ty }
+        Type { env: Arc::new(TraitEnvironment::empty(krate)), ty }
     }
 
     pub fn reference(inner: &Type, m: Mutability) -> Type {
@@ -2653,25 +2622,22 @@ impl Type {
         )
     }
 
-    fn new(db: &dyn HirDatabase, krate: CrateId, lexical_env: impl HasResolver, ty: Ty) -> Type {
+    fn new(db: &dyn HirDatabase, lexical_env: impl HasResolver, ty: Ty) -> Type {
         let resolver = lexical_env.resolver(db.upcast());
-        let environment = resolver
-            .generic_def()
-            .map_or_else(|| Arc::new(TraitEnvironment::empty(krate)), |d| db.trait_environment(d));
-        Type { krate, env: environment, ty }
+        let environment = resolver.generic_def().map_or_else(
+            || Arc::new(TraitEnvironment::empty(resolver.krate())),
+            |d| db.trait_environment(d),
+        );
+        Type { env: environment, ty }
     }
 
-    fn from_def(
-        db: &dyn HirDatabase,
-        krate: CrateId,
-        def: impl HasResolver + Into<TyDefId>,
-    ) -> Type {
+    fn from_def(db: &dyn HirDatabase, def: impl HasResolver + Into<TyDefId>) -> Type {
         let ty = TyBuilder::def_ty(db, def.into()).fill_with_unknown().build();
-        Type::new(db, krate, def, ty)
+        Type::new(db, def, ty)
     }
 
     pub fn new_slice(ty: Type) -> Type {
-        Type { krate: ty.krate, env: ty.env, ty: TyBuilder::slice(ty.ty) }
+        Type { env: ty.env, ty: TyBuilder::slice(ty.ty) }
     }
 
     pub fn is_unit(&self) -> bool {
@@ -2727,7 +2693,7 @@ impl Type {
     /// This function is used in `.await` syntax completion.
     pub fn impls_future(&self, db: &dyn HirDatabase) -> bool {
         let std_future_trait = db
-            .lang_item(self.krate, SmolStr::new_inline("future_trait"))
+            .lang_item(self.env.krate, SmolStr::new_inline("future_trait"))
             .and_then(|it| it.as_trait());
         let std_future_trait = match std_future_trait {
             Some(it) => it,
@@ -2744,7 +2710,7 @@ impl Type {
     /// This function can be used to check if a particular type is callable, since FnOnce is a
     /// supertrait of Fn and FnMut, so all callable types implements at least FnOnce.
     pub fn impls_fnonce(&self, db: &dyn HirDatabase) -> bool {
-        let fnonce_trait = match FnTrait::FnOnce.get_id(db, self.krate) {
+        let fnonce_trait = match FnTrait::FnOnce.get_id(db, self.env.krate) {
             Some(it) => it,
             None => return false,
         };
@@ -2780,7 +2746,7 @@ impl Type {
             binders: CanonicalVarKinds::empty(Interner),
         };
 
-        db.trait_solve(self.krate, goal).is_some()
+        db.trait_solve(self.env.krate, goal).is_some()
     }
 
     pub fn normalize_trait_assoc_type(
@@ -2815,7 +2781,7 @@ impl Type {
             [TyVariableKind::General].into_iter(),
         );
 
-        match db.trait_solve(self.krate, goal)? {
+        match db.trait_solve(self.env.krate, goal)? {
             Solution::Unique(s) => s
                 .value
                 .subst
@@ -2827,7 +2793,7 @@ impl Type {
     }
 
     pub fn is_copy(&self, db: &dyn HirDatabase) -> bool {
-        let lang_item = db.lang_item(self.krate, SmolStr::new_inline("copy"));
+        let lang_item = db.lang_item(self.env.krate, SmolStr::new_inline("copy"));
         let copy_trait = match lang_item {
             Some(LangItemTarget::TraitId(it)) => it,
             _ => return false,
@@ -3170,7 +3136,7 @@ impl Type {
     }
 
     fn derived(&self, ty: Ty) -> Type {
-        Type { krate: self.krate, env: self.env.clone(), ty }
+        Type { env: self.env.clone(), ty }
     }
 
     pub fn walk(&self, db: &dyn HirDatabase, mut cb: impl FnMut(Type)) {
@@ -3480,7 +3446,7 @@ impl HasCrate for TypeAlias {
 
 impl HasCrate for Type {
     fn krate(&self, _db: &dyn HirDatabase) -> Crate {
-        self.krate.into()
+        self.env.krate.into()
     }
 }
 
diff --git a/crates/hir/src/semantics.rs b/crates/hir/src/semantics.rs
index 8b565ef1fa..246b93723b 100644
--- a/crates/hir/src/semantics.rs
+++ b/crates/hir/src/semantics.rs
@@ -208,16 +208,6 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> {
         self.imp.descend_into_macros(token)
     }
 
-    /// Descend the token into macrocalls to all its mapped counterparts.
-    ///
-    /// Returns the original non descended token if none of the mapped counterparts have the same syntax kind.
-    pub fn descend_into_macros_with_same_kind(
-        &self,
-        token: SyntaxToken,
-    ) -> SmallVec<[SyntaxToken; 1]> {
-        self.imp.descend_into_macros_with_same_kind(token)
-    }
-
     /// Maps a node down by mapping its first and last token down.
     pub fn descend_node_into_attributes<N: AstNode>(&self, node: N) -> SmallVec<[N; 1]> {
         self.imp.descend_node_into_attributes(node)
@@ -609,19 +599,25 @@ impl<'db> SemanticsImpl<'db> {
         };
 
         if first == last {
-            self.descend_into_macros_impl(first, &mut |InFile { value, .. }| {
-                if let Some(node) = value.ancestors().find_map(N::cast) {
-                    res.push(node)
-                }
-                false
-            });
+            self.descend_into_macros_impl(
+                first,
+                &mut |InFile { value, .. }| {
+                    if let Some(node) = value.ancestors().find_map(N::cast) {
+                        res.push(node)
+                    }
+                },
+                false,
+            );
         } else {
             // Descend first and last token, then zip them to look for the node they belong to
             let mut scratch: SmallVec<[_; 1]> = smallvec![];
-            self.descend_into_macros_impl(first, &mut |token| {
-                scratch.push(token);
-                false
-            });
+            self.descend_into_macros_impl(
+                first,
+                &mut |token| {
+                    scratch.push(token);
+                },
+                false,
+            );
 
             let mut scratch = scratch.into_iter();
             self.descend_into_macros_impl(
@@ -642,8 +638,8 @@ impl<'db> SemanticsImpl<'db> {
                             }
                         }
                     }
-                    false
                 },
+                false,
             );
         }
         res
@@ -651,41 +647,21 @@ impl<'db> SemanticsImpl<'db> {
 
     fn descend_into_macros(&self, token: SyntaxToken) -> SmallVec<[SyntaxToken; 1]> {
         let mut res = smallvec![];
-        self.descend_into_macros_impl(token, &mut |InFile { value, .. }| {
-            res.push(value);
-            false
-        });
-        res
-    }
-
-    fn descend_into_macros_with_same_kind(&self, token: SyntaxToken) -> SmallVec<[SyntaxToken; 1]> {
-        let kind = token.kind();
-        let mut res = smallvec![];
-        self.descend_into_macros_impl(token.clone(), &mut |InFile { value, .. }| {
-            if value.kind() == kind {
-                res.push(value);
-            }
-            false
-        });
-        if res.is_empty() {
-            res.push(token);
-        }
+        self.descend_into_macros_impl(token, &mut |InFile { value, .. }| res.push(value), false);
         res
     }
 
     fn descend_into_macros_single(&self, token: SyntaxToken) -> SyntaxToken {
         let mut res = token.clone();
-        self.descend_into_macros_impl(token, &mut |InFile { value, .. }| {
-            res = value;
-            true
-        });
+        self.descend_into_macros_impl(token, &mut |InFile { value, .. }| res = value, true);
         res
     }
 
     fn descend_into_macros_impl(
         &self,
         token: SyntaxToken,
-        f: &mut dyn FnMut(InFile<SyntaxToken>) -> bool,
+        f: &mut dyn FnMut(InFile<SyntaxToken>),
+        single: bool,
     ) {
         let _p = profile::span("descend_into_macros");
         let parent = match token.parent() {
@@ -712,11 +688,16 @@ impl<'db> SemanticsImpl<'db> {
                     self.cache(value, file_id);
                 }
 
-                let mapped_tokens = expansion_info.map_token_down(self.db.upcast(), item, token)?;
-                let len = stack.len();
+                let mut mapped_tokens =
+                    expansion_info.map_token_down(self.db.upcast(), item, token)?;
 
+                let len = stack.len();
                 // requeue the tokens we got from mapping our current token down
-                stack.extend(mapped_tokens);
+                if single {
+                    stack.extend(mapped_tokens.next());
+                } else {
+                    stack.extend(mapped_tokens);
+                }
                 // if the length changed we have found a mapping for the token
                 (stack.len() != len).then(|| ())
             };
@@ -806,8 +787,8 @@ impl<'db> SemanticsImpl<'db> {
             })()
             .is_none();
 
-            if was_not_remapped && f(token) {
-                break;
+            if was_not_remapped {
+                f(token)
             }
         }
     }
diff --git a/crates/hir/src/source_analyzer.rs b/crates/hir/src/source_analyzer.rs
index 89ba16d087..35aef32824 100644
--- a/crates/hir/src/source_analyzer.rs
+++ b/crates/hir/src/source_analyzer.rs
@@ -44,7 +44,6 @@ use crate::{
     Field, Function, Local, Macro, ModuleDef, Static, Struct, ToolModule, Trait, Type, TypeAlias,
     Variant,
 };
-use base_db::CrateId;
 
 /// `SourceAnalyzer` is a convenience wrapper which exposes HIR API in terms of
 /// original source files. It should not be used inside the HIR itself.
@@ -414,7 +413,6 @@ impl SourceAnalyzer {
         db: &dyn HirDatabase,
         literal: &ast::RecordExpr,
     ) -> Option<Vec<(Field, Type)>> {
-        let krate = self.resolver.krate();
         let body = self.body()?;
         let infer = self.infer.as_ref()?;
 
@@ -423,7 +421,7 @@ impl SourceAnalyzer {
 
         let (variant, missing_fields, _exhaustive) =
             record_literal_missing_fields(db, infer, expr_id, &body[expr_id])?;
-        let res = self.missing_fields(db, krate, substs, variant, missing_fields);
+        let res = self.missing_fields(db, substs, variant, missing_fields);
         Some(res)
     }
 
@@ -432,7 +430,6 @@ impl SourceAnalyzer {
         db: &dyn HirDatabase,
         pattern: &ast::RecordPat,
     ) -> Option<Vec<(Field, Type)>> {
-        let krate = self.resolver.krate();
         let body = self.body()?;
         let infer = self.infer.as_ref()?;
 
@@ -441,14 +438,13 @@ impl SourceAnalyzer {
 
         let (variant, missing_fields, _exhaustive) =
             record_pattern_missing_fields(db, infer, pat_id, &body[pat_id])?;
-        let res = self.missing_fields(db, krate, substs, variant, missing_fields);
+        let res = self.missing_fields(db, substs, variant, missing_fields);
         Some(res)
     }
 
     fn missing_fields(
         &self,
         db: &dyn HirDatabase,
-        krate: CrateId,
         substs: &Substitution,
         variant: VariantId,
         missing_fields: Vec<LocalFieldId>,
@@ -460,7 +456,7 @@ impl SourceAnalyzer {
             .map(|local_id| {
                 let field = FieldId { parent: variant, local_id };
                 let ty = field_types[local_id].clone().substitute(Interner, substs);
-                (field.into(), Type::new_with_resolver_inner(db, krate, &self.resolver, ty))
+                (field.into(), Type::new_with_resolver_inner(db, &self.resolver, ty))
             })
             .collect()
     }
diff --git a/crates/hir_def/src/resolver.rs b/crates/hir_def/src/resolver.rs
index 2a990765ea..f3dcdcfa4a 100644
--- a/crates/hir_def/src/resolver.rs
+++ b/crates/hir_def/src/resolver.rs
@@ -448,7 +448,13 @@ impl Resolver {
     }
 
     pub fn krate(&self) -> CrateId {
-        self.module_scope().0.krate()
+        self.scopes
+            .get(0)
+            .and_then(|scope| match scope {
+                Scope::ModuleScope(m) => Some(m.def_map.krate()),
+                _ => None,
+            })
+            .expect("module scope invariant violated")
     }
 
     pub fn where_predicates_in_scope(
diff --git a/crates/ide/src/references.rs b/crates/ide/src/references.rs
index fe9c5bd785..73f736dffe 100644
--- a/crates/ide/src/references.rs
+++ b/crates/ide/src/references.rs
@@ -20,9 +20,7 @@ use rustc_hash::FxHashMap;
 use syntax::{
     algo::find_node_at_offset,
     ast::{self, HasName},
-    match_ast, AstNode,
-    SyntaxKind::*,
-    SyntaxNode, TextRange, TextSize, T,
+    match_ast, AstNode, SyntaxNode, TextRange, TextSize, T,
 };
 
 use crate::{FilePosition, NavigationTarget, TryToNav};
@@ -106,7 +104,7 @@ pub(crate) fn find_all_refs(
         }
         None => {
             let search = make_searcher(false);
-            Some(find_defs(sema, &syntax, position.offset)?.into_iter().map(search).collect())
+            Some(find_defs(sema, &syntax, position.offset).into_iter().map(search).collect())
         }
     }
 }
@@ -115,47 +113,31 @@ pub(crate) fn find_defs<'a>(
     sema: &'a Semantics<RootDatabase>,
     syntax: &SyntaxNode,
     offset: TextSize,
-) -> Option<impl Iterator<Item = Definition> + 'a> {
-    let token = syntax.token_at_offset(offset).find(|t| {
-        matches!(
-            t.kind(),
-            IDENT | INT_NUMBER | LIFETIME_IDENT | T![self] | T![super] | T![crate] | T![Self]
-        )
-    });
-    token.map(|token| {
-        sema.descend_into_macros_with_same_kind(token)
-            .into_iter()
-            .filter_map(|it| ast::NameLike::cast(it.parent()?))
-            .filter_map(move |name_like| {
-                let def = match name_like {
-                    ast::NameLike::NameRef(name_ref) => {
-                        match NameRefClass::classify(sema, &name_ref)? {
-                            NameRefClass::Definition(def) => def,
-                            NameRefClass::FieldShorthand { local_ref, field_ref: _ } => {
-                                Definition::Local(local_ref)
-                            }
-                        }
-                    }
-                    ast::NameLike::Name(name) => match NameClass::classify(sema, &name)? {
-                        NameClass::Definition(it) | NameClass::ConstReference(it) => it,
-                        NameClass::PatFieldShorthand { local_def, field_ref: _ } => {
-                            Definition::Local(local_def)
-                        }
-                    },
-                    ast::NameLike::Lifetime(lifetime) => {
-                        NameRefClass::classify_lifetime(sema, &lifetime)
-                            .and_then(|class| match class {
-                                NameRefClass::Definition(it) => Some(it),
-                                _ => None,
-                            })
-                            .or_else(|| {
-                                NameClass::classify_lifetime(sema, &lifetime)
-                                    .and_then(NameClass::defined)
-                            })?
-                    }
-                };
-                Some(def)
-            })
+) -> impl Iterator<Item = Definition> + 'a {
+    sema.find_nodes_at_offset_with_descend(syntax, offset).filter_map(move |name_like| {
+        let def = match name_like {
+            ast::NameLike::NameRef(name_ref) => match NameRefClass::classify(sema, &name_ref)? {
+                NameRefClass::Definition(def) => def,
+                NameRefClass::FieldShorthand { local_ref, field_ref: _ } => {
+                    Definition::Local(local_ref)
+                }
+            },
+            ast::NameLike::Name(name) => match NameClass::classify(sema, &name)? {
+                NameClass::Definition(it) | NameClass::ConstReference(it) => it,
+                NameClass::PatFieldShorthand { local_def, field_ref: _ } => {
+                    Definition::Local(local_def)
+                }
+            },
+            ast::NameLike::Lifetime(lifetime) => NameRefClass::classify_lifetime(sema, &lifetime)
+                .and_then(|class| match class {
+                    NameRefClass::Definition(it) => Some(it),
+                    _ => None,
+                })
+                .or_else(|| {
+                    NameClass::classify_lifetime(sema, &lifetime).and_then(NameClass::defined)
+                })?,
+        };
+        Some(def)
     })
 }
 
diff --git a/crates/ide/src/runnables.rs b/crates/ide/src/runnables.rs
index 88e17fadac..1c455c5f30 100644
--- a/crates/ide/src/runnables.rs
+++ b/crates/ide/src/runnables.rs
@@ -226,11 +226,7 @@ fn find_related_tests(
     search_scope: Option<SearchScope>,
     tests: &mut FxHashSet<Runnable>,
 ) {
-    // FIXME: why is this using references::find_defs, this should use ide_db::search
-    let defs = match references::find_defs(sema, syntax, position.offset) {
-        Some(defs) => defs,
-        None => return,
-    };
+    let defs = references::find_defs(sema, syntax, position.offset);
     for def in defs {
         let defs = def
             .usages(sema)
diff --git a/crates/ide/src/syntax_highlighting/highlight.rs b/crates/ide/src/syntax_highlighting/highlight.rs
index 3fd0748172..866bba7d1b 100644
--- a/crates/ide/src/syntax_highlighting/highlight.rs
+++ b/crates/ide/src/syntax_highlighting/highlight.rs
@@ -98,7 +98,7 @@ fn punctuation(sema: &Semantics<RootDatabase>, token: SyntaxToken, kind: SyntaxK
             }
         }
         (T![::] | T![->] | T![=>] | T![..] | T![=] | T![@] | T![.], _) => HlOperator::Other.into(),
-        (T![!], MACRO_CALL | MACRO_RULES) => HlPunct::MacroBang.into(),
+        (T![!], MACRO_CALL) => HlPunct::MacroBang.into(),
         (T![!], NEVER_TYPE) => HlTag::BuiltinType.into(),
         (T![!], PREFIX_EXPR) => HlOperator::Logical.into(),
         (T![*], PTR_TYPE) => HlTag::Keyword.into(),
diff --git a/crates/rust-analyzer/src/global_state.rs b/crates/rust-analyzer/src/global_state.rs
index 9fc3e30199..8b47ef0283 100644
--- a/crates/rust-analyzer/src/global_state.rs
+++ b/crates/rust-analyzer/src/global_state.rs
@@ -180,7 +180,7 @@ impl GlobalState {
         // A file was added or deleted
         let mut has_structure_changes = false;
 
-        let (change, changed_files) = {
+        let change = {
             let mut change = Change::new();
             let (vfs, line_endings_map) = &mut *self.vfs.write();
             let changed_files = vfs.take_changes();
@@ -188,7 +188,17 @@ impl GlobalState {
                 return false;
             }
 
-            for file in &changed_files {
+            for file in changed_files {
+                if !file.is_created_or_deleted() {
+                    // FIXME: https://github.com/rust-analyzer/rust-analyzer/issues/11357
+                    let crates = self.analysis_host.raw_database().relevant_crates(file.file_id);
+                    let crate_graph = self.analysis_host.raw_database().crate_graph();
+
+                    if crates.iter().any(|&krate| !crate_graph[krate].proc_macro.is_empty()) {
+                        self.proc_macro_changed = true;
+                    }
+                }
+
                 if let Some(path) = vfs.file_path(file.file_id).as_path() {
                     let path = path.to_path_buf();
                     if reload::should_refresh_for_change(&path, file.change_kind) {
@@ -202,11 +212,14 @@ impl GlobalState {
 
                 let text = if file.exists() {
                     let bytes = vfs.file_contents(file.file_id).to_vec();
-                    String::from_utf8(bytes).ok().and_then(|text| {
-                        let (text, line_endings) = LineEndings::normalize(text);
-                        line_endings_map.insert(file.file_id, line_endings);
-                        Some(Arc::new(text))
-                    })
+                    match String::from_utf8(bytes).ok() {
+                        Some(text) => {
+                            let (text, line_endings) = LineEndings::normalize(text);
+                            line_endings_map.insert(file.file_id, line_endings);
+                            Some(Arc::new(text))
+                        }
+                        None => None,
+                    }
                 } else {
                     None
                 };
@@ -216,19 +229,10 @@ impl GlobalState {
                 let roots = self.source_root_config.partition(vfs);
                 change.set_roots(roots);
             }
-            (change, changed_files)
+            change
         };
 
         self.analysis_host.apply_change(change);
-
-        let raw_database = &self.analysis_host.raw_database();
-        self.proc_macro_changed =
-            changed_files.iter().filter(|file| !file.is_created_or_deleted()).any(|file| {
-                let crates = raw_database.relevant_crates(file.file_id);
-                let crate_graph = raw_database.crate_graph();
-
-                crates.iter().any(|&krate| !crate_graph[krate].is_proc_macro)
-            });
         true
     }
 
diff --git a/editors/code/README.md b/editors/code/README.md
index a5593e1110..46c6f6f2aa 100644
--- a/editors/code/README.md
+++ b/editors/code/README.md
@@ -1,31 +1,34 @@
 # rust-analyzer
 
-This extension proves support for the [Rust programming language](https://www.rust-lang.org/).
+Provides support for rust-analyzer: novel LSP server for the Rust programming language.
+
+**Note** the extension may cause conflicts with the official Rust extension. It is recommended to disable the Rust extension when using the rust-analyzer extension.
 
 ## Features
 
-- [code completion] with [imports insertion]
-- go to [definition], [implementation], [type definition]
-- [find all references], [workspace symbol search], [symbol renaming]
+- [code completion], [imports insertion]
+- [go to definition], [implementation], [type definition]
+- [find all references], [workspace symbol search], [rename]
 - [types and documentation on hover]
-- [inlay hints] for types and parameter names
+- [inlay hints]
 - [semantic syntax highlighting]
-- a lot of [assists(code actions)]
+- a lot of [assist(code actions)]
 - apply suggestions from errors
 - ... and many more, checkout the [manual] to see them all
 
 [code completion]: https://rust-analyzer.github.io/manual.html#magic-completions
-[imports insertion]: https://rust-analyzer.github.io/manual.html#completion-with-autoimport
-[definition]: https://rust-analyzer.github.io/manual.html#go-to-definition
+[imports insertion]: https://rust-analyzer.github.io/manual.html#auto-import
+[go to definition]: https://rust-analyzer.github.io/manual.html#go-to-definition
 [implementation]: https://rust-analyzer.github.io/manual.html#go-to-implementation
 [type definition]: https://rust-analyzer.github.io/manual.html#go-to-type-definition
 [find all references]: https://rust-analyzer.github.io/manual.html#find-all-references
 [workspace symbol search]: https://rust-analyzer.github.io/manual.html#workspace-symbol
-[symbol renaming]: https://rust-analyzer.github.io/manual.html#rename
+[rename]: https://rust-analyzer.github.io/manual.html#rename
 [types and documentation on hover]: https://rust-analyzer.github.io/manual.html#hover
 [inlay hints]: https://rust-analyzer.github.io/manual.html#inlay-hints
 [semantic syntax highlighting]: https://rust-analyzer.github.io/manual.html#semantic-syntax-highlighting
-[assists(code actions)]: https://rust-analyzer.github.io/manual.html#assists-code-actions
+[assist(code actions)]: https://rust-analyzer.github.io/manual.html#assists-code-actions
+
 [manual]: https://rust-analyzer.github.io/manual.html
 
 ## Quick start


Test patch:
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 a747b4bc1f..36e9ec6333 100644
--- a/crates/ide/src/syntax_highlighting/test_data/highlight_doctest.html
+++ b/crates/ide/src/syntax_highlighting/test_data/highlight_doctest.html
@@ -144,10 +144,10 @@ pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
 <span class="brace">}</span>
 
 <span class="comment documentation">/// ```</span>
-<span class="comment documentation">///</span><span class="comment documentation"> </span><span class="keyword injected">macro_rules</span><span class="macro_bang injected">!</span><span class="none injected"> </span><span class="macro declaration injected">noop</span><span class="none injected"> </span><span class="brace injected">{</span><span class="none injected"> </span><span class="parenthesis injected">(</span><span class="punctuation injected">$</span><span class="none injected">expr</span><span class="colon injected">:</span><span class="none injected">expr</span><span class="parenthesis injected">)</span><span class="none injected"> </span><span class="operator injected">=</span><span class="angle injected">&gt;</span><span class="none injected"> </span><span class="brace injected">{</span><span class="none injected"> </span><span class="punctuation injected">$</span><span class="none injected">expr </span><span class="brace injected">}</span><span class="brace injected">}</span>
+<span class="comment documentation">///</span><span class="comment documentation"> </span><span class="keyword injected">macro_rules</span><span class="punctuation injected">!</span><span class="none injected"> </span><span class="macro declaration injected">noop</span><span class="none injected"> </span><span class="brace injected">{</span><span class="none injected"> </span><span class="parenthesis injected">(</span><span class="punctuation injected">$</span><span class="none injected">expr</span><span class="colon injected">:</span><span class="none injected">expr</span><span class="parenthesis injected">)</span><span class="none injected"> </span><span class="operator injected">=</span><span class="angle injected">&gt;</span><span class="none injected"> </span><span class="brace injected">{</span><span class="none injected"> </span><span class="punctuation injected">$</span><span class="none injected">expr </span><span class="brace injected">}</span><span class="brace injected">}</span>
 <span class="comment documentation">///</span><span class="comment documentation"> </span><span class="macro injected">noop</span><span class="macro_bang injected">!</span><span class="parenthesis injected">(</span><span class="numeric_literal injected">1</span><span class="parenthesis injected">)</span><span class="semicolon injected">;</span>
 <span class="comment documentation">/// ```</span>
-<span class="keyword">macro_rules</span><span class="macro_bang">!</span> <span class="macro declaration">noop</span> <span class="brace">{</span>
+<span class="keyword">macro_rules</span><span class="punctuation">!</span> <span class="macro declaration">noop</span> <span class="brace">{</span>
     <span class="parenthesis">(</span><span class="punctuation">$</span>expr<span class="colon">:</span>expr<span class="parenthesis">)</span> <span class="operator">=</span><span class="angle">&gt;</span> <span class="brace">{</span>
         <span class="punctuation">$</span>expr
     <span class="brace">}</span>
diff --git a/crates/ide/src/syntax_highlighting/test_data/highlight_keywords.html b/crates/ide/src/syntax_highlighting/test_data/highlight_keywords.html
index ba62b68e9d..7cd6a5a72d 100644
--- a/crates/ide/src/syntax_highlighting/test_data/highlight_keywords.html
+++ b/crates/ide/src/syntax_highlighting/test_data/highlight_keywords.html
@@ -50,7 +50,7 @@ pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
     <span class="keyword">use</span> <span class="keyword crate_root">super</span><span class="operator">::</span><span class="punctuation">*</span><span class="semicolon">;</span>
 <span class="brace">}</span>
 
-<span class="keyword">macro_rules</span><span class="macro_bang">!</span> <span class="macro declaration">void</span> <span class="brace">{</span>
+<span class="keyword">macro_rules</span><span class="punctuation">!</span> <span class="macro declaration">void</span> <span class="brace">{</span>
     <span class="parenthesis">(</span><span class="punctuation">$</span><span class="parenthesis">(</span><span class="punctuation">$</span>tt<span class="colon">:</span>tt<span class="parenthesis">)</span><span class="punctuation">*</span><span class="parenthesis">)</span> <span class="operator">=</span><span class="angle">&gt;</span> <span class="brace">{</span><span class="brace">}</span>
 <span class="brace">}</span>
 <span class="macro">void</span><span class="macro_bang">!</span><span class="parenthesis">(</span><span class="keyword">Self</span><span class="parenthesis">)</span><span class="semicolon">;</span>
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 b725c80565..71add7e495 100644
--- a/crates/ide/src/syntax_highlighting/test_data/highlight_macros.html
+++ b/crates/ide/src/syntax_highlighting/test_data/highlight_macros.html
@@ -48,7 +48,7 @@ pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
         <span class="comma">,</span><span class="builtin_type">i32</span> <span class="colon">:</span><span class="field declaration public">y</span> <span class="keyword">pub</span>
     <span class="brace">}</span> <span class="struct declaration">Foo</span> <span class="keyword">struct</span>
 <span class="brace">}</span>
-<span class="keyword">macro_rules</span><span class="macro_bang">!</span> <span class="macro declaration">def_fn</span> <span class="brace">{</span>
+<span class="keyword">macro_rules</span><span class="punctuation">!</span> <span class="macro declaration">def_fn</span> <span class="brace">{</span>
     <span class="parenthesis">(</span><span class="punctuation">$</span><span class="parenthesis">(</span><span class="punctuation">$</span>tt<span class="colon">:</span>tt<span class="parenthesis">)</span><span class="punctuation">*</span><span class="parenthesis">)</span> <span class="operator">=</span><span class="angle">&gt;</span> <span class="brace">{</span><span class="punctuation">$</span><span class="parenthesis">(</span><span class="punctuation">$</span>tt<span class="parenthesis">)</span><span class="punctuation">*</span><span class="brace">}</span>
 <span class="brace">}</span>
 
@@ -58,17 +58,17 @@ pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
     <span class="brace">}</span>
 <span class="brace">}</span>
 
-<span class="keyword">macro_rules</span><span class="macro_bang">!</span> <span class="macro declaration">dont_color_me_braces</span> <span class="brace">{</span>
+<span class="keyword">macro_rules</span><span class="punctuation">!</span> <span class="macro declaration">dont_color_me_braces</span> <span class="brace">{</span>
     <span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="operator">=</span><span class="angle">&gt;</span> <span class="brace">{</span><span class="numeric_literal">0</span><span class="brace">}</span>
 <span class="brace">}</span>
 
-<span class="keyword">macro_rules</span><span class="macro_bang">!</span> <span class="macro declaration">noop</span> <span class="brace">{</span>
+<span class="keyword">macro_rules</span><span class="punctuation">!</span> <span class="macro declaration">noop</span> <span class="brace">{</span>
     <span class="parenthesis">(</span><span class="punctuation">$</span>expr<span class="colon">:</span>expr<span class="parenthesis">)</span> <span class="operator">=</span><span class="angle">&gt;</span> <span class="brace">{</span>
         <span class="punctuation">$</span>expr
     <span class="brace">}</span>
 <span class="brace">}</span>
 
-<span class="keyword">macro_rules</span><span class="macro_bang">!</span> <span class="macro declaration">keyword_frag</span> <span class="brace">{</span>
+<span class="keyword">macro_rules</span><span class="punctuation">!</span> <span class="macro declaration">keyword_frag</span> <span class="brace">{</span>
     <span class="parenthesis">(</span><span class="punctuation">$</span>type<span class="colon">:</span>ty<span class="parenthesis">)</span> <span class="operator">=</span><span class="angle">&gt;</span> <span class="parenthesis">(</span><span class="punctuation">$</span>type<span class="parenthesis">)</span>
 <span class="brace">}</span>
 
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 60bc290121..29a0a9f066 100644
--- a/crates/ide/src/syntax_highlighting/test_data/highlight_strings.html
+++ b/crates/ide/src/syntax_highlighting/test_data/highlight_strings.html
@@ -42,20 +42,20 @@ pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
 
 .unresolved_reference { color: #FC5555; text-decoration: wavy underline; }
 </style>
-<pre><code><span class="keyword">macro_rules</span><span class="macro_bang">!</span> <span class="macro declaration">println</span> <span class="brace">{</span>
+<pre><code><span class="keyword">macro_rules</span><span class="punctuation">!</span> <span class="macro declaration">println</span> <span class="brace">{</span>
     <span class="parenthesis">(</span><span class="punctuation">$</span><span class="parenthesis">(</span><span class="punctuation">$</span>arg<span class="colon">:</span>tt<span class="parenthesis">)</span><span class="punctuation">*</span><span class="parenthesis">)</span> <span class="operator">=</span><span class="angle">&gt;</span> <span class="parenthesis">(</span><span class="brace">{</span>
         <span class="punctuation">$</span>crate<span class="colon">:</span><span class="colon">:</span>io<span class="colon">:</span><span class="colon">:</span>_print<span class="parenthesis">(</span><span class="punctuation">$</span>crate<span class="colon">:</span><span class="colon">:</span>format_args_nl<span class="punctuation">!</span><span class="parenthesis">(</span><span class="punctuation">$</span><span class="parenthesis">(</span><span class="punctuation">$</span>arg<span class="parenthesis">)</span><span class="punctuation">*</span><span class="parenthesis">)</span><span class="parenthesis">)</span><span class="semicolon">;</span>
     <span class="brace">}</span><span class="parenthesis">)</span>
 <span class="brace">}</span>
 <span class="attribute_bracket attribute">#</span><span class="attribute_bracket attribute">[</span><span class="builtin_attr attribute library">rustc_builtin_macro</span><span class="attribute_bracket attribute">]</span>
 <span class="attribute_bracket attribute">#</span><span class="attribute_bracket attribute">[</span><span class="builtin_attr attribute library">macro_export</span><span class="attribute_bracket attribute">]</span>
-<span class="keyword">macro_rules</span><span class="macro_bang">!</span> <span class="macro declaration">format_args</span> <span class="brace">{</span><span class="brace">}</span>
+<span class="keyword">macro_rules</span><span class="punctuation">!</span> <span class="macro declaration">format_args</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 library">rustc_builtin_macro</span><span class="attribute_bracket attribute">]</span>
 <span class="attribute_bracket attribute">#</span><span class="attribute_bracket attribute">[</span><span class="builtin_attr attribute library">macro_export</span><span class="attribute_bracket attribute">]</span>
-<span class="keyword">macro_rules</span><span class="macro_bang">!</span> <span class="macro declaration">const_format_args</span> <span class="brace">{</span><span class="brace">}</span>
+<span class="keyword">macro_rules</span><span class="punctuation">!</span> <span class="macro declaration">const_format_args</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 library">rustc_builtin_macro</span><span class="attribute_bracket attribute">]</span>
 <span class="attribute_bracket attribute">#</span><span class="attribute_bracket attribute">[</span><span class="builtin_attr attribute library">macro_export</span><span class="attribute_bracket attribute">]</span>
-<span class="keyword">macro_rules</span><span class="macro_bang">!</span> <span class="macro declaration">format_args_nl</span> <span class="brace">{</span><span class="brace">}</span>
+<span class="keyword">macro_rules</span><span class="punctuation">!</span> <span class="macro declaration">format_args_nl</span> <span class="brace">{</span><span class="brace">}</span>
 
 <span class="keyword">mod</span> <span class="module declaration">panic</span> <span class="brace">{</span>
     <span class="keyword">pub</span> <span class="keyword">macro</span> <span class="macro declaration">panic_2015</span> <span class="brace">{</span>
@@ -81,13 +81,13 @@ pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
 
 <span class="attribute_bracket attribute">#</span><span class="attribute_bracket attribute">[</span><span class="builtin_attr attribute library">rustc_builtin_macro</span><span class="parenthesis attribute">(</span><span class="none attribute">std_panic</span><span class="parenthesis attribute">)</span><span class="attribute_bracket attribute">]</span>
 <span class="attribute_bracket attribute">#</span><span class="attribute_bracket attribute">[</span><span class="builtin_attr attribute library">macro_export</span><span class="attribute_bracket attribute">]</span>
-<span class="keyword">macro_rules</span><span class="macro_bang">!</span> <span class="macro declaration">panic</span> <span class="brace">{</span><span class="brace">}</span>
+<span class="keyword">macro_rules</span><span class="punctuation">!</span> <span class="macro declaration">panic</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 library">rustc_builtin_macro</span><span class="attribute_bracket attribute">]</span>
-<span class="keyword">macro_rules</span><span class="macro_bang">!</span> <span class="macro declaration">assert</span> <span class="brace">{</span><span class="brace">}</span>
+<span class="keyword">macro_rules</span><span class="punctuation">!</span> <span class="macro declaration">assert</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 library">rustc_builtin_macro</span><span class="attribute_bracket attribute">]</span>
-<span class="keyword">macro_rules</span><span class="macro_bang">!</span> <span class="macro declaration">asm</span> <span class="brace">{</span><span class="brace">}</span>
+<span class="keyword">macro_rules</span><span class="punctuation">!</span> <span class="macro declaration">asm</span> <span class="brace">{</span><span class="brace">}</span>
 
-<span class="keyword">macro_rules</span><span class="macro_bang">!</span> <span class="macro declaration">toho</span> <span class="brace">{</span>
+<span class="keyword">macro_rules</span><span class="punctuation">!</span> <span class="macro declaration">toho</span> <span class="brace">{</span>
     <span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="operator">=</span><span class="angle">&gt;</span> <span class="parenthesis">(</span><span class="punctuation">$</span>crate<span class="colon">:</span><span class="colon">:</span>panic<span class="punctuation">!</span><span class="parenthesis">(</span><span class="string_literal">"not yet implemented"</span><span class="parenthesis">)</span><span class="parenthesis">)</span><span class="semicolon">;</span>
     <span class="parenthesis">(</span><span class="punctuation">$</span><span class="parenthesis">(</span><span class="punctuation">$</span>arg<span class="colon">:</span>tt<span class="parenthesis">)</span><span class="punctuation">+</span><span class="parenthesis">)</span> <span class="operator">=</span><span class="angle">&gt;</span> <span class="parenthesis">(</span><span class="punctuation">$</span>crate<span class="colon">:</span><span class="colon">:</span>panic<span class="punctuation">!</span><span class="parenthesis">(</span><span class="string_literal">"not yet implemented: {}"</span><span class="comma">,</span> <span class="punctuation">$</span>crate<span class="colon">:</span><span class="colon">:</span>format_args<span class="punctuation">!</span><span class="parenthesis">(</span><span class="punctuation">$</span><span class="parenthesis">(</span><span class="punctuation">$</span>arg<span class="parenthesis">)</span><span class="punctuation">+</span><span class="parenthesis">)</span><span class="parenthesis">)</span><span class="parenthesis">)</span><span class="semicolon">;</span>
 <span class="brace">}</span>
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 0716bae751..113463aa7a 100644
--- a/crates/ide/src/syntax_highlighting/test_data/highlight_unsafe.html
+++ b/crates/ide/src/syntax_highlighting/test_data/highlight_unsafe.html
@@ -42,12 +42,12 @@ pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
 
 .unresolved_reference { color: #FC5555; text-decoration: wavy underline; }
 </style>
-<pre><code><span class="keyword">macro_rules</span><span class="macro_bang">!</span> <span class="macro declaration">id</span> <span class="brace">{</span>
+<pre><code><span class="keyword">macro_rules</span><span class="punctuation">!</span> <span class="macro declaration">id</span> <span class="brace">{</span>
     <span class="parenthesis">(</span><span class="punctuation">$</span><span class="parenthesis">(</span><span class="punctuation">$</span>tt<span class="colon">:</span>tt<span class="parenthesis">)</span><span class="punctuation">*</span><span class="parenthesis">)</span> <span class="operator">=</span><span class="angle">&gt;</span> <span class="brace">{</span>
         <span class="punctuation">$</span><span class="parenthesis">(</span><span class="punctuation">$</span>tt<span class="parenthesis">)</span><span class="punctuation">*</span>
     <span class="brace">}</span><span class="semicolon">;</span>
 <span class="brace">}</span>
-<span class="keyword">macro_rules</span><span class="macro_bang">!</span> <span class="macro declaration">unsafe_deref</span> <span class="brace">{</span>
+<span class="keyword">macro_rules</span><span class="punctuation">!</span> <span class="macro declaration">unsafe_deref</span> <span class="brace">{</span>
     <span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="operator">=</span><span class="angle">&gt;</span> <span class="brace">{</span>
         <span class="punctuation">*</span><span class="parenthesis">(</span><span class="operator">&</span><span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="keyword">as</span> <span class="punctuation">*</span><span class="keyword">const</span> <span class="parenthesis">(</span><span class="parenthesis">)</span><span class="parenthesis">)</span>
     <span class="brace">}</span><span class="semicolon">;</span>