about summary refs log tree commit diff
diff options
context:
space:
mode:
authorLukas Wirth <lukastw97@gmail.com>2024-01-26 10:43:25 +0100
committerLukas Wirth <lukastw97@gmail.com>2024-01-26 19:28:39 +0100
commit5a343415e83b9cf88a2cce9ce945746c4601f765 (patch)
tree3a8779613b45027bfce2c487ad845c8362ce46c9
parentd8ef6c24cc4e2aa594dcbd561f33fb995278cf17 (diff)
downloadrust-5a343415e83b9cf88a2cce9ce945746c4601f765.tar.gz
rust-5a343415e83b9cf88a2cce9ce945746c4601f765.zip
Add some size assertions
-rw-r--r--crates/hir-def/src/lib.rs71
-rw-r--r--crates/hir-def/src/nameres/attr_resolution.rs67
-rw-r--r--crates/hir-def/src/nameres/collector.rs10
-rw-r--r--crates/hir-def/src/visibility.rs2
-rw-r--r--crates/hir-expand/src/builtin_attr_macro.rs8
-rw-r--r--crates/hir-expand/src/lib.rs3
-rw-r--r--crates/hir-expand/src/mod_path.rs2
-rw-r--r--crates/hir-expand/src/name.rs2
-rw-r--r--crates/hir/src/lib.rs197
-rw-r--r--crates/mbe/src/syntax_bridge.rs10
-rw-r--r--crates/span/src/lib.rs5
-rw-r--r--crates/stdx/src/macros.rs9
-rw-r--r--editors/code/language-configuration.json6
13 files changed, 194 insertions, 198 deletions
diff --git a/crates/hir-def/src/lib.rs b/crates/hir-def/src/lib.rs
index 790e3b414b6..243de663977 100644
--- a/crates/hir-def/src/lib.rs
+++ b/crates/hir-def/src/lib.rs
@@ -25,13 +25,13 @@ extern crate ra_ap_rustc_abi as rustc_abi;
 pub mod db;
 
 pub mod attr;
-pub mod path;
 pub mod builtin_type;
-pub mod per_ns;
 pub mod item_scope;
+pub mod path;
+pub mod per_ns;
 
-pub mod lower;
 pub mod expander;
+pub mod lower;
 
 pub mod dyn_map;
 
@@ -46,24 +46,24 @@ pub use self::hir::type_ref;
 pub mod body;
 pub mod resolver;
 
-mod trace;
 pub mod nameres;
+mod trace;
 
-pub mod src;
 pub mod child_by_source;
+pub mod src;
 
-pub mod visibility;
 pub mod find_path;
 pub mod import_map;
+pub mod visibility;
 
 pub use rustc_abi as layout;
 use triomphe::Arc;
 
 #[cfg(test)]
-mod test_db;
-#[cfg(test)]
 mod macro_expansion_tests;
 mod pretty;
+#[cfg(test)]
+mod test_db;
 
 use std::{
     hash::{Hash, Hasher},
@@ -73,7 +73,6 @@ use std::{
 use base_db::{impl_intern_key, salsa, CrateId, Edition};
 use hir_expand::{
     ast_id_map::{AstIdNode, FileAstId},
-    attrs::{Attr, AttrId, AttrInput},
     builtin_attr_macro::BuiltinAttrExpander,
     builtin_derive_macro::BuiltinDeriveExpander,
     builtin_fn_macro::{BuiltinFnLikeExpander, EagerExpander},
@@ -1274,60 +1273,6 @@ fn macro_call_as_call_id_with_eager(
     Ok(res)
 }
 
-fn derive_macro_as_call_id(
-    db: &dyn DefDatabase,
-    item_attr: &AstIdWithPath<ast::Adt>,
-    derive_attr_index: AttrId,
-    derive_pos: u32,
-    call_site: Span,
-    krate: CrateId,
-    resolver: impl Fn(path::ModPath) -> Option<(MacroId, MacroDefId)>,
-) -> Result<(MacroId, MacroDefId, MacroCallId), UnresolvedMacro> {
-    let (macro_id, def_id) = resolver(item_attr.path.clone())
-        .filter(|(_, def_id)| def_id.is_derive())
-        .ok_or_else(|| UnresolvedMacro { path: item_attr.path.clone() })?;
-    let call_id = def_id.as_lazy_macro(
-        db.upcast(),
-        krate,
-        MacroCallKind::Derive {
-            ast_id: item_attr.ast_id,
-            derive_index: derive_pos,
-            derive_attr_index,
-        },
-        call_site,
-    );
-    Ok((macro_id, def_id, call_id))
-}
-
-fn attr_macro_as_call_id(
-    db: &dyn DefDatabase,
-    item_attr: &AstIdWithPath<ast::Item>,
-    macro_attr: &Attr,
-    krate: CrateId,
-    def: MacroDefId,
-) -> MacroCallId {
-    let arg = match macro_attr.input.as_deref() {
-        Some(AttrInput::TokenTree(tt)) => {
-            let mut tt = tt.as_ref().clone();
-            tt.delimiter = tt::Delimiter::invisible_spanned(macro_attr.span);
-            Some(tt)
-        }
-
-        _ => None,
-    };
-
-    def.as_lazy_macro(
-        db.upcast(),
-        krate,
-        MacroCallKind::Attr {
-            ast_id: item_attr.ast_id,
-            attr_args: arg.map(Arc::new),
-            invoc_attr_index: macro_attr.id,
-        },
-        macro_attr.span,
-    )
-}
-
 #[derive(Debug)]
 pub struct UnresolvedMacro {
     pub path: hir_expand::mod_path::ModPath,
diff --git a/crates/hir-def/src/nameres/attr_resolution.rs b/crates/hir-def/src/nameres/attr_resolution.rs
index 6288b8366bf..1cadae8c87c 100644
--- a/crates/hir-def/src/nameres/attr_resolution.rs
+++ b/crates/hir-def/src/nameres/attr_resolution.rs
@@ -1,16 +1,21 @@
 //! Post-nameres attribute resolution.
 
-use hir_expand::{attrs::Attr, MacroCallId};
+use base_db::CrateId;
+use hir_expand::{
+    attrs::{Attr, AttrId, AttrInput},
+    MacroCallId, MacroCallKind, MacroDefId,
+};
+use span::Span;
 use syntax::{ast, SmolStr};
+use triomphe::Arc;
 
 use crate::{
     attr::builtin::{find_builtin_attr_idx, TOOL_MODULES},
-    attr_macro_as_call_id,
     db::DefDatabase,
     item_scope::BuiltinShadowMode,
     nameres::path_resolution::ResolveMode,
-    path::{ModPath, PathKind},
-    AstIdWithPath, LocalModuleId, UnresolvedMacro,
+    path::{self, ModPath, PathKind},
+    AstIdWithPath, LocalModuleId, MacroId, UnresolvedMacro,
 };
 
 use super::{DefMap, MacroSubNs};
@@ -93,3 +98,57 @@ impl DefMap {
         false
     }
 }
+
+pub(super) fn attr_macro_as_call_id(
+    db: &dyn DefDatabase,
+    item_attr: &AstIdWithPath<ast::Item>,
+    macro_attr: &Attr,
+    krate: CrateId,
+    def: MacroDefId,
+) -> MacroCallId {
+    let arg = match macro_attr.input.as_deref() {
+        Some(AttrInput::TokenTree(tt)) => {
+            let mut tt = tt.as_ref().clone();
+            tt.delimiter = tt::Delimiter::invisible_spanned(macro_attr.span);
+            Some(tt)
+        }
+
+        _ => None,
+    };
+
+    def.as_lazy_macro(
+        db.upcast(),
+        krate,
+        MacroCallKind::Attr {
+            ast_id: item_attr.ast_id,
+            attr_args: arg.map(Arc::new),
+            invoc_attr_index: macro_attr.id,
+        },
+        macro_attr.span,
+    )
+}
+
+pub(super) fn derive_macro_as_call_id(
+    db: &dyn DefDatabase,
+    item_attr: &AstIdWithPath<ast::Adt>,
+    derive_attr_index: AttrId,
+    derive_pos: u32,
+    call_site: Span,
+    krate: CrateId,
+    resolver: impl Fn(path::ModPath) -> Option<(MacroId, MacroDefId)>,
+) -> Result<(MacroId, MacroDefId, MacroCallId), UnresolvedMacro> {
+    let (macro_id, def_id) = resolver(item_attr.path.clone())
+        .filter(|(_, def_id)| def_id.is_derive())
+        .ok_or_else(|| UnresolvedMacro { path: item_attr.path.clone() })?;
+    let call_id = def_id.as_lazy_macro(
+        db.upcast(),
+        krate,
+        MacroCallKind::Derive {
+            ast_id: item_attr.ast_id,
+            derive_index: derive_pos,
+            derive_attr_index,
+        },
+        call_site,
+    );
+    Ok((macro_id, def_id, call_id))
+}
diff --git a/crates/hir-def/src/nameres/collector.rs b/crates/hir-def/src/nameres/collector.rs
index 1c0f4d4d35f..248d3213d5d 100644
--- a/crates/hir-def/src/nameres/collector.rs
+++ b/crates/hir-def/src/nameres/collector.rs
@@ -30,9 +30,7 @@ use triomphe::Arc;
 
 use crate::{
     attr::Attrs,
-    attr_macro_as_call_id,
     db::DefDatabase,
-    derive_macro_as_call_id,
     item_scope::{ImportId, ImportOrExternCrate, ImportType, PerNsGlobImports},
     item_tree::{
         self, ExternCrate, Fields, FileItemTreeId, ImportKind, ItemTree, ItemTreeId,
@@ -40,6 +38,7 @@ use crate::{
     },
     macro_call_as_call_id, macro_call_as_call_id_with_eager,
     nameres::{
+        attr_resolution::{attr_macro_as_call_id, derive_macro_as_call_id},
         diagnostics::DefDiagnostic,
         mod_resolution::ModDir,
         path_resolution::ReachedFixedPoint,
@@ -1245,7 +1244,9 @@ impl DefCollector<'_> {
                         MacroDefId { kind: MacroDefKind::BuiltInAttr(expander, _),.. }
                         if expander.is_derive()
                     ) {
-                        // Resolved to `#[derive]`
+                        // Resolved to `#[derive]`, we don't actually expand this attribute like
+                        // normal (as that would just be an identity expansion with extra output)
+                        // Instead we treat derive attributes special and apply them separately.
 
                         let item_tree = tree.item_tree(self.db);
                         let ast_adt_id: FileAstId<ast::Adt> = match *mod_item {
@@ -1284,7 +1285,8 @@ impl DefCollector<'_> {
                                 }
 
                                 // We treat the #[derive] macro as an attribute call, but we do not resolve it for nameres collection.
-                                // This is just a trick to be able to resolve the input to derives as proper paths.
+                                // This is just a trick to be able to resolve the input to derives
+                                // as proper paths in `Semantics`.
                                 // Check the comment in [`builtin_attr_macro`].
                                 let call_id = attr_macro_as_call_id(
                                     self.db,
diff --git a/crates/hir-def/src/visibility.rs b/crates/hir-def/src/visibility.rs
index 3294ce29a4a..8d27884c269 100644
--- a/crates/hir-def/src/visibility.rs
+++ b/crates/hir-def/src/visibility.rs
@@ -4,6 +4,7 @@ use std::iter;
 
 use hir_expand::{span_map::SpanMapRef, InFile};
 use la_arena::ArenaMap;
+use stdx::assert_eq_size;
 use syntax::ast;
 use triomphe::Arc;
 
@@ -24,6 +25,7 @@ pub enum RawVisibility {
     /// `pub`.
     Public,
 }
+assert_eq_size!(RawVisibility, 48);
 
 impl RawVisibility {
     pub(crate) const fn private() -> RawVisibility {
diff --git a/crates/hir-expand/src/builtin_attr_macro.rs b/crates/hir-expand/src/builtin_attr_macro.rs
index 55157abe671..dd2aa94ad01 100644
--- a/crates/hir-expand/src/builtin_attr_macro.rs
+++ b/crates/hir-expand/src/builtin_attr_macro.rs
@@ -48,11 +48,13 @@ impl BuiltinAttrExpander {
 
 register_builtin! { expand:
     (bench, Bench) => dummy_attr_expand,
+    (cfg, Cfg) => dummy_attr_expand,
+    (cfg_attr, CfgAttr) => dummy_attr_expand,
     (cfg_accessible, CfgAccessible) => dummy_attr_expand,
     (cfg_eval, CfgEval) => dummy_attr_expand,
-    (derive, Derive) => derive_attr_expand,
+    (derive, Derive) => derive_expand,
     // derive const is equivalent to derive for our proposes.
-    (derive_const, DeriveConst) => derive_attr_expand,
+    (derive_const, DeriveConst) => derive_expand,
     (global_allocator, GlobalAllocator) => dummy_attr_expand,
     (test, Test) => dummy_attr_expand,
     (test_case, TestCase) => dummy_attr_expand
@@ -91,7 +93,7 @@ fn dummy_attr_expand(
 /// always resolve as a derive without nameres recollecting them.
 /// So this hacky approach is a lot more friendly for us, though it does require a bit of support in
 /// [`hir::Semantics`] to make this work.
-fn derive_attr_expand(
+fn derive_expand(
     db: &dyn ExpandDatabase,
     id: MacroCallId,
     tt: &tt::Subtree,
diff --git a/crates/hir-expand/src/lib.rs b/crates/hir-expand/src/lib.rs
index 05f12527a44..37b41c09c5f 100644
--- a/crates/hir-expand/src/lib.rs
+++ b/crates/hir-expand/src/lib.rs
@@ -26,6 +26,7 @@ pub mod span_map;
 mod fixup;
 
 use attrs::collect_attrs;
+use stdx::assert_eq_size;
 use triomphe::Arc;
 
 use std::{fmt, hash::Hash};
@@ -175,6 +176,7 @@ pub struct MacroCallLoc {
     pub kind: MacroCallKind,
     pub call_site: Span,
 }
+assert_eq_size!(MacroCallLoc, 104);
 
 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
 pub struct MacroDefId {
@@ -185,6 +187,7 @@ pub struct MacroDefId {
     pub allow_internal_unsafe: bool,
     pub span: Span,
 }
+assert_eq_size!(MacroDefId, 44);
 
 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
 pub enum MacroDefKind {
diff --git a/crates/hir-expand/src/mod_path.rs b/crates/hir-expand/src/mod_path.rs
index 0eb1fc1eb50..6dc01fba91b 100644
--- a/crates/hir-expand/src/mod_path.rs
+++ b/crates/hir-expand/src/mod_path.rs
@@ -15,6 +15,7 @@ use crate::{
 use base_db::CrateId;
 use smallvec::SmallVec;
 use span::SyntaxContextId;
+use stdx::assert_eq_size;
 use syntax::{ast, AstNode};
 
 #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
@@ -22,6 +23,7 @@ pub struct ModPath {
     pub kind: PathKind,
     segments: SmallVec<[Name; 1]>,
 }
+assert_eq_size!(ModPath, 40);
 
 #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
 pub struct UnescapedModPath<'a>(&'a ModPath);
diff --git a/crates/hir-expand/src/name.rs b/crates/hir-expand/src/name.rs
index 91c362399e7..6ebefde32c4 100644
--- a/crates/hir-expand/src/name.rs
+++ b/crates/hir-expand/src/name.rs
@@ -2,6 +2,7 @@
 
 use std::fmt;
 
+use stdx::assert_eq_size;
 use syntax::{ast, format_smolstr, utils::is_raw_identifier, SmolStr};
 
 /// `Name` is a wrapper around string, which is used in hir for both references
@@ -13,6 +14,7 @@ use syntax::{ast, format_smolstr, utils::is_raw_identifier, SmolStr};
 /// name without "r#".
 #[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
 pub struct Name(Repr);
+assert_eq_size!(Name, 24);
 
 /// Wrapper of `Name` to print the name without "r#" even when it is a raw identifier.
 #[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs
index c50be5f1141..c332ab0050c 100644
--- a/crates/hir/src/lib.rs
+++ b/crates/hir/src/lib.rs
@@ -24,12 +24,12 @@
 mod semantics;
 mod source_analyzer;
 
-mod from_id;
 mod attrs;
+mod from_id;
 mod has_source;
 
-pub mod diagnostics;
 pub mod db;
+pub mod diagnostics;
 pub mod symbols;
 
 mod display;
@@ -70,13 +70,12 @@ use hir_ty::{
     primitive::UintTy,
     traits::FnTrait,
     AliasTy, CallableDefId, CallableSig, Canonical, CanonicalVarKinds, Cast, ClosureId, GenericArg,
-    GenericArgData, Interner, ParamKind, QuantifiedWhereClause, Scalar, Substitution,
-    TraitEnvironment, TraitRefExt, Ty, TyBuilder, TyDefId, TyExt, TyKind, ValueTyDefId,
-    WhereClause,
+    GenericArgData, InferenceDiagnostic, Interner, ParamKind, QuantifiedWhereClause, Scalar,
+    Substitution, TraitEnvironment, TraitRefExt, Ty, TyBuilder, TyDefId, TyExt, TyKind,
+    ValueTyDefId, WhereClause,
 };
 use itertools::Itertools;
 use nameres::diagnostics::DefDiagnosticKind;
-use once_cell::unsync::Lazy;
 use rustc_hash::FxHashSet;
 use stdx::{impl_from, never};
 use syntax::{
@@ -1592,53 +1591,46 @@ impl DefWithBody {
         }
 
         for diag in source_map.diagnostics() {
-            match diag {
-                BodyDiagnostic::InactiveCode { node, cfg, opts } => acc.push(
-                    InactiveCode { node: *node, cfg: cfg.clone(), opts: opts.clone() }.into(),
-                ),
-                BodyDiagnostic::MacroError { node, message } => acc.push(
-                    MacroError {
-                        node: (*node).map(|it| it.into()),
-                        precise_location: None,
-                        message: message.to_string(),
-                    }
-                    .into(),
-                ),
-                BodyDiagnostic::UnresolvedProcMacro { node, krate } => acc.push(
-                    UnresolvedProcMacro {
-                        node: (*node).map(|it| it.into()),
-                        precise_location: None,
-                        macro_name: None,
-                        kind: MacroKind::ProcMacro,
-                        krate: *krate,
-                    }
-                    .into(),
-                ),
-                BodyDiagnostic::UnresolvedMacroCall { node, path } => acc.push(
-                    UnresolvedMacroCall {
-                        macro_call: (*node).map(|ast_ptr| ast_ptr.into()),
-                        precise_location: None,
-                        path: path.clone(),
-                        is_bang: true,
-                    }
-                    .into(),
-                ),
+            acc.push(match diag {
+                BodyDiagnostic::InactiveCode { node, cfg, opts } => {
+                    InactiveCode { node: *node, cfg: cfg.clone(), opts: opts.clone() }.into()
+                }
+                BodyDiagnostic::MacroError { node, message } => MacroError {
+                    node: (*node).map(|it| it.into()),
+                    precise_location: None,
+                    message: message.to_string(),
+                }
+                .into(),
+                BodyDiagnostic::UnresolvedProcMacro { node, krate } => UnresolvedProcMacro {
+                    node: (*node).map(|it| it.into()),
+                    precise_location: None,
+                    macro_name: None,
+                    kind: MacroKind::ProcMacro,
+                    krate: *krate,
+                }
+                .into(),
+                BodyDiagnostic::UnresolvedMacroCall { node, path } => UnresolvedMacroCall {
+                    macro_call: (*node).map(|ast_ptr| ast_ptr.into()),
+                    precise_location: None,
+                    path: path.clone(),
+                    is_bang: true,
+                }
+                .into(),
                 BodyDiagnostic::UnreachableLabel { node, name } => {
-                    acc.push(UnreachableLabel { node: *node, name: name.clone() }.into())
+                    UnreachableLabel { node: *node, name: name.clone() }.into()
                 }
                 BodyDiagnostic::UndeclaredLabel { node, name } => {
-                    acc.push(UndeclaredLabel { node: *node, name: name.clone() }.into())
+                    UndeclaredLabel { node: *node, name: name.clone() }.into()
                 }
-            }
+            });
         }
 
         let infer = db.infer(self.into());
-        let source_map = Lazy::new(|| db.body_with_source_map(self.into()).1);
         let expr_syntax = |expr| source_map.expr_syntax(expr).expect("unexpected synthetic");
         let pat_syntax = |pat| source_map.pat_syntax(pat).expect("unexpected synthetic");
         for d in &infer.diagnostics {
-            match d {
-                &hir_ty::InferenceDiagnostic::NoSuchField { field: expr, private } => {
+            acc.push(match d {
+                &InferenceDiagnostic::NoSuchField { field: expr, private } => {
                     let expr_or_pat = match expr {
                         ExprOrPatId::ExprId(expr) => {
                             source_map.field_syntax(expr).map(AstPtr::wrap_left)
@@ -1647,57 +1639,48 @@ impl DefWithBody {
                             source_map.pat_field_syntax(pat).map(AstPtr::wrap_right)
                         }
                     };
-                    acc.push(NoSuchField { field: expr_or_pat, private }.into())
+                    NoSuchField { field: expr_or_pat, private }.into()
                 }
-                &hir_ty::InferenceDiagnostic::MismatchedArgCount { call_expr, expected, found } => {
-                    acc.push(
-                        MismatchedArgCount { call_expr: expr_syntax(call_expr), expected, found }
-                            .into(),
-                    )
+                &InferenceDiagnostic::MismatchedArgCount { call_expr, expected, found } => {
+                    MismatchedArgCount { call_expr: expr_syntax(call_expr), expected, found }.into()
                 }
-                &hir_ty::InferenceDiagnostic::PrivateField { expr, field } => {
+                &InferenceDiagnostic::PrivateField { expr, field } => {
                     let expr = expr_syntax(expr);
                     let field = field.into();
-                    acc.push(PrivateField { expr, field }.into())
+                    PrivateField { expr, field }.into()
                 }
-                &hir_ty::InferenceDiagnostic::PrivateAssocItem { id, item } => {
+                &InferenceDiagnostic::PrivateAssocItem { id, item } => {
                     let expr_or_pat = match id {
                         ExprOrPatId::ExprId(expr) => expr_syntax(expr).map(AstPtr::wrap_left),
                         ExprOrPatId::PatId(pat) => pat_syntax(pat).map(AstPtr::wrap_right),
                     };
                     let item = item.into();
-                    acc.push(PrivateAssocItem { expr_or_pat, item }.into())
+                    PrivateAssocItem { expr_or_pat, item }.into()
                 }
-                hir_ty::InferenceDiagnostic::ExpectedFunction { call_expr, found } => {
+                InferenceDiagnostic::ExpectedFunction { call_expr, found } => {
                     let call_expr = expr_syntax(*call_expr);
-
-                    acc.push(
-                        ExpectedFunction {
-                            call: call_expr,
-                            found: Type::new(db, DefWithBodyId::from(self), found.clone()),
-                        }
-                        .into(),
-                    )
+                    ExpectedFunction {
+                        call: call_expr,
+                        found: Type::new(db, DefWithBodyId::from(self), found.clone()),
+                    }
+                    .into()
                 }
-                hir_ty::InferenceDiagnostic::UnresolvedField {
+                InferenceDiagnostic::UnresolvedField {
                     expr,
                     receiver,
                     name,
                     method_with_same_name_exists,
                 } => {
                     let expr = expr_syntax(*expr);
-
-                    acc.push(
-                        UnresolvedField {
-                            expr,
-                            name: name.clone(),
-                            receiver: Type::new(db, DefWithBodyId::from(self), receiver.clone()),
-                            method_with_same_name_exists: *method_with_same_name_exists,
-                        }
-                        .into(),
-                    )
+                    UnresolvedField {
+                        expr,
+                        name: name.clone(),
+                        receiver: Type::new(db, DefWithBodyId::from(self), receiver.clone()),
+                        method_with_same_name_exists: *method_with_same_name_exists,
+                    }
+                    .into()
                 }
-                hir_ty::InferenceDiagnostic::UnresolvedMethodCall {
+                InferenceDiagnostic::UnresolvedMethodCall {
                     expr,
                     receiver,
                     name,
@@ -1705,50 +1688,38 @@ impl DefWithBody {
                     assoc_func_with_same_name,
                 } => {
                     let expr = expr_syntax(*expr);
-
-                    acc.push(
-                        UnresolvedMethodCall {
-                            expr,
-                            name: name.clone(),
-                            receiver: Type::new(db, DefWithBodyId::from(self), receiver.clone()),
-                            field_with_same_name: field_with_same_name
-                                .clone()
-                                .map(|ty| Type::new(db, DefWithBodyId::from(self), ty)),
-                            assoc_func_with_same_name: *assoc_func_with_same_name,
-                        }
-                        .into(),
-                    )
+                    UnresolvedMethodCall {
+                        expr,
+                        name: name.clone(),
+                        receiver: Type::new(db, DefWithBodyId::from(self), receiver.clone()),
+                        field_with_same_name: field_with_same_name
+                            .clone()
+                            .map(|ty| Type::new(db, DefWithBodyId::from(self), ty)),
+                        assoc_func_with_same_name: *assoc_func_with_same_name,
+                    }
+                    .into()
                 }
-                &hir_ty::InferenceDiagnostic::UnresolvedAssocItem { id } => {
+                &InferenceDiagnostic::UnresolvedAssocItem { id } => {
                     let expr_or_pat = match id {
                         ExprOrPatId::ExprId(expr) => expr_syntax(expr).map(AstPtr::wrap_left),
                         ExprOrPatId::PatId(pat) => pat_syntax(pat).map(AstPtr::wrap_right),
                     };
-                    acc.push(UnresolvedAssocItem { expr_or_pat }.into())
+                    UnresolvedAssocItem { expr_or_pat }.into()
                 }
-                &hir_ty::InferenceDiagnostic::BreakOutsideOfLoop {
-                    expr,
-                    is_break,
-                    bad_value_break,
-                } => {
+                &InferenceDiagnostic::BreakOutsideOfLoop { expr, is_break, bad_value_break } => {
                     let expr = expr_syntax(expr);
-                    acc.push(BreakOutsideOfLoop { expr, is_break, bad_value_break }.into())
+                    BreakOutsideOfLoop { expr, is_break, bad_value_break }.into()
                 }
-                hir_ty::InferenceDiagnostic::TypedHole { expr, expected } => {
+                InferenceDiagnostic::TypedHole { expr, expected } => {
                     let expr = expr_syntax(*expr);
-                    acc.push(
-                        TypedHole {
-                            expr,
-                            expected: Type::new(db, DefWithBodyId::from(self), expected.clone()),
-                        }
-                        .into(),
-                    )
+
+                    TypedHole {
+                        expr,
+                        expected: Type::new(db, DefWithBodyId::from(self), expected.clone()),
+                    }
+                    .into()
                 }
-                &hir_ty::InferenceDiagnostic::MismatchedTupleStructPatArgCount {
-                    pat,
-                    expected,
-                    found,
-                } => {
+                &InferenceDiagnostic::MismatchedTupleStructPatArgCount { pat, expected, found } => {
                     let expr_or_pat = match pat {
                         ExprOrPatId::ExprId(expr) => expr_syntax(expr).map(AstPtr::wrap_left),
                         ExprOrPatId::PatId(pat) => {
@@ -1762,11 +1733,9 @@ impl DefWithBody {
                             InFile { file_id, value: ptr }
                         }
                     };
-                    acc.push(
-                        MismatchedTupleStructPatArgCount { expr_or_pat, expected, found }.into(),
-                    )
+                    MismatchedTupleStructPatArgCount { expr_or_pat, expected, found }.into()
                 }
-            }
+            });
         }
         for (pat_or_expr, mismatch) in infer.type_mismatches() {
             let expr_or_pat = match pat_or_expr {
@@ -1805,8 +1774,6 @@ impl DefWithBody {
             }
         }
 
-        let hir_body = db.body(self.into());
-
         if let Ok(borrowck_results) = db.borrowck(self.into()) {
             for borrowck_result in borrowck_results.iter() {
                 let mir_body = &borrowck_result.mir_body;
@@ -1828,7 +1795,7 @@ impl DefWithBody {
                     )
                 }
                 let mol = &borrowck_result.mutability_of_locals;
-                for (binding_id, binding_data) in hir_body.bindings.iter() {
+                for (binding_id, binding_data) in body.bindings.iter() {
                     if binding_data.problems.is_some() {
                         // We should report specific diagnostics for these problems, not `need-mut` and `unused-mut`.
                         continue;
diff --git a/crates/mbe/src/syntax_bridge.rs b/crates/mbe/src/syntax_bridge.rs
index 8b57d7eeaf5..4513732902d 100644
--- a/crates/mbe/src/syntax_bridge.rs
+++ b/crates/mbe/src/syntax_bridge.rs
@@ -234,7 +234,7 @@ where
     let mut stack = NonEmptyVec::new(entry);
 
     while let Some((token, abs_range)) = conv.bump() {
-        let tt::Subtree { delimiter, token_trees: result } = stack.last_mut();
+        let tt::Subtree { delimiter, token_trees } = stack.last_mut();
 
         let tt = match token.as_leaf() {
             Some(leaf) => tt::TokenTree::Leaf(leaf.clone()),
@@ -243,7 +243,7 @@ where
                 COMMENT => {
                     let span = conv.span_for(abs_range);
                     if let Some(tokens) = conv.convert_doc_comment(&token, span) {
-                        result.extend(tokens);
+                        token_trees.extend(tokens);
                     }
                     continue;
                 }
@@ -317,7 +317,7 @@ where
                                 span: conv
                                     .span_for(TextRange::at(abs_range.start(), TextSize::of('\''))),
                             });
-                            result.push(apostrophe.into());
+                            token_trees.push(apostrophe.into());
 
                             let ident = tt::Leaf::from(tt::Ident {
                                 text: SmolStr::new(&token.to_text(conv)[1..]),
@@ -326,7 +326,7 @@ where
                                     abs_range.end(),
                                 )),
                             });
-                            result.push(ident.into());
+                            token_trees.push(ident.into());
                             continue;
                         }
                         _ => continue,
@@ -337,7 +337,7 @@ where
             },
         };
 
-        result.push(tt);
+        token_trees.push(tt);
     }
 
     // If we get here, we've consumed all input tokens.
diff --git a/crates/span/src/lib.rs b/crates/span/src/lib.rs
index f6569050b4a..426e4cb55a4 100644
--- a/crates/span/src/lib.rs
+++ b/crates/span/src/lib.rs
@@ -1,10 +1,8 @@
 //! File and span related types.
-// FIXME: This should be moved into its own crate to get rid of the dependency inversion, base-db
-// has business depending on tt, tt should depend on a span crate only (which unforunately will have
-// to depend on salsa)
 use std::fmt::{self, Write};
 
 use salsa::InternId;
+use stdx::assert_eq_size;
 
 mod map;
 
@@ -38,6 +36,7 @@ pub const FIXUP_ERASED_FILE_AST_ID_MARKER: ErasedFileAstId =
     la_arena::Idx::from_raw(la_arena::RawIdx::from_u32(!0 - 1));
 
 pub type Span = SpanData<SyntaxContextId>;
+assert_eq_size!(Span, 20);
 
 #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)]
 pub struct SpanData<Ctx> {
diff --git a/crates/stdx/src/macros.rs b/crates/stdx/src/macros.rs
index d71e418c89b..9f7b7dbc1af 100644
--- a/crates/stdx/src/macros.rs
+++ b/crates/stdx/src/macros.rs
@@ -59,3 +59,12 @@ macro_rules! impl_from {
         )*
     }
 }
+
+#[macro_export]
+macro_rules! assert_eq_size {
+    ($($ty:ty,)+ $val:expr $(,)?) => {
+        const _: () = {
+            $(core::mem::transmute::<[u8; $val], $ty>;)+
+        };
+    };
+}
diff --git a/editors/code/language-configuration.json b/editors/code/language-configuration.json
index 1c348b63f1a..a2af8b51a90 100644
--- a/editors/code/language-configuration.json
+++ b/editors/code/language-configuration.json
@@ -6,7 +6,9 @@
     "brackets": [
         ["{", "}"],
         ["[", "]"],
-        ["(", ")"]
+        ["(", ")"],
+        ["#[", "]"],
+        ["#![", "]"]
     ],
     "colorizedBracketPairs": [
         ["{", "}"],
@@ -17,6 +19,8 @@
         { "open": "{", "close": "}" },
         { "open": "[", "close": "]" },
         { "open": "(", "close": ")" },
+        { "open": "#[", "close": "]" },
+        { "open": "#![", "close": "]" },
         { "open": "\"", "close": "\"", "notIn": ["string"] },
         { "open": "/*", "close": " */" },
         { "open": "`", "close": "`", "notIn": ["string"] }