Repository: rust-lang/rust-analyzer
Pull request #13320 (2022-09-30 22:21:39)

Fix type alias hovers not rendering generic parameters


Patch:
diff --git a/Cargo.lock b/Cargo.lock
index 93b7f746e0..216cf51447 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -863,7 +863,7 @@ dependencies = [
 
 [[package]]
 name = "lsp-server"
-version = "0.7.0"
+version = "0.6.0"
 dependencies = [
  "crossbeam-channel",
  "log",
@@ -1502,18 +1502,18 @@ dependencies = [
 
 [[package]]
 name = "serde"
-version = "1.0.144"
+version = "1.0.143"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0f747710de3dcd43b88c9168773254e809d8ddbdf9653b84e2554ab219f17860"
+checksum = "53e8e5d5b70924f74ff5c6d64d9a5acd91422117c60f48c4e07855238a254553"
 dependencies = [
  "serde_derive",
 ]
 
 [[package]]
 name = "serde_derive"
-version = "1.0.144"
+version = "1.0.143"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "94ed3a816fb1d101812f83e789f888322c34e291f894f19590dc310963e87a00"
+checksum = "d3d8e8de557aee63c26b85b947f5e59b690d0454c753f3adeb5cd7835ab88391"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -1522,9 +1522,9 @@ dependencies = [
 
 [[package]]
 name = "serde_json"
-version = "1.0.85"
+version = "1.0.83"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e55a28e3aaef9d5ce0506d0a14dbba8054ddc7e499ef522dd8b26859ec9d4a44"
+checksum = "38dd04e3c8279e75b31ef29dbdceebfe5ad89f4d0937213c53f7d49d01b3d5a7"
 dependencies = [
  "indexmap",
  "itoa",
diff --git a/crates/base-db/src/fixture.rs b/crates/base-db/src/fixture.rs
index 5b7828a269..8e6e6a11ab 100644
--- a/crates/base-db/src/fixture.rs
+++ b/crates/base-db/src/fixture.rs
@@ -196,7 +196,7 @@ impl ChangeFixture {
                 Env::default(),
                 Ok(Vec::new()),
                 false,
-                CrateOrigin::CratesIo { repo: None, name: None },
+                CrateOrigin::CratesIo { repo: None },
             );
         } else {
             for (from, to, prelude) in crate_deps {
@@ -270,7 +270,7 @@ impl ChangeFixture {
                 Env::default(),
                 Ok(proc_macro),
                 true,
-                CrateOrigin::CratesIo { repo: None, name: None },
+                CrateOrigin::CratesIo { repo: None },
             );
 
             for krate in all_crates {
@@ -398,7 +398,7 @@ fn parse_crate(crate_str: String) -> (String, CrateOrigin, Option<String>) {
         let (version, origin) = match b.split_once(':') {
             Some(("CratesIo", data)) => match data.split_once(',') {
                 Some((version, url)) => {
-                    (version, CrateOrigin::CratesIo { repo: Some(url.to_owned()), name: None })
+                    (version, CrateOrigin::CratesIo { repo: Some(url.to_owned()) })
                 }
                 _ => panic!("Bad crates.io parameter: {}", data),
             },
@@ -409,7 +409,7 @@ fn parse_crate(crate_str: String) -> (String, CrateOrigin, Option<String>) {
         let crate_origin = match &*crate_str {
             "std" => CrateOrigin::Lang(LangCrateOrigin::Std),
             "core" => CrateOrigin::Lang(LangCrateOrigin::Core),
-            _ => CrateOrigin::CratesIo { repo: None, name: None },
+            _ => CrateOrigin::CratesIo { repo: None },
         };
         (crate_str, crate_origin, None)
     }
diff --git a/crates/base-db/src/input.rs b/crates/base-db/src/input.rs
index e7f0c4ec29..b388e47dee 100644
--- a/crates/base-db/src/input.rs
+++ b/crates/base-db/src/input.rs
@@ -136,7 +136,7 @@ impl ops::Deref for CrateName {
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub enum CrateOrigin {
     /// Crates that are from crates.io official registry,
-    CratesIo { repo: Option<String>, name: Option<String> },
+    CratesIo { repo: Option<String> },
     /// Crates that are provided by the language, like std, core, proc-macro, ...
     Lang(LangCrateOrigin),
 }
@@ -648,7 +648,7 @@ mod tests {
             Env::default(),
             Ok(Vec::new()),
             false,
-            CrateOrigin::CratesIo { repo: None, name: None },
+            CrateOrigin::CratesIo { repo: None },
         );
         let crate2 = graph.add_crate_root(
             FileId(2u32),
@@ -660,7 +660,7 @@ mod tests {
             Env::default(),
             Ok(Vec::new()),
             false,
-            CrateOrigin::CratesIo { repo: None, name: None },
+            CrateOrigin::CratesIo { repo: None },
         );
         let crate3 = graph.add_crate_root(
             FileId(3u32),
@@ -672,7 +672,7 @@ mod tests {
             Env::default(),
             Ok(Vec::new()),
             false,
-            CrateOrigin::CratesIo { repo: None, name: None },
+            CrateOrigin::CratesIo { repo: None },
         );
         assert!(graph
             .add_dep(crate1, Dependency::new(CrateName::new("crate2").unwrap(), crate2))
@@ -698,7 +698,7 @@ mod tests {
             Env::default(),
             Ok(Vec::new()),
             false,
-            CrateOrigin::CratesIo { repo: None, name: None },
+            CrateOrigin::CratesIo { repo: None },
         );
         let crate2 = graph.add_crate_root(
             FileId(2u32),
@@ -710,7 +710,7 @@ mod tests {
             Env::default(),
             Ok(Vec::new()),
             false,
-            CrateOrigin::CratesIo { repo: None, name: None },
+            CrateOrigin::CratesIo { repo: None },
         );
         assert!(graph
             .add_dep(crate1, Dependency::new(CrateName::new("crate2").unwrap(), crate2))
@@ -733,7 +733,7 @@ mod tests {
             Env::default(),
             Ok(Vec::new()),
             false,
-            CrateOrigin::CratesIo { repo: None, name: None },
+            CrateOrigin::CratesIo { repo: None },
         );
         let crate2 = graph.add_crate_root(
             FileId(2u32),
@@ -745,7 +745,7 @@ mod tests {
             Env::default(),
             Ok(Vec::new()),
             false,
-            CrateOrigin::CratesIo { repo: None, name: None },
+            CrateOrigin::CratesIo { repo: None },
         );
         let crate3 = graph.add_crate_root(
             FileId(3u32),
@@ -757,7 +757,7 @@ mod tests {
             Env::default(),
             Ok(Vec::new()),
             false,
-            CrateOrigin::CratesIo { repo: None, name: None },
+            CrateOrigin::CratesIo { repo: None },
         );
         assert!(graph
             .add_dep(crate1, Dependency::new(CrateName::new("crate2").unwrap(), crate2))
@@ -780,7 +780,7 @@ mod tests {
             Env::default(),
             Ok(Vec::new()),
             false,
-            CrateOrigin::CratesIo { repo: None, name: None },
+            CrateOrigin::CratesIo { repo: None },
         );
         let crate2 = graph.add_crate_root(
             FileId(2u32),
@@ -792,7 +792,7 @@ mod tests {
             Env::default(),
             Ok(Vec::new()),
             false,
-            CrateOrigin::CratesIo { repo: None, name: None },
+            CrateOrigin::CratesIo { repo: None },
         );
         assert!(graph
             .add_dep(
diff --git a/crates/hir-def/src/adt.rs b/crates/hir-def/src/adt.rs
index 938db032fb..277135d6dc 100644
--- a/crates/hir-def/src/adt.rs
+++ b/crates/hir-def/src/adt.rs
@@ -1,12 +1,12 @@
 //! Defines hir-level representation of structs, enums and unions
 
-use std::{num::NonZeroU32, sync::Arc};
+use std::sync::Arc;
 
 use base_db::CrateId;
 use either::Either;
 use hir_expand::{
     name::{AsName, Name},
-    HirFileId, InFile,
+    InFile,
 };
 use la_arena::{Arena, ArenaMap};
 use syntax::ast::{self, HasName, HasVisibility};
@@ -14,18 +14,15 @@ use tt::{Delimiter, DelimiterKind, Leaf, Subtree, TokenTree};
 
 use crate::{
     body::{CfgExpander, LowerCtx},
-    builtin_type::{BuiltinInt, BuiltinUint},
     db::DefDatabase,
     intern::Interned,
-    item_tree::{AttrOwner, Field, FieldAstId, Fields, ItemTree, ModItem, RawVisibilityId},
-    nameres::diagnostics::DefDiagnostic,
+    item_tree::{AttrOwner, Field, Fields, ItemTree, ModItem, RawVisibilityId},
     src::HasChildSource,
     src::HasSource,
     trace::Trace,
     type_ref::TypeRef,
     visibility::RawVisibility,
-    EnumId, LocalEnumVariantId, LocalFieldId, LocalModuleId, Lookup, ModuleId, StructId, UnionId,
-    VariantId,
+    EnumId, LocalEnumVariantId, LocalFieldId, Lookup, ModuleId, StructId, UnionId, VariantId,
 };
 use cfg::CfgOptions;
 
@@ -34,7 +31,7 @@ use cfg::CfgOptions;
 pub struct StructData {
     pub name: Name,
     pub variant_data: Arc<VariantData>,
-    pub repr: Option<ReprData>,
+    pub repr: Option<ReprKind>,
     pub visibility: RawVisibility,
 }
 
@@ -42,7 +39,6 @@ pub struct StructData {
 pub struct EnumData {
     pub name: Name,
     pub variants: Arena<EnumVariantData>,
-    pub repr: Option<ReprData>,
     pub visibility: RawVisibility,
 }
 
@@ -67,19 +63,10 @@ pub struct FieldData {
     pub visibility: RawVisibility,
 }
 
-#[derive(Copy, Debug, Clone, PartialEq, Eq)]
+#[derive(Debug, Clone, PartialEq, Eq)]
 pub enum ReprKind {
-    C,
-    BuiltinInt { builtin: Either<BuiltinInt, BuiltinUint>, is_c: bool },
-    Transparent,
-    Default,
-}
-
-#[derive(Copy, Debug, Clone, PartialEq, Eq)]
-pub struct ReprData {
-    pub kind: ReprKind,
-    pub packed: bool,
-    pub align: Option<NonZeroU32>,
+    Packed,
+    Other,
 }
 
 fn repr_from_value(
@@ -87,71 +74,25 @@ fn repr_from_value(
     krate: CrateId,
     item_tree: &ItemTree,
     of: AttrOwner,
-) -> Option<ReprData> {
+) -> Option<ReprKind> {
     item_tree.attrs(db, krate, of).by_key("repr").tt_values().find_map(parse_repr_tt)
 }
 
-fn parse_repr_tt(tt: &Subtree) -> Option<ReprData> {
+fn parse_repr_tt(tt: &Subtree) -> Option<ReprKind> {
     match tt.delimiter {
         Some(Delimiter { kind: DelimiterKind::Parenthesis, .. }) => {}
         _ => return None,
     }
 
-    let mut data = ReprData { kind: ReprKind::Default, packed: false, align: None };
-
-    let mut tts = tt.token_trees.iter().peekable();
-    while let Some(tt) = tts.next() {
-        if let TokenTree::Leaf(Leaf::Ident(ident)) = tt {
-            match &*ident.text {
-                "packed" => {
-                    data.packed = true;
-                    if let Some(TokenTree::Subtree(_)) = tts.peek() {
-                        tts.next();
-                    }
-                }
-                "align" => {
-                    if let Some(TokenTree::Subtree(tt)) = tts.peek() {
-                        tts.next();
-                        if let Some(TokenTree::Leaf(Leaf::Literal(lit))) = tt.token_trees.first() {
-                            if let Ok(align) = lit.text.parse() {
-                                data.align = Some(align);
-                            }
-                        }
-                    }
-                }
-                "C" => {
-                    if let ReprKind::BuiltinInt { is_c, .. } = &mut data.kind {
-                        *is_c = true;
-                    } else {
-                        data.kind = ReprKind::C;
-                    }
-                }
-                "transparent" => data.kind = ReprKind::Transparent,
-                repr => {
-                    let is_c = matches!(data.kind, ReprKind::C);
-                    if let Some(builtin) = BuiltinInt::from_suffix(repr)
-                        .map(Either::Left)
-                        .or_else(|| BuiltinUint::from_suffix(repr).map(Either::Right))
-                    {
-                        data.kind = ReprKind::BuiltinInt { builtin, is_c };
-                    }
-                }
-            }
-        }
+    let mut it = tt.token_trees.iter();
+    match it.next()? {
+        TokenTree::Leaf(Leaf::Ident(ident)) if ident.text == "packed" => Some(ReprKind::Packed),
+        _ => Some(ReprKind::Other),
     }
-
-    Some(data)
 }
 
 impl StructData {
     pub(crate) fn struct_data_query(db: &dyn DefDatabase, id: StructId) -> Arc<StructData> {
-        db.struct_data_with_diagnostics(id).0
-    }
-
-    pub(crate) fn struct_data_with_diagnostics_query(
-        db: &dyn DefDatabase,
-        id: StructId,
-    ) -> (Arc<StructData>, Arc<[DefDiagnostic]>) {
         let loc = id.lookup(db);
         let krate = loc.container.krate;
         let item_tree = loc.id.item_tree(db);
@@ -159,35 +100,15 @@ impl StructData {
         let cfg_options = db.crate_graph()[loc.container.krate].cfg_options.clone();
 
         let strukt = &item_tree[loc.id.value];
-        let (variant_data, diagnostics) = lower_fields(
-            db,
-            krate,
-            loc.id.file_id(),
-            loc.container.local_id,
-            &item_tree,
-            &cfg_options,
-            &strukt.fields,
-            None,
-        );
-        (
-            Arc::new(StructData {
-                name: strukt.name.clone(),
-                variant_data: Arc::new(variant_data),
-                repr,
-                visibility: item_tree[strukt.visibility].clone(),
-            }),
-            diagnostics.into(),
-        )
+        let variant_data = lower_fields(db, krate, &item_tree, &cfg_options, &strukt.fields, None);
+        Arc::new(StructData {
+            name: strukt.name.clone(),
+            variant_data: Arc::new(variant_data),
+            repr,
+            visibility: item_tree[strukt.visibility].clone(),
+        })
     }
-
     pub(crate) fn union_data_query(db: &dyn DefDatabase, id: UnionId) -> Arc<StructData> {
-        db.union_data_with_diagnostics(id).0
-    }
-
-    pub(crate) fn union_data_with_diagnostics_query(
-        db: &dyn DefDatabase,
-        id: UnionId,
-    ) -> (Arc<StructData>, Arc<[DefDiagnostic]>) {
         let loc = id.lookup(db);
         let krate = loc.container.krate;
         let item_tree = loc.id.item_tree(db);
@@ -195,98 +116,56 @@ impl StructData {
         let cfg_options = db.crate_graph()[loc.container.krate].cfg_options.clone();
 
         let union = &item_tree[loc.id.value];
-        let (variant_data, diagnostics) = lower_fields(
-            db,
-            krate,
-            loc.id.file_id(),
-            loc.container.local_id,
-            &item_tree,
-            &cfg_options,
-            &union.fields,
-            None,
-        );
-        (
-            Arc::new(StructData {
-                name: union.name.clone(),
-                variant_data: Arc::new(variant_data),
-                repr,
-                visibility: item_tree[union.visibility].clone(),
-            }),
-            diagnostics.into(),
-        )
+        let variant_data = lower_fields(db, krate, &item_tree, &cfg_options, &union.fields, None);
+
+        Arc::new(StructData {
+            name: union.name.clone(),
+            variant_data: Arc::new(variant_data),
+            repr,
+            visibility: item_tree[union.visibility].clone(),
+        })
     }
 }
 
 impl EnumData {
     pub(crate) fn enum_data_query(db: &dyn DefDatabase, e: EnumId) -> Arc<EnumData> {
-        db.enum_data_with_diagnostics(e).0
-    }
-
-    pub(crate) fn enum_data_with_diagnostics_query(
-        db: &dyn DefDatabase,
-        e: EnumId,
-    ) -> (Arc<EnumData>, Arc<[DefDiagnostic]>) {
         let loc = e.lookup(db);
         let krate = loc.container.krate;
         let item_tree = loc.id.item_tree(db);
         let cfg_options = db.crate_graph()[krate].cfg_options.clone();
-        let repr = repr_from_value(db, krate, &item_tree, ModItem::from(loc.id.value).into());
 
         let enum_ = &item_tree[loc.id.value];
         let mut variants = Arena::new();
-        let mut diagnostics = Vec::new();
         for tree_id in enum_.variants.clone() {
-            let attrs = item_tree.attrs(db, krate, tree_id.into());
-            let var = &item_tree[tree_id];
-            if attrs.is_cfg_enabled(&cfg_options) {
-                let (var_data, field_diagnostics) = lower_fields(
+            if item_tree.attrs(db, krate, tree_id.into()).is_cfg_enabled(&cfg_options) {
+                let var = &item_tree[tree_id];
+                let var_data = lower_fields(
                     db,
                     krate,
-                    loc.id.file_id(),
-                    loc.container.local_id,
                     &item_tree,
                     &cfg_options,
                     &var.fields,
                     Some(enum_.visibility),
                 );
-                diagnostics.extend(field_diagnostics);
 
                 variants.alloc(EnumVariantData {
                     name: var.name.clone(),
                     variant_data: Arc::new(var_data),
                 });
-            } else {
-                diagnostics.push(DefDiagnostic::unconfigured_code(
-                    loc.container.local_id,
-                    InFile::new(loc.id.file_id(), var.ast_id.upcast()),
-                    attrs.cfg().unwrap(),
-                    cfg_options.clone(),
-                ))
             }
         }
 
-        (
-            Arc::new(EnumData {
-                name: enum_.name.clone(),
-                variants,
-                repr,
-                visibility: item_tree[enum_.visibility].clone(),
-            }),
-            diagnostics.into(),
-        )
+        Arc::new(EnumData {
+            name: enum_.name.clone(),
+            variants,
+            visibility: item_tree[enum_.visibility].clone(),
+        })
     }
 
     pub fn variant(&self, name: &Name) -> Option<LocalEnumVariantId> {
         let (id, _) = self.variants.iter().find(|(_id, data)| &data.name == name)?;
         Some(id)
     }
-
-    pub fn variant_body_type(&self) -> Either<BuiltinInt, BuiltinUint> {
-        match self.repr {
-            Some(ReprData { kind: ReprKind::BuiltinInt { builtin, .. }, .. }) => builtin,
-            _ => Either::Left(BuiltinInt::Isize),
-        }
-    }
 }
 
 impl HasChildSource<LocalEnumVariantId> for EnumId {
@@ -445,64 +324,31 @@ fn lower_struct(
 fn lower_fields(
     db: &dyn DefDatabase,
     krate: CrateId,
-    current_file_id: HirFileId,
-    container: LocalModuleId,
     item_tree: &ItemTree,
     cfg_options: &CfgOptions,
     fields: &Fields,
     override_visibility: Option<RawVisibilityId>,
-) -> (VariantData, Vec<DefDiagnostic>) {
-    let mut diagnostics = Vec::new();
+) -> VariantData {
     match fields {
         Fields::Record(flds) => {
             let mut arena = Arena::new();
             for field_id in flds.clone() {
-                let attrs = item_tree.attrs(db, krate, field_id.into());
-                let field = &item_tree[field_id];
-                if attrs.is_cfg_enabled(cfg_options) {
-                    arena.alloc(lower_field(item_tree, field, override_visibility));
-                } else {
-                    diagnostics.push(DefDiagnostic::unconfigured_code(
-                        container,
-                        InFile::new(
-                            current_file_id,
-                            match field.ast_id {
-                                FieldAstId::Record(it) => it.upcast(),
-                                FieldAstId::Tuple(it) => it.upcast(),
-                            },
-                        ),
-                        attrs.cfg().unwrap(),
-                        cfg_options.clone(),
-                    ))
+                if item_tree.attrs(db, krate, field_id.into()).is_cfg_enabled(cfg_options) {
+                    arena.alloc(lower_field(item_tree, &item_tree[field_id], override_visibility));
                 }
             }
-            (VariantData::Record(arena), diagnostics)
+            VariantData::Record(arena)
         }
         Fields::Tuple(flds) => {
             let mut arena = Arena::new();
             for field_id in flds.clone() {
-                let attrs = item_tree.attrs(db, krate, field_id.into());
-                let field = &item_tree[field_id];
-                if attrs.is_cfg_enabled(cfg_options) {
-                    arena.alloc(lower_field(item_tree, field, override_visibility));
-                } else {
-                    diagnostics.push(DefDiagnostic::unconfigured_code(
-                        container,
-                        InFile::new(
-                            current_file_id,
-                            match field.ast_id {
-                                FieldAstId::Record(it) => it.upcast(),
-                                FieldAstId::Tuple(it) => it.upcast(),
-                            },
-                        ),
-                        attrs.cfg().unwrap(),
-                        cfg_options.clone(),
-                    ))
+                if item_tree.attrs(db, krate, field_id.into()).is_cfg_enabled(cfg_options) {
+                    arena.alloc(lower_field(item_tree, &item_tree[field_id], override_visibility));
                 }
             }
-            (VariantData::Tuple(arena), diagnostics)
+            VariantData::Tuple(arena)
         }
-        Fields::Unit => (VariantData::Unit, diagnostics),
+        Fields::Unit => VariantData::Unit,
     }
 }
 
diff --git a/crates/hir-def/src/body.rs b/crates/hir-def/src/body.rs
index 2dc7714bbb..22f5fb9926 100644
--- a/crates/hir-def/src/body.rs
+++ b/crates/hir-def/src/body.rs
@@ -27,7 +27,7 @@ use crate::{
     macro_id_to_def_id,
     nameres::DefMap,
     path::{ModPath, Path},
-    src::{HasChildSource, HasSource},
+    src::HasSource,
     AsMacroCall, BlockId, DefWithBodyId, HasModule, LocalModuleId, Lookup, MacroId, ModuleId,
     UnresolvedMacro,
 };
@@ -324,12 +324,6 @@ impl Body {
                 let src = s.source(db);
                 (src.file_id, s.module(db), src.value.body())
             }
-            DefWithBodyId::VariantId(v) => {
-                let e = v.parent.lookup(db);
-                let src = v.parent.child_source(db);
-                let variant = &src.value[v.local_id];
-                (src.file_id, e.container, variant.expr())
-            }
         };
         let expander = Expander::new(db, file_id, module);
         let (mut body, source_map) = Body::new(db, expander, params, body);
diff --git a/crates/hir-def/src/body/lower.rs b/crates/hir-def/src/body/lower.rs
index c4f91e49a6..3b3297f781 100644
--- a/crates/hir-def/src/body/lower.rs
+++ b/crates/hir-def/src/body/lower.rs
@@ -29,9 +29,8 @@ use crate::{
     builtin_type::{BuiltinFloat, BuiltinInt, BuiltinUint},
     db::DefDatabase,
     expr::{
-        dummy_expr_id, Array, BindingAnnotation, ClosureKind, Expr, ExprId, FloatTypeWrapper,
-        Label, LabelId, Literal, MatchArm, Movability, Pat, PatId, RecordFieldPat, RecordLitField,
-        Statement,
+        dummy_expr_id, Array, BindingAnnotation, Expr, ExprId, FloatTypeWrapper, Label, LabelId,
+        Literal, MatchArm, Pat, PatId, RecordFieldPat, RecordLitField, Statement,
     },
     intern::Interned,
     item_scope::BuiltinShadowMode,
@@ -98,7 +97,6 @@ pub(super) fn lower(
         name_to_pat_grouping: Default::default(),
         is_lowering_inside_or_pat: false,
         is_lowering_assignee_expr: false,
-        is_lowering_generator: false,
     }
     .collect(params, body)
 }
@@ -113,7 +111,6 @@ struct ExprCollector<'a> {
     name_to_pat_grouping: FxHashMap<Name, Vec<PatId>>,
     is_lowering_inside_or_pat: bool,
     is_lowering_assignee_expr: bool,
-    is_lowering_generator: bool,
 }
 
 impl ExprCollector<'_> {
@@ -361,7 +358,6 @@ impl ExprCollector<'_> {
                 self.alloc_expr(Expr::Return { expr }, syntax_ptr)
             }
             ast::Expr::YieldExpr(e) => {
-                self.is_lowering_generator = true;
                 let expr = e.expr().map(|e| self.collect_expr(e));
                 self.alloc_expr(Expr::Yield { expr }, syntax_ptr)
             }
@@ -463,31 +459,13 @@ impl ExprCollector<'_> {
                     .ret_type()
                     .and_then(|r| r.ty())
                     .map(|it| Interned::new(TypeRef::from_ast(&self.ctx(), it)));
-
-                let prev_is_lowering_generator = self.is_lowering_generator;
-                self.is_lowering_generator = false;
-
                 let body = self.collect_expr_opt(e.body());
-
-                let closure_kind = if self.is_lowering_generator {
-                    let movability = if e.static_token().is_some() {
-                        Movability::Static
-                    } else {
-                        Movability::Movable
-                    };
-                    ClosureKind::Generator(movability)
-                } else {
-                    ClosureKind::Closure
-                };
-                self.is_lowering_generator = prev_is_lowering_generator;
-
                 self.alloc_expr(
                     Expr::Closure {
                         args: args.into(),
                         arg_types: arg_types.into(),
                         ret_type,
                         body,
-                        closure_kind,
                     },
                     syntax_ptr,
                 )
diff --git a/crates/hir-def/src/body/pretty.rs b/crates/hir-def/src/body/pretty.rs
index 162d173d52..f2fed95444 100644
--- a/crates/hir-def/src/body/pretty.rs
+++ b/crates/hir-def/src/body/pretty.rs
@@ -2,10 +2,8 @@
 
 use std::fmt::{self, Write};
 
-use syntax::ast::HasName;
-
 use crate::{
-    expr::{Array, BindingAnnotation, ClosureKind, Literal, Movability, Statement},
+    expr::{Array, BindingAnnotation, Literal, Statement},
     pretty::{print_generic_args, print_path, print_type_ref},
     type_ref::TypeRef,
 };
@@ -34,16 +32,6 @@ pub(super) fn print_body_hir(db: &dyn DefDatabase, body: &Body, owner: DefWithBo
             };
             format!("const {} = ", name)
         }
-        DefWithBodyId::VariantId(it) => {
-            needs_semi = false;
-            let src = it.parent.child_source(db);
-            let variant = &src.value[it.local_id];
-            let name = match &variant.name() {
-                Some(name) => name.to_string(),
-                None => "_".to_string(),
-            };
-            format!("{}", name)
-        }
     };
 
     let mut p = Printer { body, buf: header, indent_level: 0, needs_indent: false };
@@ -362,10 +350,7 @@ impl<'a> Printer<'a> {
                 self.print_expr(*index);
                 w!(self, "]");
             }
-            Expr::Closure { args, arg_types, ret_type, body, closure_kind } => {
-                if let ClosureKind::Generator(Movability::Static) = closure_kind {
-                    w!(self, "static ");
-                }
+            Expr::Closure { args, arg_types, ret_type, body } => {
                 w!(self, "|");
                 for (i, (pat, ty)) in args.iter().zip(arg_types.iter()).enumerate() {
                     if i != 0 {
diff --git a/crates/hir-def/src/child_by_source.rs b/crates/hir-def/src/child_by_source.rs
index bb13165257..5b1435e8f4 100644
--- a/crates/hir-def/src/child_by_source.rs
+++ b/crates/hir-def/src/child_by_source.rs
@@ -198,10 +198,6 @@ impl ChildBySource for EnumId {
 impl ChildBySource for DefWithBodyId {
     fn child_by_source_to(&self, db: &dyn DefDatabase, res: &mut DynMap, file_id: HirFileId) {
         let body = db.body(*self);
-        if let &DefWithBodyId::VariantId(v) = self {
-            VariantId::EnumVariantId(v).child_by_source_to(db, res, file_id)
-        }
-
         for (_, def_map) in body.blocks(db) {
             // All block expressions are merged into the same map, because they logically all add
             // inner items to the containing `DefWithBodyId`.
diff --git a/crates/hir-def/src/data.rs b/crates/hir-def/src/data.rs
index 2dc69b00ac..631ae3cf11 100644
--- a/crates/hir-def/src/data.rs
+++ b/crates/hir-def/src/data.rs
@@ -219,7 +219,7 @@ impl TraitData {
     pub(crate) fn trait_data_with_diagnostics_query(
         db: &dyn DefDatabase,
         tr: TraitId,
-    ) -> (Arc<TraitData>, Arc<[DefDiagnostic]>) {
+    ) -> (Arc<TraitData>, Arc<Vec<DefDiagnostic>>) {
         let tr_loc @ ItemLoc { container: module_id, id: tree_id } = tr.lookup(db);
         let item_tree = tree_id.item_tree(db);
         let tr_def = &item_tree[tree_id.value];
@@ -251,7 +251,7 @@ impl TraitData {
                 visibility,
                 skip_array_during_method_dispatch,
             }),
-            diagnostics.into(),
+            Arc::new(diagnostics),
         )
     }
 
@@ -299,7 +299,7 @@ impl ImplData {
     pub(crate) fn impl_data_with_diagnostics_query(
         db: &dyn DefDatabase,
         id: ImplId,
-    ) -> (Arc<ImplData>, Arc<[DefDiagnostic]>) {
+    ) -> (Arc<ImplData>, Arc<Vec<DefDiagnostic>>) {
         let _p = profile::span("impl_data_with_diagnostics_query");
         let ItemLoc { container: module_id, id: tree_id } = id.lookup(db);
 
@@ -318,7 +318,7 @@ impl ImplData {
 
         (
             Arc::new(ImplData { target_trait, self_ty, items, is_negative, attribute_calls }),
-            diagnostics.into(),
+            Arc::new(diagnostics),
         )
     }
 
diff --git a/crates/hir-def/src/db.rs b/crates/hir-def/src/db.rs
index 431c825549..40b2f734b7 100644
--- a/crates/hir-def/src/db.rs
+++ b/crates/hir-def/src/db.rs
@@ -97,33 +97,24 @@ pub trait DefDatabase: InternDatabase + AstDatabase + Upcast<dyn AstDatabase> {
     #[salsa::invoke(StructData::struct_data_query)]
     fn struct_data(&self, id: StructId) -> Arc<StructData>;
 
-    #[salsa::invoke(StructData::struct_data_with_diagnostics_query)]
-    fn struct_data_with_diagnostics(&self, id: StructId)
-        -> (Arc<StructData>, Arc<[DefDiagnostic]>);
-
     #[salsa::invoke(StructData::union_data_query)]
     fn union_data(&self, id: UnionId) -> Arc<StructData>;
 
-    #[salsa::invoke(StructData::union_data_with_diagnostics_query)]
-    fn union_data_with_diagnostics(&self, id: UnionId) -> (Arc<StructData>, Arc<[DefDiagnostic]>);
-
     #[salsa::invoke(EnumData::enum_data_query)]
     fn enum_data(&self, e: EnumId) -> Arc<EnumData>;
 
-    #[salsa::invoke(EnumData::enum_data_with_diagnostics_query)]
-    fn enum_data_with_diagnostics(&self, e: EnumId) -> (Arc<EnumData>, Arc<[DefDiagnostic]>);
-
     #[salsa::invoke(ImplData::impl_data_query)]
     fn impl_data(&self, e: ImplId) -> Arc<ImplData>;
 
     #[salsa::invoke(ImplData::impl_data_with_diagnostics_query)]
-    fn impl_data_with_diagnostics(&self, e: ImplId) -> (Arc<ImplData>, Arc<[DefDiagnostic]>);
+    fn impl_data_with_diagnostics(&self, e: ImplId) -> (Arc<ImplData>, Arc<Vec<DefDiagnostic>>);
 
     #[salsa::invoke(TraitData::trait_data_query)]
     fn trait_data(&self, e: TraitId) -> Arc<TraitData>;
 
     #[salsa::invoke(TraitData::trait_data_with_diagnostics_query)]
-    fn trait_data_with_diagnostics(&self, tr: TraitId) -> (Arc<TraitData>, Arc<[DefDiagnostic]>);
+    fn trait_data_with_diagnostics(&self, tr: TraitId)
+        -> (Arc<TraitData>, Arc<Vec<DefDiagnostic>>);
 
     #[salsa::invoke(TypeAliasData::type_alias_data_query)]
     fn type_alias_data(&self, e: TypeAliasId) -> Arc<TypeAliasData>;
diff --git a/crates/hir-def/src/expr.rs b/crates/hir-def/src/expr.rs
index 1626465502..419d3feec3 100644
--- a/crates/hir-def/src/expr.rs
+++ b/crates/hir-def/src/expr.rs
@@ -198,7 +198,6 @@ pub enum Expr {
         arg_types: Box<[Option<Interned<TypeRef>>]>,
         ret_type: Option<Interned<TypeRef>>,
         body: ExprId,
-        closure_kind: ClosureKind,
     },
     Tuple {
         exprs: Box<[ExprId]>,
@@ -212,18 +211,6 @@ pub enum Expr {
     Underscore,
 }
 
-#[derive(Debug, Clone, Copy, PartialEq, Eq)]
-pub enum ClosureKind {
-    Closure,
-    Generator(Movability),
-}
-
-#[derive(Debug, Clone, Copy, PartialEq, Eq)]
-pub enum Movability {
-    Static,
-    Movable,
-}
-
 #[derive(Debug, Clone, Eq, PartialEq)]
 pub enum Array {
     ElementList { elements: Box<[ExprId]>, is_assignee_expr: bool },
diff --git a/crates/hir-def/src/find_path.rs b/crates/hir-def/src/find_path.rs
index c70e6fdccd..b94b500040 100644
--- a/crates/hir-def/src/find_path.rs
+++ b/crates/hir-def/src/find_path.rs
@@ -333,8 +333,8 @@ fn calculate_best_path(
                     db,
                     def_map,
                     visited_modules,
-                    crate_root,
                     from,
+                    crate_root,
                     info.container,
                     max_len - 1,
                     prefixed,
diff --git a/crates/hir-def/src/item_tree.rs b/crates/hir-def/src/item_tree.rs
index 570344596d..3342d4db4a 100644
--- a/crates/hir-def/src/item_tree.rs
+++ b/crates/hir-def/src/item_tree.rs
@@ -943,7 +943,6 @@ impl AssocItem {
 pub struct Variant {
     pub name: Name,
     pub fields: Fields,
-    pub ast_id: FileAstId<ast::Variant>,
 }
 
 #[derive(Debug, Clone, PartialEq, Eq)]
@@ -953,17 +952,10 @@ pub enum Fields {
     Unit,
 }
 
-#[derive(Debug, Clone, PartialEq, Eq)]
-pub enum FieldAstId {
-    Record(FileAstId<ast::RecordField>),
-    Tuple(FileAstId<ast::TupleField>),
-}
-
 /// A single field of an enum variant or struct
 #[derive(Debug, Clone, PartialEq, Eq)]
 pub struct Field {
     pub name: Name,
     pub type_ref: Interned<TypeRef>,
     pub visibility: RawVisibilityId,
-    pub ast_id: FieldAstId,
 }
diff --git a/crates/hir-def/src/item_tree/lower.rs b/crates/hir-def/src/item_tree/lower.rs
index 077a1b619d..7f2551e941 100644
--- a/crates/hir-def/src/item_tree/lower.rs
+++ b/crates/hir-def/src/item_tree/lower.rs
@@ -184,8 +184,7 @@ impl<'a> Ctx<'a> {
         let name = field.name()?.as_name();
         let visibility = self.lower_visibility(field);
         let type_ref = self.lower_type_ref_opt(field.ty());
-        let ast_id = FieldAstId::Record(self.source_ast_id_map.ast_id(field));
-        let res = Field { name, type_ref, visibility, ast_id };
+        let res = Field { name, type_ref, visibility };
         Some(res)
     }
 
@@ -204,8 +203,7 @@ impl<'a> Ctx<'a> {
         let name = Name::new_tuple_field(idx);
         let visibility = self.lower_visibility(field);
         let type_ref = self.lower_type_ref_opt(field.ty());
-        let ast_id = FieldAstId::Tuple(self.source_ast_id_map.ast_id(field));
-        Field { name, type_ref, visibility, ast_id }
+        Field { name, type_ref, visibility }
     }
 
     fn lower_union(&mut self, union: &ast::Union) -> Option<FileItemTreeId<Union>> {
@@ -249,8 +247,7 @@ impl<'a> Ctx<'a> {
     fn lower_variant(&mut self, variant: &ast::Variant) -> Option<Variant> {
         let name = variant.name()?.as_name();
         let fields = self.lower_fields(&variant.kind());
-        let ast_id = self.source_ast_id_map.ast_id(variant);
-        let res = Variant { name, fields, ast_id };
+        let res = Variant { name, fields };
         Some(res)
     }
 
diff --git a/crates/hir-def/src/item_tree/pretty.rs b/crates/hir-def/src/item_tree/pretty.rs
index da1643152c..34dd817fd1 100644
--- a/crates/hir-def/src/item_tree/pretty.rs
+++ b/crates/hir-def/src/item_tree/pretty.rs
@@ -115,7 +115,7 @@ impl<'a> Printer<'a> {
                 w!(self, "{{");
                 self.indented(|this| {
                     for field in fields.clone() {
-                        let Field { visibility, name, type_ref, ast_id: _ } = &this.tree[field];
+                        let Field { visibility, name, type_ref } = &this.tree[field];
                         this.print_attrs_of(field);
                         this.print_visibility(*visibility);
                         w!(this, "{}: ", name);
@@ -129,7 +129,7 @@ impl<'a> Printer<'a> {
                 w!(self, "(");
                 self.indented(|this| {
                     for field in fields.clone() {
-                        let Field { visibility, name, type_ref, ast_id: _ } = &this.tree[field];
+                        let Field { visibility, name, type_ref } = &this.tree[field];
                         this.print_attrs_of(field);
                         this.print_visibility(*visibility);
                         w!(this, "{}: ", name);
@@ -323,7 +323,7 @@ impl<'a> Printer<'a> {
                 self.print_where_clause_and_opening_brace(generic_params);
                 self.indented(|this| {
                     for variant in variants.clone() {
-                        let Variant { name, fields, ast_id: _ } = &this.tree[variant];
+                        let Variant { name, fields } = &this.tree[variant];
                         this.print_attrs_of(variant);
                         w!(this, "{}", name);
                         this.print_fields(fields);
diff --git a/crates/hir-def/src/lib.rs b/crates/hir-def/src/lib.rs
index 5c7aa72349..32ebfda4fd 100644
--- a/crates/hir-def/src/lib.rs
+++ b/crates/hir-def/src/lib.rs
@@ -474,24 +474,16 @@ pub enum DefWithBodyId {
     FunctionId(FunctionId),
     StaticId(StaticId),
     ConstId(ConstId),
-    VariantId(EnumVariantId),
 }
 
 impl_from!(FunctionId, ConstId, StaticId for DefWithBodyId);
 
-impl From<EnumVariantId> for DefWithBodyId {
-    fn from(id: EnumVariantId) -> Self {
-        DefWithBodyId::VariantId(id)
-    }
-}
-
 impl DefWithBodyId {
     pub fn as_generic_def_id(self) -> Option<GenericDefId> {
         match self {
             DefWithBodyId::FunctionId(f) => Some(f.into()),
             DefWithBodyId::StaticId(_) => None,
             DefWithBodyId::ConstId(c) => Some(c.into()),
-            DefWithBodyId::VariantId(c) => Some(c.into()),
         }
     }
 }
@@ -689,7 +681,6 @@ impl HasModule for DefWithBodyId {
             DefWithBodyId::FunctionId(it) => it.lookup(db).module(db),
             DefWithBodyId::StaticId(it) => it.lookup(db).module(db),
             DefWithBodyId::ConstId(it) => it.lookup(db).module(db),
-            DefWithBodyId::VariantId(it) => it.parent.lookup(db).container,
         }
     }
 }
@@ -700,7 +691,6 @@ impl DefWithBodyId {
             DefWithBodyId::FunctionId(it) => it.lookup(db).id.value.into(),
             DefWithBodyId::StaticId(it) => it.lookup(db).id.value.into(),
             DefWithBodyId::ConstId(it) => it.lookup(db).id.value.into(),
-            DefWithBodyId::VariantId(it) => it.parent.lookup(db).id.value.into(),
         }
     }
 }
diff --git a/crates/hir-def/src/nameres/collector.rs b/crates/hir-def/src/nameres/collector.rs
index 9ffc218818..9242b48c59 100644
--- a/crates/hir-def/src/nameres/collector.rs
+++ b/crates/hir-def/src/nameres/collector.rs
@@ -2122,7 +2122,7 @@ impl ModCollector<'_, '_> {
     fn emit_unconfigured_diagnostic(&mut self, item: ModItem, cfg: &CfgExpr) {
         let ast_id = item.ast_id(self.item_tree);
 
-        let ast_id = InFile::new(self.file_id(), ast_id.upcast());
+        let ast_id = InFile::new(self.file_id(), ast_id);
         self.def_collector.def_map.diagnostics.push(DefDiagnostic::unconfigured_code(
             self.module_id,
             ast_id,
diff --git a/crates/hir-def/src/nameres/diagnostics.rs b/crates/hir-def/src/nameres/diagnostics.rs
index 0661422919..ed7e920fd2 100644
--- a/crates/hir-def/src/nameres/diagnostics.rs
+++ b/crates/hir-def/src/nameres/diagnostics.rs
@@ -4,7 +4,7 @@ use base_db::CrateId;
 use cfg::{CfgExpr, CfgOptions};
 use hir_expand::MacroCallKind;
 use la_arena::Idx;
-use syntax::ast::{self, AnyHasAttrs};
+use syntax::ast;
 
 use crate::{
     attr::AttrId,
@@ -22,7 +22,7 @@ pub enum DefDiagnosticKind {
 
     UnresolvedImport { id: ItemTreeId<item_tree::Import>, index: Idx<ast::UseTree> },
 
-    UnconfiguredCode { ast: AstId<AnyHasAttrs>, cfg: CfgExpr, opts: CfgOptions },
+    UnconfiguredCode { ast: AstId<ast::Item>, cfg: CfgExpr, opts: CfgOptions },
 
     UnresolvedProcMacro { ast: MacroCallKind, krate: CrateId },
 
@@ -75,7 +75,7 @@ impl DefDiagnostic {
 
     pub fn unconfigured_code(
         container: LocalModuleId,
-        ast: AstId<ast::AnyHasAttrs>,
+        ast: AstId<ast::Item>,
         cfg: CfgExpr,
         opts: CfgOptions,
     ) -> Self {
diff --git a/crates/hir-def/src/resolver.rs b/crates/hir-def/src/resolver.rs
index 070f683713..8aa5973cac 100644
--- a/crates/hir-def/src/resolver.rs
+++ b/crates/hir-def/src/resolver.rs
@@ -839,7 +839,6 @@ impl HasResolver for DefWithBodyId {
             DefWithBodyId::ConstId(c) => c.resolver(db),
             DefWithBodyId::FunctionId(f) => f.resolver(db),
             DefWithBodyId::StaticId(s) => s.resolver(db),
-            DefWithBodyId::VariantId(v) => v.parent.resolver(db),
         }
     }
 }
diff --git a/crates/hir-expand/src/ast_id_map.rs b/crates/hir-expand/src/ast_id_map.rs
index 2b27db0e95..11c0a6764e 100644
--- a/crates/hir-expand/src/ast_id_map.rs
+++ b/crates/hir-expand/src/ast_id_map.rs
@@ -93,12 +93,7 @@ impl AstIdMap {
         // trait does not change ids of top-level items, which helps caching.
         bdfs(node, |it| {
             let kind = it.kind();
-            if ast::Item::can_cast(kind)
-                || ast::BlockExpr::can_cast(kind)
-                || ast::Variant::can_cast(kind)
-                || ast::RecordField::can_cast(kind)
-                || ast::TupleField::can_cast(kind)
-            {
+            if ast::Item::can_cast(kind) || ast::BlockExpr::can_cast(kind) {
                 res.alloc(&it);
                 true
             } else {
diff --git a/crates/hir-expand/src/name.rs b/crates/hir-expand/src/name.rs
index 2679a1c360..4ce21a5796 100644
--- a/crates/hir-expand/src/name.rs
+++ b/crates/hir-expand/src/name.rs
@@ -263,7 +263,6 @@ pub mod known {
         Iterator,
         IntoIterator,
         Item,
-        IntoIter,
         Try,
         Ok,
         Future,
diff --git a/crates/hir-ty/src/builder.rs b/crates/hir-ty/src/builder.rs
index 3ae7fb2a61..94d7806cb6 100644
--- a/crates/hir-ty/src/builder.rs
+++ b/crates/hir-ty/src/builder.rs
@@ -9,8 +9,8 @@ use chalk_ir::{
     AdtId, BoundVar, DebruijnIndex, Scalar,
 };
 use hir_def::{
-    builtin_type::BuiltinType, generics::TypeOrConstParamData, ConstParamId, DefWithBodyId,
-    GenericDefId, TraitId, TypeAliasId,
+    builtin_type::BuiltinType, generics::TypeOrConstParamData, ConstParamId, GenericDefId, TraitId,
+    TypeAliasId,
 };
 use smallvec::SmallVec;
 
@@ -205,38 +205,6 @@ impl TyBuilder<()> {
         )
     }
 
-    /// Creates a `TyBuilder` to build `Substitution` for a generator defined in `parent`.
-    ///
-    /// A generator's substitution consists of:
-    /// - generic parameters in scope on `parent`
-    /// - resume type of generator
-    /// - yield type of generator ([`Generator::Yield`](std::ops::Generator::Yield))
-    /// - return type of generator ([`Generator::Return`](std::ops::Generator::Return))
-    /// in this order.
-    ///
-    /// This method prepopulates the builder with placeholder substitution of `parent`, so you
-    /// should only push exactly 3 `GenericArg`s before building.
-    pub fn subst_for_generator(db: &dyn HirDatabase, parent: DefWithBodyId) -> TyBuilder<()> {
-        let parent_subst = match parent.as_generic_def_id() {
-            Some(parent) => generics(db.upcast(), parent).placeholder_subst(db),
-            // Static initializers *may* contain generators.
-            None => Substitution::empty(Interner),
-        };
-        let builder = TyBuilder::new(
-            (),
-            parent_subst
-                .iter(Interner)
-                .map(|arg| match arg.constant(Interner) {
-                    Some(c) => ParamKind::Const(c.data(Interner).ty.clone()),
-                    None => ParamKind::Type,
-                })
-                // These represent resume type, yield type, and return type of generator.
-                .chain(std::iter::repeat(ParamKind::Type).take(3))
-                .collect(),
-        );
-        builder.use_parent_substs(&parent_subst)
-    }
-
     pub fn build(self) -> Substitution {
         let ((), subst) = self.build_internal();
         subst
diff --git a/crates/hir-ty/src/chalk_db.rs b/crates/hir-ty/src/chalk_db.rs
index c5cf6729d1..faec99c7d3 100644
--- a/crates/hir-ty/src/chalk_db.rs
+++ b/crates/hir-ty/src/chalk_db.rs
@@ -11,7 +11,6 @@ use chalk_solve::rust_ir::{self, OpaqueTyDatumBound, WellKnownTrait};
 
 use base_db::CrateId;
 use hir_def::{
-    expr::Movability,
     lang_item::{lang_attr, LangItemTarget},
     AssocItemId, GenericDefId, HasModule, ItemContainerId, Lookup, ModuleId, TypeAliasId,
 };
@@ -27,9 +26,9 @@ use crate::{
     to_assoc_type_id, to_chalk_trait_id,
     traits::ChalkContext,
     utils::generics,
-    wrap_empty_binders, AliasEq, AliasTy, BoundVar, CallableDefId, DebruijnIndex, FnDefId,
-    Interner, ProjectionTy, ProjectionTyExt, QuantifiedWhereClause, Substitution, TraitRef,
-    TraitRefExt, Ty, TyBuilder, TyExt, TyKind, WhereClause,
+    AliasEq, AliasTy, BoundVar, CallableDefId, DebruijnIndex, FnDefId, Interner, ProjectionTy,
+    ProjectionTyExt, QuantifiedWhereClause, Substitution, TraitRef, TraitRefExt, Ty, TyBuilder,
+    TyExt, TyKind, WhereClause,
 };
 
 pub(crate) type AssociatedTyDatum = chalk_solve::rust_ir::AssociatedTyDatum<Interner>;
@@ -373,63 +372,17 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
     }
     fn generator_datum(
         &self,
-        id: chalk_ir::GeneratorId<Interner>,
+        _: chalk_ir::GeneratorId<Interner>,
     ) -> std::sync::Arc<chalk_solve::rust_ir::GeneratorDatum<Interner>> {
-        let (parent, expr) = self.db.lookup_intern_generator(id.into());
-
-        // We fill substitution with unknown type, because we only need to know whether the generic
-        // params are types or consts to build `Binders` and those being filled up are for
-        // `resume_type`, `yield_type`, and `return_type` of the generator in question.
-        let subst = TyBuilder::subst_for_generator(self.db, parent).fill_with_unknown().build();
-
-        let len = subst.len(Interner);
-        let input_output = rust_ir::GeneratorInputOutputDatum {
-            resume_type: TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, len - 3))
-                .intern(Interner),
-            yield_type: TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, len - 2))
-                .intern(Interner),
-            return_type: TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, len - 1))
-                .intern(Interner),
-            // FIXME: calculate upvars
-            upvars: vec![],
-        };
-
-        let it = subst
-            .iter(Interner)
-            .map(|it| it.constant(Interner).map(|c| c.data(Interner).ty.clone()));
-        let input_output = crate::make_type_and_const_binders(it, input_output);
-
-        let movability = match self.db.body(parent)[expr] {
-            hir_def::expr::Expr::Closure {
-                closure_kind: hir_def::expr::ClosureKind::Generator(movability),
-                ..
-            } => movability,
-            _ => unreachable!("non generator expression interned as generator"),
-        };
-        let movability = match movability {
-            Movability::Static => rust_ir::Movability::Static,
-            Movability::Movable => rust_ir::Movability::Movable,
-        };
-
-        Arc::new(rust_ir::GeneratorDatum { movability, input_output })
+        // FIXME
+        unimplemented!()
     }
     fn generator_witness_datum(
         &self,
-        id: chalk_ir::GeneratorId<Interner>,
+        _: chalk_ir::GeneratorId<Interner>,
     ) -> std::sync::Arc<chalk_solve::rust_ir::GeneratorWitnessDatum<Interner>> {
-        // FIXME: calculate inner types
-        let inner_types =
-            rust_ir::GeneratorWitnessExistential { types: wrap_empty_binders(vec![]) };
-
-        let (parent, _) = self.db.lookup_intern_generator(id.into());
-        // See the comment in `generator_datum()` for unknown types.
-        let subst = TyBuilder::subst_for_generator(self.db, parent).fill_with_unknown().build();
-        let it = subst
-            .iter(Interner)
-            .map(|it| it.constant(Interner).map(|c| c.data(Interner).ty.clone()));
-        let inner_types = crate::make_type_and_const_binders(it, inner_types);
-
-        Arc::new(rust_ir::GeneratorWitnessDatum { inner_types })
+        // FIXME
+        unimplemented!()
     }
 
     fn unification_database(&self) -> &dyn chalk_ir::UnificationDatabase<Interner> {
diff --git a/crates/hir-ty/src/chalk_ext.rs b/crates/hir-ty/src/chalk_ext.rs
index ed97bd2da4..4a5533c648 100644
--- a/crates/hir-ty/src/chalk_ext.rs
+++ b/crates/hir-ty/src/chalk_ext.rs
@@ -166,8 +166,6 @@ impl TyExt for Ty {
         let trait_ref = match self.kind(Interner) {
             // The principal trait bound should be the first element of the bounds. This is an
             // invariant ensured by `TyLoweringContext::lower_dyn_trait()`.
-            // FIXME: dyn types may not have principal trait and we don't want to return auto trait
-            // here.
             TyKind::Dyn(dyn_ty) => dyn_ty.bounds.skip_binders().interned().get(0).and_then(|b| {
                 match b.skip_binders() {
                     WhereClause::Implemented(trait_ref) => Some(trait_ref),
diff --git a/crates/hir-ty/src/consteval.rs b/crates/hir-ty/src/consteval.rs
index 2c0c6e0b83..6ecb6e6fd1 100644
--- a/crates/hir-ty/src/consteval.rs
+++ b/crates/hir-ty/src/consteval.rs
@@ -7,17 +7,14 @@ use std::{
 
 use chalk_ir::{BoundVar, DebruijnIndex, GenericArgData, IntTy, Scalar};
 use hir_def::{
-    builtin_type::BuiltinInt,
     expr::{ArithOp, BinaryOp, Expr, ExprId, Literal, Pat, PatId},
     path::ModPath,
     resolver::{resolver_for_expr, ResolveValueResult, Resolver, ValueNs},
-    src::HasChildSource,
     type_ref::ConstScalar,
-    ConstId, DefWithBodyId, EnumVariantId, Lookup,
+    ConstId, DefWithBodyId,
 };
-use la_arena::{Arena, Idx, RawIdx};
+use la_arena::{Arena, Idx};
 use stdx::never;
-use syntax::ast::HasName;
 
 use crate::{
     db::HirDatabase, infer::InferenceContext, lower::ParamLoweringMode, to_placeholder_idx,
@@ -80,7 +77,6 @@ pub enum ConstEvalError {
 #[derive(Debug, Clone, PartialEq, Eq)]
 pub enum ComputedExpr {
     Literal(Literal),
-    Enum(String, EnumVariantId, Literal),
     Tuple(Box<[ComputedExpr]>),
 }
 
@@ -108,7 +104,6 @@ impl Display for ComputedExpr {
                 Literal::String(x) => std::fmt::Debug::fmt(x, f),
                 Literal::ByteString(x) => std::fmt::Debug::fmt(x, f),
             },
-            ComputedExpr::Enum(name, _, _) => name.fmt(f),
             ComputedExpr::Tuple(t) => {
                 f.write_char('(')?;
                 for x in &**t {
@@ -153,51 +148,13 @@ fn is_valid(scalar: &Scalar, value: i128) -> bool {
     }
 }
 
-fn get_name(ctx: &mut ConstEvalCtx<'_>, variant: EnumVariantId) -> String {
-    let loc = variant.parent.lookup(ctx.db.upcast());
-    let children = variant.parent.child_source(ctx.db.upcast());
-    let item_tree = loc.id.item_tree(ctx.db.upcast());
-
-    let variant_name = children.value[variant.local_id].name();
-    let enum_name = item_tree[loc.id.value].name.to_string();
-    enum_name + "::" + &variant_name.unwrap().to_string()
-}
-
 pub fn eval_const(
     expr_id: ExprId,
     ctx: &mut ConstEvalCtx<'_>,
 ) -> Result<ComputedExpr, ConstEvalError> {
-    let u128_to_i128 = |it: u128| -> Result<i128, ConstEvalError> {
-        it.try_into().map_err(|_| ConstEvalError::NotSupported("u128 is too big"))
-    };
-
     let expr = &ctx.exprs[expr_id];
     match expr {
-        Expr::Missing => match ctx.owner {
-            // evaluate the implicit variant index of an enum variant without expression
-            // FIXME: This should return the type of the enum representation
-            DefWithBodyId::VariantId(variant) => {
-                let prev_idx: u32 = variant.local_id.into_raw().into();
-                let prev_idx = prev_idx.checked_sub(1).map(RawIdx::from).map(Idx::from_raw);
-                let value = match prev_idx {
-                    Some(local_id) => {
-                        let prev_variant = EnumVariantId { local_id, parent: variant.parent };
-                        1 + match ctx.db.const_eval_variant(prev_variant)? {
-                            ComputedExpr::Literal(Literal::Int(v, _)) => v,
-                            ComputedExpr::Literal(Literal::Uint(v, _)) => u128_to_i128(v)?,
-                            _ => {
-                                return Err(ConstEvalError::NotSupported(
-                                    "Enum can't contain this kind of value",
-                                ))
-                            }
-                        }
-                    }
-                    _ => 0,
-                };
-                Ok(ComputedExpr::Literal(Literal::Int(value, Some(BuiltinInt::I128))))
-            }
-            _ => Err(ConstEvalError::IncompleteExpr),
-        },
+        Expr::Missing => Err(ConstEvalError::IncompleteExpr),
         Expr::Literal(l) => Ok(ComputedExpr::Literal(l.clone())),
         &Expr::UnaryOp { expr, op } => {
             let ty = &ctx.expr_ty(expr);
@@ -210,7 +167,9 @@ pub fn eval_const(
                             return Ok(ComputedExpr::Literal(Literal::Bool(!b)))
                         }
                         ComputedExpr::Literal(Literal::Int(v, _)) => v,
-                        ComputedExpr::Literal(Literal::Uint(v, _)) => u128_to_i128(v)?,
+                        ComputedExpr::Literal(Literal::Uint(v, _)) => v
+                            .try_into()
+                            .map_err(|_| ConstEvalError::NotSupported("too big u128"))?,
                         _ => return Err(ConstEvalError::NotSupported("this kind of operator")),
                     };
                     let r = match ty.kind(Interner) {
@@ -239,7 +198,9 @@ pub fn eval_const(
                 hir_def::expr::UnaryOp::Neg => {
                     let v = match ev {
                         ComputedExpr::Literal(Literal::Int(v, _)) => v,
-                        ComputedExpr::Literal(Literal::Uint(v, _)) => u128_to_i128(v)?,
+                        ComputedExpr::Literal(Literal::Uint(v, _)) => v
+                            .try_into()
+                            .map_err(|_| ConstEvalError::NotSupported("too big u128"))?,
                         _ => return Err(ConstEvalError::NotSupported("this kind of operator")),
                     };
                     Ok(ComputedExpr::Literal(Literal::Int(
@@ -258,12 +219,16 @@ pub fn eval_const(
             let op = op.ok_or(ConstEvalError::IncompleteExpr)?;
             let v1 = match lhs {
                 ComputedExpr::Literal(Literal::Int(v, _)) => v,
-                ComputedExpr::Literal(Literal::Uint(v, _)) => u128_to_i128(v)?,
+                ComputedExpr::Literal(Literal::Uint(v, _)) => {
+                    v.try_into().map_err(|_| ConstEvalError::NotSupported("too big u128"))?
+                }
                 _ => return Err(ConstEvalError::NotSupported("this kind of operator")),
             };
             let v2 = match rhs {
                 ComputedExpr::Literal(Literal::Int(v, _)) => v,
-                ComputedExpr::Literal(Literal::Uint(v, _)) => u128_to_i128(v)?,
+                ComputedExpr::Literal(Literal::Uint(v, _)) => {
+                    v.try_into().map_err(|_| ConstEvalError::NotSupported("too big u128"))?
+                }
                 _ => return Err(ConstEvalError::NotSupported("this kind of operator")),
             };
             match op {
@@ -374,22 +339,9 @@ pub fn eval_const(
                 ValueNs::GenericParam(_) => {
                     Err(ConstEvalError::NotSupported("const generic without substitution"))
                 }
-                ValueNs::EnumVariantId(id) => match ctx.db.const_eval_variant(id)? {
-                    ComputedExpr::Literal(lit) => {
-                        Ok(ComputedExpr::Enum(get_name(ctx, id), id, lit))
-                    }
-                    _ => Err(ConstEvalError::NotSupported(
-                        "Enums can't evalute to anything but numbers",
-                    )),
-                },
                 _ => Err(ConstEvalError::NotSupported("path that are not const or local")),
             }
         }
-        // FIXME: Handle the cast target
-        &Expr::Cast { expr, .. } => match eval_const(expr, ctx)? {
-            ComputedExpr::Enum(_, _, lit) => Ok(ComputedExpr::Literal(lit)),
-            _ => Err(ConstEvalError::NotSupported("Can't cast these types")),
-        },
         _ => Err(ConstEvalError::NotSupported("This kind of expression")),
     }
 }
@@ -460,15 +412,7 @@ pub(crate) fn const_eval_recover(
     Err(ConstEvalError::Loop)
 }
 
-pub(crate) fn const_eval_variant_recover(
-    _: &dyn HirDatabase,
-    _: &[String],
-    _: &EnumVariantId,
-) -> Result<ComputedExpr, ConstEvalError> {
-    Err(ConstEvalError::Loop)
-}
-
-pub(crate) fn const_eval_variant_query(
+pub(crate) fn const_eval_query(
     db: &dyn HirDatabase,
     const_id: ConstId,
 ) -> Result<ComputedExpr, ConstEvalError> {
@@ -489,26 +433,6 @@ pub(crate) fn const_eval_variant_query(
     result
 }
 
-pub(crate) fn const_eval_query_variant(
-    db: &dyn HirDatabase,
-    variant_id: EnumVariantId,
-) -> Result<ComputedExpr, ConstEvalError> {
-    let def = variant_id.into();
-    let body = db.body(def);
-    let infer = &db.infer(def);
-    eval_const(
-        body.body_expr,
-        &mut ConstEvalCtx {
-            db,
-            owner: def,
-            exprs: &body.exprs,
-            pats: &body.pats,
-            local_data: HashMap::default(),
-            infer,
-        },
-    )
-}
-
 pub(crate) fn eval_to_const<'a>(
     expr: Idx<Expr>,
     mode: ParamLoweringMode,
diff --git a/crates/hir-ty/src/db.rs b/crates/hir-ty/src/db.rs
index 932fce8356..69283e55a4 100644
--- a/crates/hir-ty/src/db.rs
+++ b/crates/hir-ty/src/db.rs
@@ -6,8 +6,8 @@ use std::sync::Arc;
 use arrayvec::ArrayVec;
 use base_db::{impl_intern_key, salsa, CrateId, Upcast};
 use hir_def::{
-    db::DefDatabase, expr::ExprId, BlockId, ConstId, ConstParamId, DefWithBodyId, EnumVariantId,
-    FunctionId, GenericDefId, ImplId, LifetimeParamId, LocalFieldId, TypeOrConstParamId, VariantId,
+    db::DefDatabase, expr::ExprId, BlockId, ConstId, ConstParamId, DefWithBodyId, FunctionId,
+    GenericDefId, ImplId, LifetimeParamId, LocalFieldId, TypeOrConstParamId, VariantId,
 };
 use la_arena::ArenaMap;
 
@@ -43,14 +43,10 @@ pub trait HirDatabase: DefDatabase + Upcast<dyn DefDatabase> {
     #[salsa::invoke(crate::lower::const_param_ty_query)]
     fn const_param_ty(&self, def: ConstParamId) -> Ty;
 
-    #[salsa::invoke(crate::consteval::const_eval_variant_query)]
+    #[salsa::invoke(crate::consteval::const_eval_query)]
     #[salsa::cycle(crate::consteval::const_eval_recover)]
     fn const_eval(&self, def: ConstId) -> Result<ComputedExpr, ConstEvalError>;
 
-    #[salsa::invoke(crate::consteval::const_eval_query_variant)]
-    #[salsa::cycle(crate::consteval::const_eval_variant_recover)]
-    fn const_eval_variant(&self, def: EnumVariantId) -> Result<ComputedExpr, ConstEvalError>;
-
     #[salsa::invoke(crate::lower::impl_trait_query)]
     fn impl_trait(&self, def: ImplId) -> Option<Binders<TraitRef>>;
 
@@ -120,8 +116,6 @@ pub trait HirDatabase: DefDatabase + Upcast<dyn DefDatabase> {
     fn intern_impl_trait_id(&self, id: ImplTraitId) -> InternedOpaqueTyId;
     #[salsa::interned]
     fn intern_closure(&self, id: (DefWithBodyId, ExprId)) -> InternedClosureId;
-    #[salsa::interned]
-    fn intern_generator(&self, id: (DefWithBodyId, ExprId)) -> InternedGeneratorId;
 
     #[salsa::invoke(chalk_db::associated_ty_data_query)]
     fn associated_ty_data(&self, id: chalk_db::AssocTypeId) -> Arc<chalk_db::AssociatedTyDatum>;
@@ -194,9 +188,6 @@ fn infer_wait(db: &dyn HirDatabase, def: DefWithBodyId) -> Arc<InferenceResult>
         DefWithBodyId::ConstId(it) => {
             db.const_data(it).name.clone().unwrap_or_else(Name::missing).to_string()
         }
-        DefWithBodyId::VariantId(it) => {
-            db.enum_data(it.parent).variants[it.local_id].name.to_string()
-        }
     });
     db.infer_query(def)
 }
@@ -235,10 +226,6 @@ impl_intern_key!(InternedOpaqueTyId);
 pub struct InternedClosureId(salsa::InternId);
 impl_intern_key!(InternedClosureId);
 
-#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
-pub struct InternedGeneratorId(salsa::InternId);
-impl_intern_key!(InternedGeneratorId);
-
 /// This exists just for Chalk, because Chalk just has a single `FnDefId` where
 /// we have different IDs for struct and enum variant constructors.
 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)]
diff --git a/crates/hir-ty/src/diagnostics/unsafe_check.rs b/crates/hir-ty/src/diagnostics/unsafe_check.rs
index 431ab949b4..161b19a739 100644
--- a/crates/hir-ty/src/diagnostics/unsafe_check.rs
+++ b/crates/hir-ty/src/diagnostics/unsafe_check.rs
@@ -18,9 +18,7 @@ pub fn missing_unsafe(db: &dyn HirDatabase, def: DefWithBodyId) -> Vec<ExprId> {
 
     let is_unsafe = match def {
         DefWithBodyId::FunctionId(it) => db.function_data(it).has_unsafe_kw(),
-        DefWithBodyId::StaticId(_) | DefWithBodyId::ConstId(_) | DefWithBodyId::VariantId(_) => {
-            false
-        }
+        DefWithBodyId::StaticId(_) | DefWithBodyId::ConstId(_) => false,
     };
     if is_unsafe {
         return res;
diff --git a/crates/hir-ty/src/display.rs b/crates/hir-ty/src/display.rs
index a5058f71a4..874abdaea8 100644
--- a/crates/hir-ty/src/display.rs
+++ b/crates/hir-ty/src/display.rs
@@ -20,7 +20,6 @@ use hir_def::{
 };
 use hir_expand::{hygiene::Hygiene, name::Name};
 use itertools::Itertools;
-use smallvec::SmallVec;
 use syntax::SmolStr;
 
 use crate::{
@@ -222,7 +221,6 @@ pub enum DisplaySourceCodeError {
     PathNotFound,
     UnknownType,
     Closure,
-    Generator,
 }
 
 pub enum HirDisplayError {
@@ -785,34 +783,7 @@ impl HirDisplay for Ty {
                 write!(f, "{{unknown}}")?;
             }
             TyKind::InferenceVar(..) => write!(f, "_")?,
-            TyKind::Generator(_, subst) => {
-                if f.display_target.is_source_code() {
-                    return Err(HirDisplayError::DisplaySourceCodeError(
-                        DisplaySourceCodeError::Generator,
-                    ));
-                }
-
-                let subst = subst.as_slice(Interner);
-                let a: Option<SmallVec<[&Ty; 3]>> = subst
-                    .get(subst.len() - 3..)
-                    .map(|args| args.iter().map(|arg| arg.ty(Interner)).collect())
-                    .flatten();
-
-                if let Some([resume_ty, yield_ty, ret_ty]) = a.as_deref() {
-                    write!(f, "|")?;
-                    resume_ty.hir_fmt(f)?;
-                    write!(f, "|")?;
-
-                    write!(f, " yields ")?;
-                    yield_ty.hir_fmt(f)?;
-
-                    write!(f, " -> ")?;
-                    ret_ty.hir_fmt(f)?;
-                } else {
-                    // This *should* be unreachable, but fallback just in case.
-                    write!(f, "{{generator}}")?;
-                }
-            }
+            TyKind::Generator(..) => write!(f, "{{generator}}")?,
             TyKind::GeneratorWitness(..) => write!(f, "{{generator witness}}")?,
         }
         Ok(())
diff --git a/crates/hir-ty/src/infer.rs b/crates/hir-ty/src/infer.rs
index 25179afaca..e37763e8ea 100644
--- a/crates/hir-ty/src/infer.rs
+++ b/crates/hir-ty/src/infer.rs
@@ -19,7 +19,6 @@ use std::sync::Arc;
 use chalk_ir::{cast::Cast, ConstValue, DebruijnIndex, Mutability, Safety, Scalar, TypeFlags};
 use hir_def::{
     body::Body,
-    builtin_type::BuiltinType,
     data::{ConstData, StaticData},
     expr::{BindingAnnotation, ExprId, PatId},
     lang_item::LangItemTarget,
@@ -68,12 +67,6 @@ pub(crate) fn infer_query(db: &dyn HirDatabase, def: DefWithBodyId) -> Arc<Infer
         DefWithBodyId::ConstId(c) => ctx.collect_const(&db.const_data(c)),
         DefWithBodyId::FunctionId(f) => ctx.collect_fn(f),
         DefWithBodyId::StaticId(s) => ctx.collect_static(&db.static_data(s)),
-        DefWithBodyId::VariantId(v) => {
-            ctx.return_ty = TyBuilder::builtin(match db.enum_data(v.parent).variant_body_type() {
-                Either::Left(builtin) => BuiltinType::Int(builtin),
-                Either::Right(builtin) => BuiltinType::Uint(builtin),
-            });
-        }
     }
 
     ctx.infer_body();
@@ -339,7 +332,7 @@ pub struct InferenceResult {
     /// unresolved or missing subpatterns or subpatterns of mismatched types.
     pub type_of_pat: ArenaMap<PatId, Ty>,
     type_mismatches: FxHashMap<ExprOrPatId, TypeMismatch>,
-    /// Interned common types to return references to.
+    /// Interned Unknown to return references to.
     standard_types: InternedStandardTypes,
     /// Stores the types which were implicitly dereferenced in pattern binding modes.
     pub pat_adjustments: FxHashMap<PatId, Vec<Ty>>,
@@ -419,8 +412,6 @@ pub(crate) struct InferenceContext<'a> {
     /// closures, but currently this is the only field that will change there,
     /// so it doesn't make sense.
     return_ty: Ty,
-    /// The resume type and the yield type, respectively, of the generator being inferred.
-    resume_yield_tys: Option<(Ty, Ty)>,
     diverges: Diverges,
     breakables: Vec<BreakableContext>,
 }
@@ -485,7 +476,6 @@ impl<'a> InferenceContext<'a> {
             table: unify::InferenceTable::new(db, trait_env.clone()),
             trait_env,
             return_ty: TyKind::Error.intern(Interner), // set in collect_fn_signature
-            resume_yield_tys: None,
             db,
             owner,
             body,
@@ -883,12 +873,6 @@ impl<'a> InferenceContext<'a> {
     fn resolve_into_iter_item(&self) -> Option<TypeAliasId> {
         let path = path![core::iter::IntoIterator];
         let trait_ = self.resolver.resolve_known_trait(self.db.upcast(), &path)?;
-        self.db.trait_data(trait_).associated_type_by_name(&name![IntoIter])
-    }
-
-    fn resolve_iterator_item(&self) -> Option<TypeAliasId> {
-        let path = path![core::iter::Iterator];
-        let trait_ = self.resolver.resolve_known_trait(self.db.upcast(), &path)?;
         self.db.trait_data(trait_).associated_type_by_name(&name![Item])
     }
 
diff --git a/crates/hir-ty/src/infer/closure.rs b/crates/hir-ty/src/infer/closure.rs
index 094e460dbf..3ead929098 100644
--- a/crates/hir-ty/src/infer/closure.rs
+++ b/crates/hir-ty/src/infer/closure.rs
@@ -12,7 +12,6 @@ use crate::{
 use super::{Expectation, InferenceContext};
 
 impl InferenceContext<'_> {
-    // This function handles both closures and generators.
     pub(super) fn deduce_closure_type_from_expectations(
         &mut self,
         closure_expr: ExprId,
@@ -28,11 +27,6 @@ impl InferenceContext<'_> {
         // Deduction from where-clauses in scope, as well as fn-pointer coercion are handled here.
         let _ = self.coerce(Some(closure_expr), closure_ty, &expected_ty);
 
-        // Generators are not Fn* so return early.
-        if matches!(closure_ty.kind(Interner), TyKind::Generator(..)) {
-            return;
-        }
-
         // Deduction based on the expected `dyn Fn` is done separately.
         if let TyKind::Dyn(dyn_ty) = expected_ty.kind(Interner) {
             if let Some(sig) = self.deduce_sig_from_dyn_ty(dyn_ty) {
diff --git a/crates/hir-ty/src/infer/expr.rs b/crates/hir-ty/src/infer/expr.rs
index 2643baf8a3..2d04a864a2 100644
--- a/crates/hir-ty/src/infer/expr.rs
+++ b/crates/hir-ty/src/infer/expr.rs
@@ -10,10 +10,7 @@ use chalk_ir::{
     cast::Cast, fold::Shift, DebruijnIndex, GenericArgData, Mutability, TyVariableKind,
 };
 use hir_def::{
-    expr::{
-        ArithOp, Array, BinaryOp, ClosureKind, CmpOp, Expr, ExprId, LabelId, Literal, Statement,
-        UnaryOp,
-    },
+    expr::{ArithOp, Array, BinaryOp, CmpOp, Expr, ExprId, LabelId, Literal, Statement, UnaryOp},
     generics::TypeOrConstParamData,
     path::{GenericArg, GenericArgs},
     resolver::resolver_for_expr,
@@ -207,10 +204,8 @@ impl<'a> InferenceContext<'a> {
             }
             &Expr::For { iterable, body, pat, label } => {
                 let iterable_ty = self.infer_expr(iterable, &Expectation::none());
-                let into_iter_ty =
-                    self.resolve_associated_type(iterable_ty, self.resolve_into_iter_item());
                 let pat_ty =
-                    self.resolve_associated_type(into_iter_ty, self.resolve_iterator_item());
+                    self.resolve_associated_type(iterable_ty, self.resolve_into_iter_item());
 
                 self.infer_pat(pat, &pat_ty, BindingMode::default());
                 self.with_breakable_ctx(BreakableKind::Loop, self.err_ty(), label, |this| {
@@ -221,7 +216,7 @@ impl<'a> InferenceContext<'a> {
                 self.diverges = Diverges::Maybe;
                 TyBuilder::unit()
             }
-            Expr::Closure { body, args, ret_type, arg_types, closure_kind } => {
+            Expr::Closure { body, args, ret_type, arg_types } => {
                 assert_eq!(args.len(), arg_types.len());
 
                 let mut sig_tys = Vec::new();
@@ -249,40 +244,20 @@ impl<'a> InferenceContext<'a> {
                     ),
                 })
                 .intern(Interner);
-
-                let (ty, resume_yield_tys) = if matches!(closure_kind, ClosureKind::Generator(_)) {
-                    // FIXME: report error when there are more than 1 parameter.
-                    let resume_ty = match sig_tys.first() {
-                        // When `sig_tys.len() == 1` the first type is the return type, not the
-                        // first parameter type.
-                        Some(ty) if sig_tys.len() > 1 => ty.clone(),
-                        _ => self.result.standard_types.unit.clone(),
-                    };
-                    let yield_ty = self.table.new_type_var();
-
-                    let subst = TyBuilder::subst_for_generator(self.db, self.owner)
-                        .push(resume_ty.clone())
-                        .push(yield_ty.clone())
-                        .push(ret_ty.clone())
-                        .build();
-
-                    let generator_id = self.db.intern_generator((self.owner, tgt_expr)).into();
-                    let generator_ty = TyKind::Generator(generator_id, subst).intern(Interner);
-
-                    (generator_ty, Some((resume_ty, yield_ty)))
-                } else {
-                    let closure_id = self.db.intern_closure((self.owner, tgt_expr)).into();
-                    let closure_ty =
-                        TyKind::Closure(closure_id, Substitution::from1(Interner, sig_ty.clone()))
-                            .intern(Interner);
-
-                    (closure_ty, None)
-                };
+                let closure_id = self.db.intern_closure((self.owner, tgt_expr)).into();
+                let closure_ty =
+                    TyKind::Closure(closure_id, Substitution::from1(Interner, sig_ty.clone()))
+                        .intern(Interner);
 
                 // Eagerly try to relate the closure type with the expected
                 // type, otherwise we often won't have enough information to
                 // infer the body.
-                self.deduce_closure_type_from_expectations(tgt_expr, &ty, &sig_ty, expected);
+                self.deduce_closure_type_from_expectations(
+                    tgt_expr,
+                    &closure_ty,
+                    &sig_ty,
+                    expected,
+                );
 
                 // Now go through the argument patterns
                 for (arg_pat, arg_ty) in args.iter().zip(sig_tys) {
@@ -291,8 +266,6 @@ impl<'a> InferenceContext<'a> {
 
                 let prev_diverges = mem::replace(&mut self.diverges, Diverges::Maybe);
                 let prev_ret_ty = mem::replace(&mut self.return_ty, ret_ty.clone());
-                let prev_resume_yield_tys =
-                    mem::replace(&mut self.resume_yield_tys, resume_yield_tys);
 
                 self.with_breakable_ctx(BreakableKind::Border, self.err_ty(), None, |this| {
                     this.infer_expr_coerce(*body, &Expectation::has_type(ret_ty));
@@ -300,9 +273,8 @@ impl<'a> InferenceContext<'a> {
 
                 self.diverges = prev_diverges;
                 self.return_ty = prev_ret_ty;
-                self.resume_yield_tys = prev_resume_yield_tys;
 
-                ty
+                closure_ty
             }
             Expr::Call { callee, args, .. } => {
                 let callee_ty = self.infer_expr(*callee, &Expectation::none());
@@ -451,18 +423,11 @@ impl<'a> InferenceContext<'a> {
                 TyKind::Never.intern(Interner)
             }
             Expr::Yield { expr } => {
-                if let Some((resume_ty, yield_ty)) = self.resume_yield_tys.clone() {
-                    if let Some(expr) = expr {
-                        self.infer_expr_coerce(*expr, &Expectation::has_type(yield_ty));
-                    } else {
-                        let unit = self.result.standard_types.unit.clone();
-                        let _ = self.coerce(Some(tgt_expr), &unit, &yield_ty);
-                    }
-                    resume_ty
-                } else {
-                    // FIXME: report error (yield expr in non-generator)
-                    TyKind::Error.intern(Interner)
+                // FIXME: track yield type for coercion
+                if let Some(expr) = expr {
+                    self.infer_expr(*expr, &Expectation::none());
                 }
+                TyKind::Never.intern(Interner)
             }
             Expr::RecordLit { path, fields, spread, .. } => {
                 let (ty, def_id) = self.resolve_variant(path.as_deref(), false);
diff --git a/crates/hir-ty/src/lower.rs b/crates/hir-ty/src/lower.rs
index e28c87dfa4..532544fee5 100644
--- a/crates/hir-ty/src/lower.rs
+++ b/crates/hir-ty/src/lower.rs
@@ -981,11 +981,10 @@ impl<'a> TyLoweringContext<'a> {
 
     fn lower_dyn_trait(&self, bounds: &[Interned<TypeBound>]) -> Ty {
         let self_ty = TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0)).intern(Interner);
-        // INVARIANT: The principal trait bound, if present, must come first. Others may be in any
-        // order but should be in the same order for the same set but possibly different order of
-        // bounds in the input.
-        // INVARIANT: If this function returns `DynTy`, there should be at least one trait bound.
-        // These invariants are utilized by `TyExt::dyn_trait()` and chalk.
+        // INVARIANT: The principal trait bound must come first. Others may be in any order but
+        // should be in the same order for the same set but possibly different order of bounds in
+        // the input.
+        // This invariant is used by `TyExt::dyn_trait()` and chalk.
         let bounds = self.with_shifted_in(DebruijnIndex::ONE, |ctx| {
             let mut bounds: Vec<_> = bounds
                 .iter()
@@ -1036,12 +1035,6 @@ impl<'a> TyLoweringContext<'a> {
                 return None;
             }
 
-            if bounds.first().and_then(|b| b.trait_id()).is_none() {
-                // When there's no trait bound, that's an error. This happens when the trait refs
-                // are unresolved.
-                return None;
-            }
-
             // As multiple occurrences of the same auto traits *are* permitted, we dedulicate the
             // bounds. We shouldn't have repeated elements besides auto traits at this point.
             bounds.dedup();
@@ -1053,8 +1046,7 @@ impl<'a> TyLoweringContext<'a> {
             let bounds = crate::make_single_type_binders(bounds);
             TyKind::Dyn(DynTy { bounds, lifetime: static_lifetime() }).intern(Interner)
         } else {
-            // FIXME: report error
-            // (additional non-auto traits, associated type rebound, or no resolved trait)
+            // FIXME: report error (additional non-auto traits or associated type rebound)
             TyKind::Error.intern(Interner)
         }
     }
diff --git a/crates/hir-ty/src/mapping.rs b/crates/hir-ty/src/mapping.rs
index f80fb39c1f..d765fee0e1 100644
--- a/crates/hir-ty/src/mapping.rs
+++ b/crates/hir-ty/src/mapping.rs
@@ -103,18 +103,6 @@ impl From<crate::db::InternedClosureId> for chalk_ir::ClosureId<Interner> {
     }
 }
 
-impl From<chalk_ir::GeneratorId<Interner>> for crate::db::InternedGeneratorId {
-    fn from(id: chalk_ir::GeneratorId<Interner>) -> Self {
-        Self::from_intern_id(id.0)
-    }
-}
-
-impl From<crate::db::InternedGeneratorId> for chalk_ir::GeneratorId<Interner> {
-    fn from(id: crate::db::InternedGeneratorId) -> Self {
-        chalk_ir::GeneratorId(id.as_intern_id())
-    }
-}
-
 pub fn to_foreign_def_id(id: TypeAliasId) -> ForeignDefId {
     chalk_ir::ForeignDefId(salsa::InternKey::as_intern_id(&id))
 }
diff --git a/crates/hir-ty/src/method_resolution.rs b/crates/hir-ty/src/method_resolution.rs
index 41fcef73d9..dbf2750032 100644
--- a/crates/hir-ty/src/method_resolution.rs
+++ b/crates/hir-ty/src/method_resolution.rs
@@ -989,18 +989,17 @@ fn iterate_inherent_methods(
             )?;
         }
         TyKind::Dyn(_) => {
-            if let Some(principal_trait) = self_ty.dyn_trait() {
-                let traits = all_super_traits(db.upcast(), principal_trait);
-                iterate_inherent_trait_methods(
-                    self_ty,
-                    table,
-                    name,
-                    receiver_ty,
-                    receiver_adjustments.clone(),
-                    callback,
-                    traits.into_iter(),
-                )?;
-            }
+            let principal_trait = self_ty.dyn_trait().unwrap();
+            let traits = all_super_traits(db.upcast(), principal_trait);
+            iterate_inherent_trait_methods(
+                self_ty,
+                table,
+                name,
+                receiver_ty,
+                receiver_adjustments.clone(),
+                callback,
+                traits.into_iter(),
+            )?;
         }
         _ => {}
     }
diff --git a/crates/hir/src/diagnostics.rs b/crates/hir/src/diagnostics.rs
index c5dc60f1ec..5edc16d8bc 100644
--- a/crates/hir/src/diagnostics.rs
+++ b/crates/hir/src/diagnostics.rs
@@ -1,7 +1,7 @@
 //! Re-export diagnostics such that clients of `hir` don't have to depend on
 //! low-level crates.
 //!
-//! This probably isn't the best way to do this -- ideally, diagnostics should
+//! This probably isn't the best way to do this -- ideally, diagnistics should
 //! be expressed in terms of hir types themselves.
 use base_db::CrateId;
 use cfg::{CfgExpr, CfgOptions};
diff --git a/crates/hir/src/display.rs b/crates/hir/src/display.rs
index 0e29c52ade..27b2f445d7 100644
--- a/crates/hir/src/display.rs
+++ b/crates/hir/src/display.rs
@@ -492,6 +492,9 @@ impl HirDisplay for TypeAlias {
         write_visibility(self.module(f.db).id, self.visibility(f.db), f)?;
         let data = f.db.type_alias_data(self.id);
         write!(f, "type {}", data.name)?;
+        let def_id = GenericDefId::TypeAliasId(self.id);
+        write_generic_params(def_id, f)?;
+        write_where_clause(def_id, f)?;
         if !data.bounds.is_empty() {
             f.write_str(": ")?;
             f.write_joined(&data.bounds, " + ")?;
diff --git a/crates/hir/src/from_id.rs b/crates/hir/src/from_id.rs
index f825a72c0f..9c7558d191 100644
--- a/crates/hir/src/from_id.rs
+++ b/crates/hir/src/from_id.rs
@@ -140,7 +140,6 @@ impl From<DefWithBody> for DefWithBodyId {
             DefWithBody::Function(it) => DefWithBodyId::FunctionId(it.id),
             DefWithBody::Static(it) => DefWithBodyId::StaticId(it.id),
             DefWithBody::Const(it) => DefWithBodyId::ConstId(it.id),
-            DefWithBody::Variant(it) => DefWithBodyId::VariantId(it.into()),
         }
     }
 }
@@ -151,7 +150,6 @@ impl From<DefWithBodyId> for DefWithBody {
             DefWithBodyId::FunctionId(it) => DefWithBody::Function(it.into()),
             DefWithBodyId::StaticId(it) => DefWithBody::Static(it.into()),
             DefWithBodyId::ConstId(it) => DefWithBody::Const(it.into()),
-            DefWithBodyId::VariantId(it) => DefWithBody::Variant(it.into()),
         }
     }
 }
@@ -174,7 +172,9 @@ impl From<GenericDef> for GenericDefId {
             GenericDef::Trait(it) => GenericDefId::TraitId(it.id),
             GenericDef::TypeAlias(it) => GenericDefId::TypeAliasId(it.id),
             GenericDef::Impl(it) => GenericDefId::ImplId(it.id),
-            GenericDef::Variant(it) => GenericDefId::EnumVariantId(it.into()),
+            GenericDef::Variant(it) => {
+                GenericDefId::EnumVariantId(EnumVariantId { parent: it.parent.id, local_id: it.id })
+            }
             GenericDef::Const(it) => GenericDefId::ConstId(it.id),
         }
     }
@@ -188,7 +188,9 @@ impl From<GenericDefId> for GenericDef {
             GenericDefId::TraitId(it) => GenericDef::Trait(it.into()),
             GenericDefId::TypeAliasId(it) => GenericDef::TypeAlias(it.into()),
             GenericDefId::ImplId(it) => GenericDef::Impl(it.into()),
-            GenericDefId::EnumVariantId(it) => GenericDef::Variant(it.into()),
+            GenericDefId::EnumVariantId(it) => {
+                GenericDef::Variant(Variant { parent: it.parent.into(), id: it.local_id })
+            }
             GenericDefId::ConstId(it) => GenericDef::Const(it.into()),
         }
     }
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs
index d1c8fa59ae..d2717c5665 100644
--- a/crates/hir/src/lib.rs
+++ b/crates/hir/src/lib.rs
@@ -39,7 +39,7 @@ use arrayvec::ArrayVec;
 use base_db::{CrateDisplayName, CrateId, CrateOrigin, Edition, FileId, ProcMacroKind};
 use either::Either;
 use hir_def::{
-    adt::{ReprData, VariantData},
+    adt::{ReprKind, VariantData},
     body::{BodyDiagnostic, SyntheticSyntax},
     expr::{BindingAnnotation, LabelId, Pat, PatId},
     generics::{TypeOrConstParamData, TypeParamProvenance},
@@ -50,7 +50,7 @@ use hir_def::{
     resolver::{HasResolver, Resolver},
     src::HasSource as _,
     AdtId, AssocItemId, AssocItemLoc, AttrDefId, ConstId, ConstParamId, DefWithBodyId, EnumId,
-    EnumVariantId, FunctionId, GenericDefId, HasModule, ImplId, ItemContainerId, LifetimeParamId,
+    FunctionId, GenericDefId, HasModule, ImplId, ItemContainerId, LifetimeParamId,
     LocalEnumVariantId, LocalFieldId, Lookup, MacroExpander, MacroId, ModuleId, StaticId, StructId,
     TraitId, TypeAliasId, TypeOrConstParamId, TypeParamId, UnionId,
 };
@@ -73,7 +73,7 @@ use once_cell::unsync::Lazy;
 use rustc_hash::FxHashSet;
 use stdx::{impl_from, never};
 use syntax::{
-    ast::{self, Expr, HasAttrs as _, HasDocComments, HasName},
+    ast::{self, HasAttrs as _, HasDocComments, HasName},
     AstNode, AstPtr, SmolStr, SyntaxNodePtr, TextRange, T,
 };
 
@@ -348,10 +348,7 @@ impl ModuleDef {
             ModuleDef::Module(it) => it.id.into(),
             ModuleDef::Const(it) => it.id.into(),
             ModuleDef::Static(it) => it.id.into(),
-            ModuleDef::Variant(it) => {
-                EnumVariantId { parent: it.parent.into(), local_id: it.id }.into()
-            }
-            ModuleDef::BuiltinType(_) | ModuleDef::Macro(_) => return Vec::new(),
+            _ => return Vec::new(),
         };
 
         let module = match self.module(db) {
@@ -380,10 +377,10 @@ impl ModuleDef {
             ModuleDef::Function(it) => Some(it.into()),
             ModuleDef::Const(it) => Some(it.into()),
             ModuleDef::Static(it) => Some(it.into()),
-            ModuleDef::Variant(it) => Some(it.into()),
 
             ModuleDef::Module(_)
             | ModuleDef::Adt(_)
+            | ModuleDef::Variant(_)
             | ModuleDef::Trait(_)
             | ModuleDef::TypeAlias(_)
             | ModuleDef::Macro(_)
@@ -540,30 +537,6 @@ impl Module {
                     }
                     acc.extend(decl.diagnostics(db))
                 }
-                ModuleDef::Adt(adt) => {
-                    match adt {
-                        Adt::Struct(s) => {
-                            for diag in db.struct_data_with_diagnostics(s.id).1.iter() {
-                                emit_def_diagnostic(db, acc, diag);
-                            }
-                        }
-                        Adt::Union(u) => {
-                            for diag in db.union_data_with_diagnostics(u.id).1.iter() {
-                                emit_def_diagnostic(db, acc, diag);
-                            }
-                        }
-                        Adt::Enum(e) => {
-                            for v in e.variants(db) {
-                                acc.extend(ModuleDef::Variant(v).diagnostics(db));
-                            }
-
-                            for diag in db.enum_data_with_diagnostics(e.id).1.iter() {
-                                emit_def_diagnostic(db, acc, diag);
-                            }
-                        }
-                    }
-                    acc.extend(decl.diagnostics(db))
-                }
                 _ => acc.extend(decl.diagnostics(db)),
             }
         }
@@ -901,7 +874,7 @@ impl Struct {
         Type::from_def(db, self.id)
     }
 
-    pub fn repr(self, db: &dyn HirDatabase) -> Option<ReprData> {
+    pub fn repr(self, db: &dyn HirDatabase) -> Option<ReprKind> {
         db.struct_data(self.id).repr.clone()
     }
 
@@ -979,21 +952,6 @@ impl Enum {
     pub fn ty(self, db: &dyn HirDatabase) -> Type {
         Type::from_def(db, self.id)
     }
-
-    /// The type of the enum variant bodies.
-    pub fn variant_body_ty(self, db: &dyn HirDatabase) -> Type {
-        Type::new_for_crate(
-            self.id.lookup(db.upcast()).container.krate(),
-            TyBuilder::builtin(match db.enum_data(self.id).variant_body_type() {
-                Either::Left(builtin) => hir_def::builtin_type::BuiltinType::Int(builtin),
-                Either::Right(builtin) => hir_def::builtin_type::BuiltinType::Uint(builtin),
-            }),
-        )
-    }
-
-    pub fn is_data_carrying(self, db: &dyn HirDatabase) -> bool {
-        self.variants(db).iter().any(|v| !matches!(v.kind(db), StructKind::Unit))
-    }
 }
 
 impl HasVisibility for Enum {
@@ -1002,12 +960,6 @@ impl HasVisibility for Enum {
     }
 }
 
-impl From<&Variant> for DefWithBodyId {
-    fn from(&v: &Variant) -> Self {
-        DefWithBodyId::VariantId(v.into())
-    }
-}
-
 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
 pub struct Variant {
     pub(crate) parent: Enum,
@@ -1042,14 +994,6 @@ impl Variant {
     pub(crate) fn variant_data(self, db: &dyn HirDatabase) -> Arc<VariantData> {
         db.enum_data(self.parent.id).variants[self.id].variant_data.clone()
     }
-
-    pub fn value(self, db: &dyn HirDatabase) -> Option<Expr> {
-        self.source(db)?.value.expr()
-    }
-
-    pub fn eval(self, db: &dyn HirDatabase) -> Result<ComputedExpr, ConstEvalError> {
-        db.const_eval_variant(self.into())
-    }
 }
 
 /// Variants inherit visibility from the parent enum.
@@ -1185,9 +1129,8 @@ pub enum DefWithBody {
     Function(Function),
     Static(Static),
     Const(Const),
-    Variant(Variant),
 }
-impl_from!(Function, Const, Static, Variant for DefWithBody);
+impl_from!(Function, Const, Static for DefWithBody);
 
 impl DefWithBody {
     pub fn module(self, db: &dyn HirDatabase) -> Module {
@@ -1195,7 +1138,6 @@ impl DefWithBody {
             DefWithBody::Const(c) => c.module(db),
             DefWithBody::Function(f) => f.module(db),
             DefWithBody::Static(s) => s.module(db),
-            DefWithBody::Variant(v) => v.module(db),
         }
     }
 
@@ -1204,7 +1146,6 @@ impl DefWithBody {
             DefWithBody::Function(f) => Some(f.name(db)),
             DefWithBody::Static(s) => Some(s.name(db)),
             DefWithBody::Const(c) => c.name(db),
-            DefWithBody::Variant(v) => Some(v.name(db)),
         }
     }
 
@@ -1214,7 +1155,6 @@ impl DefWithBody {
             DefWithBody::Function(it) => it.ret_type(db),
             DefWithBody::Static(it) => it.ty(db),
             DefWithBody::Const(it) => it.ty(db),
-            DefWithBody::Variant(it) => it.parent.variant_body_ty(db),
         }
     }
 
@@ -1223,7 +1163,6 @@ impl DefWithBody {
             DefWithBody::Function(it) => it.id.into(),
             DefWithBody::Static(it) => it.id.into(),
             DefWithBody::Const(it) => it.id.into(),
-            DefWithBody::Variant(it) => it.into(),
         }
     }
 
@@ -1440,7 +1379,6 @@ impl DefWithBody {
             DefWithBody::Function(it) => it.into(),
             DefWithBody::Static(it) => it.into(),
             DefWithBody::Const(it) => it.into(),
-            DefWithBody::Variant(it) => it.into(),
         };
         for diag in hir_ty::diagnostics::incorrect_case(db, krate, def.into()) {
             acc.push(diag.into())
@@ -3002,7 +2940,7 @@ impl Type {
 
         let adt = adt_id.into();
         match adt {
-            Adt::Struct(s) => matches!(s.repr(db), Some(ReprData { packed: true, .. })),
+            Adt::Struct(s) => matches!(s.repr(db), Some(ReprKind::Packed)),
             _ => false,
         }
     }
diff --git a/crates/hir/src/semantics/source_to_def.rs b/crates/hir/src/semantics/source_to_def.rs
index fa45e3c12e..ba9a1cfb6b 100644
--- a/crates/hir/src/semantics/source_to_def.rs
+++ b/crates/hir/src/semantics/source_to_def.rs
@@ -115,7 +115,7 @@ pub(super) struct SourceToDefCtx<'a, 'b> {
 }
 
 impl SourceToDefCtx<'_, '_> {
-    pub(super) fn file_to_def(&self, file: FileId) -> SmallVec<[ModuleId; 1]> {
+    pub(super) fn file_to_def(&mut self, file: FileId) -> SmallVec<[ModuleId; 1]> {
         let _p = profile::span("SourceBinder::to_module_def");
         let mut mods = SmallVec::new();
         for &crate_id in self.db.relevant_crates(file).iter() {
@@ -130,7 +130,7 @@ impl SourceToDefCtx<'_, '_> {
         mods
     }
 
-    pub(super) fn module_to_def(&self, src: InFile<ast::Module>) -> Option<ModuleId> {
+    pub(super) fn module_to_def(&mut self, src: InFile<ast::Module>) -> Option<ModuleId> {
         let _p = profile::span("module_to_def");
         let parent_declaration = src
             .syntax()
@@ -151,7 +151,7 @@ impl SourceToDefCtx<'_, '_> {
         Some(def_map.module_id(child_id))
     }
 
-    pub(super) fn source_file_to_def(&self, src: InFile<ast::SourceFile>) -> Option<ModuleId> {
+    pub(super) fn source_file_to_def(&mut self, src: InFile<ast::SourceFile>) -> Option<ModuleId> {
         let _p = profile::span("source_file_to_def");
         let file_id = src.file_id.original_file(self.db.upcast());
         self.file_to_def(file_id).get(0).copied()
@@ -384,7 +384,7 @@ impl SourceToDefCtx<'_, '_> {
         } else {
             let it = ast::Variant::cast(container.value)?;
             let def = self.enum_variant_to_def(InFile::new(container.file_id, it))?;
-            DefWithBodyId::from(def).into()
+            VariantId::from(def).into()
         };
         Some(cont)
     }
diff --git a/crates/hir/src/symbols.rs b/crates/hir/src/symbols.rs
index fd78decda4..616a406c72 100644
--- a/crates/hir/src/symbols.rs
+++ b/crates/hir/src/symbols.rs
@@ -244,10 +244,6 @@ impl<'a> SymbolCollector<'a> {
             DefWithBodyId::ConstId(id) => Some(
                 id.lookup(self.db.upcast()).source(self.db.upcast()).value.name()?.text().into(),
             ),
-            DefWithBodyId::VariantId(id) => Some({
-                let db = self.db.upcast();
-                id.parent.lookup(db).source(db).value.name()?.text().into()
-            }),
         }
     }
 
diff --git a/crates/ide-assists/src/handlers/unwrap_tuple.rs b/crates/ide-assists/src/handlers/unwrap_tuple.rs
deleted file mode 100644
index 25c58d086e..0000000000
--- a/crates/ide-assists/src/handlers/unwrap_tuple.rs
+++ /dev/null
@@ -1,159 +0,0 @@
-use syntax::{
-    ast::{self, edit::AstNodeEdit},
-    AstNode, T,
-};
-
-use crate::{AssistContext, AssistId, AssistKind, Assists};
-
-// Assist: unwrap_tuple
-//
-// Unwrap the tuple to different variables.
-//
-// ```
-// # //- minicore: result
-// fn main() {
-//     $0let (foo, bar) = ("Foo", "Bar");
-// }
-// ```
-// ->
-// ```
-// fn main() {
-//     let foo = "Foo";
-//     let bar = "Bar";
-// }
-// ```
-pub(crate) fn unwrap_tuple(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> {
-    let let_kw = ctx.find_token_syntax_at_offset(T![let])?;
-    let let_stmt = let_kw.parent().and_then(ast::LetStmt::cast)?;
-    let indent_level = let_stmt.indent_level().0 as usize;
-    let pat = let_stmt.pat()?;
-    let ty = let_stmt.ty();
-    let init = let_stmt.initializer()?;
-
-    // This only applies for tuple patterns, types, and initializers.
-    let tuple_pat = match pat {
-        ast::Pat::TuplePat(pat) => pat,
-        _ => return None,
-    };
-    let tuple_ty = ty.and_then(|it| match it {
-        ast::Type::TupleType(ty) => Some(ty),
-        _ => None,
-    });
-    let tuple_init = match init {
-        ast::Expr::TupleExpr(expr) => expr,
-        _ => return None,
-    };
-
-    if tuple_pat.fields().count() != tuple_init.fields().count() {
-        return None;
-    }
-    if let Some(tys) = &tuple_ty {
-        if tuple_pat.fields().count() != tys.fields().count() {
-            return None;
-        }
-    }
-
-    let parent = let_kw.parent()?;
-
-    acc.add(
-        AssistId("unwrap_tuple", AssistKind::RefactorRewrite),
-        "Unwrap tuple",
-        let_kw.text_range(),
-        |edit| {
-            let indents = "    ".repeat(indent_level);
-
-            // If there is an ascribed type, insert that type for each declaration,
-            // otherwise, omit that type.
-            if let Some(tys) = tuple_ty {
-                let mut zipped_decls = String::new();
-                for (pat, ty, expr) in
-                    itertools::izip!(tuple_pat.fields(), tys.fields(), tuple_init.fields())
-                {
-                    zipped_decls.push_str(&format!("{}let {pat}: {ty} = {expr};\n", indents))
-                }
-                edit.replace(parent.text_range(), zipped_decls.trim());
-            } else {
-                let mut zipped_decls = String::new();
-                for (pat, expr) in itertools::izip!(tuple_pat.fields(), tuple_init.fields()) {
-                    zipped_decls.push_str(&format!("{}let {pat} = {expr};\n", indents));
-                }
-                edit.replace(parent.text_range(), zipped_decls.trim());
-            }
-        },
-    )
-}
-
-#[cfg(test)]
-mod tests {
-    use crate::tests::check_assist;
-
-    use super::*;
-
-    #[test]
-    fn unwrap_tuples() {
-        check_assist(
-            unwrap_tuple,
-            r#"
-fn main() {
-    $0let (foo, bar) = ("Foo", "Bar");
-}
-"#,
-            r#"
-fn main() {
-    let foo = "Foo";
-    let bar = "Bar";
-}
-"#,
-        );
-
-        check_assist(
-            unwrap_tuple,
-            r#"
-fn main() {
-    $0let (foo, bar, baz) = ("Foo", "Bar", "Baz");
-}
-"#,
-            r#"
-fn main() {
-    let foo = "Foo";
-    let bar = "Bar";
-    let baz = "Baz";
-}
-"#,
-        );
-    }
-
-    #[test]
-    fn unwrap_tuple_with_types() {
-        check_assist(
-            unwrap_tuple,
-            r#"
-fn main() {
-    $0let (foo, bar): (u8, i32) = (5, 10);
-}
-"#,
-            r#"
-fn main() {
-    let foo: u8 = 5;
-    let bar: i32 = 10;
-}
-"#,
-        );
-
-        check_assist(
-            unwrap_tuple,
-            r#"
-fn main() {
-    $0let (foo, bar, baz): (u8, i32, f64) = (5, 10, 17.5);
-}
-"#,
-            r#"
-fn main() {
-    let foo: u8 = 5;
-    let bar: i32 = 10;
-    let baz: f64 = 17.5;
-}
-"#,
-        );
-    }
-}
diff --git a/crates/ide-assists/src/lib.rs b/crates/ide-assists/src/lib.rs
index 82bcc3dfa5..812d22efbd 100644
--- a/crates/ide-assists/src/lib.rs
+++ b/crates/ide-assists/src/lib.rs
@@ -189,7 +189,6 @@ mod handlers {
     mod replace_turbofish_with_explicit_type;
     mod split_import;
     mod unmerge_match_arm;
-    mod unwrap_tuple;
     mod sort_items;
     mod toggle_ignore;
     mod unmerge_use;
@@ -292,7 +291,6 @@ mod handlers {
             unnecessary_async::unnecessary_async,
             unwrap_block::unwrap_block,
             unwrap_result_return_type::unwrap_result_return_type,
-            unwrap_tuple::unwrap_tuple,
             wrap_return_type_in_result::wrap_return_type_in_result,
             // These are manually sorted for better priorities. By default,
             // priority is determined by the size of the target range (smaller
diff --git a/crates/ide-db/src/search.rs b/crates/ide-db/src/search.rs
index 82b85f2fa5..7cabdb55e8 100644
--- a/crates/ide-db/src/search.rs
+++ b/crates/ide-db/src/search.rs
@@ -239,7 +239,6 @@ impl Definition {
                 DefWithBody::Function(f) => f.source(db).map(|src| src.syntax().cloned()),
                 DefWithBody::Const(c) => c.source(db).map(|src| src.syntax().cloned()),
                 DefWithBody::Static(s) => s.source(db).map(|src| src.syntax().cloned()),
-                DefWithBody::Variant(v) => v.source(db).map(|src| src.syntax().cloned()),
             };
             return match def {
                 Some(def) => SearchScope::file_range(def.as_ref().original_file_range(db)),
diff --git a/crates/ide-diagnostics/src/handlers/inactive_code.rs b/crates/ide-diagnostics/src/handlers/inactive_code.rs
index f558b7256a..04918891b2 100644
--- a/crates/ide-diagnostics/src/handlers/inactive_code.rs
+++ b/crates/ide-diagnostics/src/handlers/inactive_code.rs
@@ -137,37 +137,6 @@ trait Bar {
 
     #[cfg_attr(not(never), inline, cfg(no))] fn h() {}
   //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ weak: code is inactive due to #[cfg] directives: no is disabled
-"#,
-        );
-    }
-
-    #[test]
-    fn inactive_fields_and_variants() {
-        check(
-            r#"
-enum Foo {
-  #[cfg(a)] Bar,
-//^^^^^^^^^^^^^ weak: code is inactive due to #[cfg] directives: a is disabled
-  Baz {
-    #[cfg(a)] baz: String,
-  //^^^^^^^^^^^^^^^^^^^^^ weak: code is inactive due to #[cfg] directives: a is disabled
-  },
-  Qux(#[cfg(a)] String),
-    //^^^^^^^^^^^^^^^^ weak: code is inactive due to #[cfg] directives: a is disabled
-}
-
-struct Baz {
-  #[cfg(a)] baz: String,
-//^^^^^^^^^^^^^^^^^^^^^ weak: code is inactive due to #[cfg] directives: a is disabled
-}
-
-struct Qux(#[cfg(a)] String);
-         //^^^^^^^^^^^^^^^^ weak: code is inactive due to #[cfg] directives: a is disabled
-
-union FooBar {
-  #[cfg(a)] baz: u32,
-//^^^^^^^^^^^^^^^^^^ weak: code is inactive due to #[cfg] directives: a is disabled
-}
 "#,
         );
     }
diff --git a/crates/ide/src/hover/render.rs b/crates/ide/src/hover/render.rs
index d109c07691..c5c50d88dd 100644
--- a/crates/ide/src/hover/render.rs
+++ b/crates/ide/src/hover/render.rs
@@ -346,16 +346,7 @@ pub(super) fn definition(
         Definition::Module(it) => label_and_docs(db, it),
         Definition::Function(it) => label_and_docs(db, it),
         Definition::Adt(it) => label_and_docs(db, it),
-        Definition::Variant(it) => label_value_and_docs(db, it, |&it| {
-            if !it.parent_enum(db).is_data_carrying(db) {
-                match it.eval(db) {
-                    Ok(x) => Some(format!("{}", x)),
-                    Err(_) => it.value(db).map(|x| format!("{:?}", x)),
-                }
-            } else {
-                None
-            }
-        }),
+        Definition::Variant(it) => label_and_docs(db, it),
         Definition::Const(it) => label_value_and_docs(db, it, |it| {
             let body = it.eval(db);
             match body {
diff --git a/crates/ide/src/inlay_hints.rs b/crates/ide/src/inlay_hints.rs
index 34d8bf67a3..93fcd7cad7 100644
--- a/crates/ide/src/inlay_hints.rs
+++ b/crates/ide/src/inlay_hints.rs
@@ -176,6 +176,12 @@ impl fmt::Debug for InlayHintLabelPart {
 // * elided lifetimes
 // * compiler inserted reborrows
 //
+// |===
+// | Editor  | Action Name
+//
+// | VS Code | **rust-analyzer: Toggle inlay hints*
+// |===
+//
 // image::https://user-images.githubusercontent.com/48062697/113020660-b5f98b80-917a-11eb-8d70-3be3fd558cdd.png[]
 pub(crate) fn inlay_hints(
     db: &RootDatabase,
@@ -2024,14 +2030,7 @@ impl<T> Vec<T> {
 }
 
 impl<T> IntoIterator for Vec<T> {
-    type Item = T;
-    type IntoIter = IntoIter<T>;
-}
-
-struct IntoIter<T> {}
-
-impl<T> Iterator for IntoIter<T> {
-    type Item = T;
+    type Item=T;
 }
 
 fn main() {
diff --git a/crates/ide/src/lib.rs b/crates/ide/src/lib.rs
index 7820b67142..c1ef25b592 100644
--- a/crates/ide/src/lib.rs
+++ b/crates/ide/src/lib.rs
@@ -236,7 +236,7 @@ impl Analysis {
             Env::default(),
             Ok(Vec::new()),
             false,
-            CrateOrigin::CratesIo { repo: None, name: None },
+            CrateOrigin::CratesIo { repo: None },
         );
         change.change_file(file_id, Some(Arc::new(text)));
         change.set_crate_graph(crate_graph);
diff --git a/crates/ide/src/moniker.rs b/crates/ide/src/moniker.rs
index 852a8fd837..600a526300 100644
--- a/crates/ide/src/moniker.rs
+++ b/crates/ide/src/moniker.rs
@@ -253,14 +253,10 @@ pub(crate) fn def_to_moniker(
         },
         kind: if krate == from_crate { MonikerKind::Export } else { MonikerKind::Import },
         package_information: {
-            let (name, repo, version) = match krate.origin(db) {
-                CrateOrigin::CratesIo { repo, name } => (
-                    name.unwrap_or(krate.display_name(db)?.canonical_name().to_string()),
-                    repo?,
-                    krate.version(db)?,
-                ),
+            let name = krate.display_name(db)?.to_string();
+            let (repo, version) = match krate.origin(db) {
+                CrateOrigin::CratesIo { repo } => (repo?, krate.version(db)?),
                 CrateOrigin::Lang(lang) => (
-                    krate.display_name(db)?.canonical_name().to_string(),
                     "https://github.com/rust-lang/rust/".to_string(),
                     match lang {
                         LangCrateOrigin::Other => {
diff --git a/crates/ide/src/syntax_highlighting/highlight.rs b/crates/ide/src/syntax_highlighting/highlight.rs
index e7d0a8be7f..9395e914c4 100644
--- a/crates/ide/src/syntax_highlighting/highlight.rs
+++ b/crates/ide/src/syntax_highlighting/highlight.rs
@@ -87,9 +87,9 @@ fn punctuation(
     let parent = token.parent();
     let parent_kind = parent.as_ref().map_or(EOF, SyntaxNode::kind);
     match (kind, parent_kind) {
-        (T![?], TRY_EXPR) => HlTag::Operator(HlOperator::Other) | HlMod::ControlFlow,
+        (T![?], _) => HlTag::Operator(HlOperator::Other) | HlMod::ControlFlow,
         (T![&], BIN_EXPR) => HlOperator::Bitwise.into(),
-        (T![&], REF_EXPR) => {
+        (T![&], _) => {
             let h = HlTag::Operator(HlOperator::Other).into();
             let is_unsafe = parent
                 .and_then(ast::RefExpr::cast)
@@ -100,9 +100,7 @@ fn punctuation(
                 h
             }
         }
-        (T![::] | T![->] | T![=>] | T![..] | T![..=] | T![=] | T![@] | T![.], _) => {
-            HlOperator::Other.into()
-        }
+        (T![::] | T![->] | T![=>] | T![..] | T![=] | T![@] | T![.], _) => HlOperator::Other.into(),
         (T![!], MACRO_CALL | MACRO_RULES) => HlPunct::MacroBang.into(),
         (T![!], NEVER_TYPE) => HlTag::BuiltinType.into(),
         (T![!], PREFIX_EXPR) => HlOperator::Logical.into(),
@@ -131,7 +129,7 @@ fn punctuation(
         (T![+=] | T![-=] | T![*=] | T![/=] | T![%=], BIN_EXPR) => {
             Highlight::from(HlOperator::Arithmetic) | HlMod::Mutable
         }
-        (T![|] | T![&] | T![^] | T![>>] | T![<<], BIN_EXPR) => HlOperator::Bitwise.into(),
+        (T![|] | T![&] | T![!] | T![^] | T![>>] | T![<<], BIN_EXPR) => HlOperator::Bitwise.into(),
         (T![|=] | T![&=] | T![^=] | T![>>=] | T![<<=], BIN_EXPR) => {
             Highlight::from(HlOperator::Bitwise) | HlMod::Mutable
         }
@@ -139,6 +137,7 @@ fn punctuation(
         (T![>] | T![<] | T![==] | T![>=] | T![<=] | T![!=], BIN_EXPR) => {
             HlOperator::Comparison.into()
         }
+        (_, PREFIX_EXPR | BIN_EXPR | RANGE_EXPR | RANGE_PAT | REST_PAT) => HlOperator::Other.into(),
         (_, ATTR) => HlTag::AttributeBracket.into(),
         (kind, _) => match kind {
             T!['['] | T![']'] => HlPunct::Bracket,
diff --git a/crates/proc-macro-srv/src/abis/abi_sysroot/mod.rs b/crates/proc-macro-srv/src/abis/abi_sysroot/mod.rs
index 243972b049..44712f4191 100644
--- a/crates/proc-macro-srv/src/abis/abi_sysroot/mod.rs
+++ b/crates/proc-macro-srv/src/abis/abi_sysroot/mod.rs
@@ -11,8 +11,6 @@ use proc_macro_api::ProcMacroKind;
 
 use super::PanicMessage;
 
-pub use ra_server::TokenStream;
-
 pub(crate) struct Abi {
     exported_macros: Vec<proc_macro::bridge::client::ProcMacro>,
 }
diff --git a/crates/proc-macro-srv/src/abis/mod.rs b/crates/proc-macro-srv/src/abis/mod.rs
index 2f854bc159..f7d3a30919 100644
--- a/crates/proc-macro-srv/src/abis/mod.rs
+++ b/crates/proc-macro-srv/src/abis/mod.rs
@@ -32,8 +32,8 @@ mod abi_sysroot;
 include!(concat!(env!("OUT_DIR"), "/rustc_version.rs"));
 
 // Used by `test/utils.rs`
-#[cfg(all(test, feature = "sysroot-abi"))]
-pub(crate) use abi_sysroot::TokenStream as TestTokenStream;
+#[cfg(test)]
+pub(crate) use abi_1_63::TokenStream as TestTokenStream;
 
 use super::dylib::LoadProcMacroDylibError;
 pub(crate) use abi_1_58::Abi as Abi_1_58;
@@ -144,10 +144,3 @@ impl Abi {
         }
     }
 }
-
-#[test]
-fn test_version_check() {
-    let path = paths::AbsPathBuf::assert(crate::proc_macro_test_dylib_path());
-    let info = proc_macro_api::read_dylib_info(&path).unwrap();
-    assert!(info.version.1 >= 50);
-}
diff --git a/crates/proc-macro-srv/src/lib.rs b/crates/proc-macro-srv/src/lib.rs
index 72a2dfe72d..3679bfc43c 100644
--- a/crates/proc-macro-srv/src/lib.rs
+++ b/crates/proc-macro-srv/src/lib.rs
@@ -20,8 +20,6 @@
 mod dylib;
 mod abis;
 
-pub mod cli;
-
 use std::{
     collections::{hash_map::Entry, HashMap},
     env,
@@ -151,10 +149,7 @@ impl EnvSnapshot {
     }
 }
 
-#[cfg(all(feature = "sysroot-abi", test))]
-mod tests;
+pub mod cli;
 
 #[cfg(test)]
-pub fn proc_macro_test_dylib_path() -> std::path::PathBuf {
-    proc_macro_test::PROC_MACRO_TEST_LOCATION.into()
-}
+mod tests;
diff --git a/crates/project-model/src/build_scripts.rs b/crates/project-model/src/build_scripts.rs
index 32db42f1db..837ea01619 100644
--- a/crates/project-model/src/build_scripts.rs
+++ b/crates/project-model/src/build_scripts.rs
@@ -15,7 +15,7 @@ use rustc_hash::FxHashMap;
 use semver::Version;
 use serde::Deserialize;
 
-use crate::{cfg_flag::CfgFlag, CargoConfig, CargoFeatures, CargoWorkspace, Package};
+use crate::{cfg_flag::CfgFlag, CargoConfig, CargoWorkspace, Package};
 
 #[derive(Debug, Default, Clone, PartialEq, Eq)]
 pub struct WorkspaceBuildScripts {
@@ -49,6 +49,7 @@ impl WorkspaceBuildScripts {
 
         let mut cmd = Command::new(toolchain::cargo());
         cmd.envs(&config.extra_env);
+
         cmd.args(&["check", "--quiet", "--workspace", "--message-format=json"]);
 
         // --all-targets includes tests, benches and examples in addition to the
@@ -60,18 +61,15 @@ impl WorkspaceBuildScripts {
             cmd.args(&["--target", target]);
         }
 
-        match &config.features {
-            CargoFeatures::All => {
-                cmd.arg("--all-features");
+        if config.all_features {
+            cmd.arg("--all-features");
+        } else {
+            if config.no_default_features {
+                cmd.arg("--no-default-features");
             }
-            CargoFeatures::Selected { features, no_default_features } => {
-                if *no_default_features {
-                    cmd.arg("--no-default-features");
-                }
-                if !features.is_empty() {
-                    cmd.arg("--features");
-                    cmd.arg(features.join(" "));
-                }
+            if !config.features.is_empty() {
+                cmd.arg("--features");
+                cmd.arg(config.features.join(" "));
             }
         }
 
diff --git a/crates/project-model/src/cargo_workspace.rs b/crates/project-model/src/cargo_workspace.rs
index bd2bbadea2..736d80041b 100644
--- a/crates/project-model/src/cargo_workspace.rs
+++ b/crates/project-model/src/cargo_workspace.rs
@@ -71,41 +71,35 @@ impl Default for UnsetTestCrates {
     }
 }
 
-#[derive(Clone, Debug, PartialEq, Eq)]
-pub enum CargoFeatures {
-    All,
-    Selected {
-        /// List of features to activate.
-        features: Vec<String>,
-        /// Do not activate the `default` feature.
-        no_default_features: bool,
-    },
-}
-
-impl Default for CargoFeatures {
-    fn default() -> Self {
-        CargoFeatures::Selected { features: vec![], no_default_features: false }
-    }
-}
-
 #[derive(Default, Clone, Debug, PartialEq, Eq)]
 pub struct CargoConfig {
+    /// Do not activate the `default` feature.
+    pub no_default_features: bool,
+
+    /// Activate all available features
+    pub all_features: bool,
+
     /// List of features to activate.
-    pub features: CargoFeatures,
+    /// This will be ignored if `cargo_all_features` is true.
+    pub features: Vec<String>,
+
     /// rustc target
     pub target: Option<String>,
+
     /// Don't load sysroot crates (`std`, `core` & friends). Might be useful
     /// when debugging isolated issues.
     pub no_sysroot: bool,
+
     /// rustc private crate source
     pub rustc_source: Option<RustcSource>,
+
     /// crates to disable `#[cfg(test)]` on
     pub unset_test_crates: UnsetTestCrates,
-    /// Invoke `cargo check` through the RUSTC_WRAPPER.
+
     pub wrap_rustc_in_build_scripts: bool,
-    /// The command to run instead of `cargo check` for building build scripts.
+
     pub run_build_script_command: Option<Vec<String>>,
-    /// Extra env vars to set when invoking the cargo command
+
     pub extra_env: FxHashMap<String, String>,
 }
 
@@ -149,7 +143,7 @@ pub struct PackageData {
     pub targets: Vec<Target>,
     /// Does this package come from the local filesystem (and is editable)?
     pub is_local: bool,
-    /// Whether this package is a member of the workspace
+    // Whether this package is a member of the workspace
     pub is_member: bool,
     /// List of packages this package depends on
     pub dependencies: Vec<PackageDependency>,
@@ -255,8 +249,8 @@ impl TargetKind {
     }
 }
 
-// Deserialize helper for the cargo metadata
 #[derive(Deserialize, Default)]
+// Deserialise helper for the cargo metadata
 struct PackageMetadata {
     #[serde(rename = "rust-analyzer")]
     rust_analyzer: Option<RustAnalyzerPackageMetaData>,
@@ -272,25 +266,22 @@ impl CargoWorkspace {
         let target = config
             .target
             .clone()
-            .or_else(|| cargo_config_build_target(cargo_toml, &config.extra_env))
-            .or_else(|| rustc_discover_host_triple(cargo_toml, &config.extra_env));
+            .or_else(|| cargo_config_build_target(cargo_toml, config))
+            .or_else(|| rustc_discover_host_triple(cargo_toml, config));
 
         let mut meta = MetadataCommand::new();
         meta.cargo_path(toolchain::cargo());
         meta.manifest_path(cargo_toml.to_path_buf());
-        match &config.features {
-            CargoFeatures::All => {
-                meta.features(CargoOpt::AllFeatures);
+        if config.all_features {
+            meta.features(CargoOpt::AllFeatures);
+        } else {
+            if config.no_default_features {
+                // FIXME: `NoDefaultFeatures` is mutual exclusive with `SomeFeatures`
+                // https://github.com/oli-obk/cargo_metadata/issues/79
+                meta.features(CargoOpt::NoDefaultFeatures);
             }
-            CargoFeatures::Selected { features, no_default_features } => {
-                if *no_default_features {
-                    // FIXME: `NoDefaultFeatures` is mutual exclusive with `SomeFeatures`
-                    // https://github.com/oli-obk/cargo_metadata/issues/79
-                    meta.features(CargoOpt::NoDefaultFeatures);
-                }
-                if !features.is_empty() {
-                    meta.features(CargoOpt::SomeFeatures(features.clone()));
-                }
+            if !config.features.is_empty() {
+                meta.features(CargoOpt::SomeFeatures(config.features.clone()));
             }
         }
         meta.current_dir(current_dir.as_os_str());
@@ -304,9 +295,12 @@ impl CargoWorkspace {
         // unclear whether cargo itself supports it.
         progress("metadata".to_string());
 
-        (|| -> Result<cargo_metadata::Metadata, cargo_metadata::Error> {
-            let mut command = meta.cargo_command();
-            command.envs(&config.extra_env);
+        fn exec_with_env(
+            command: &cargo_metadata::MetadataCommand,
+            extra_env: &FxHashMap<String, String>,
+        ) -> Result<cargo_metadata::Metadata, cargo_metadata::Error> {
+            let mut command = command.cargo_command();
+            command.envs(extra_env);
             let output = command.output()?;
             if !output.status.success() {
                 return Err(cargo_metadata::Error::CargoMetadata {
@@ -318,8 +312,12 @@ impl CargoWorkspace {
                 .find(|line| line.starts_with('{'))
                 .ok_or(cargo_metadata::Error::NoJson)?;
             cargo_metadata::MetadataCommand::parse(stdout)
-        })()
-        .with_context(|| format!("Failed to run `{:?}`", meta.cargo_command()))
+        }
+
+        let meta = exec_with_env(&meta, &config.extra_env)
+            .with_context(|| format!("Failed to run `{:?}`", meta.cargo_command()))?;
+
+        Ok(meta)
     }
 
     pub fn new(mut meta: cargo_metadata::Metadata) -> CargoWorkspace {
@@ -388,14 +386,32 @@ impl CargoWorkspace {
         }
         let resolve = meta.resolve.expect("metadata executed with deps");
         for mut node in resolve.nodes {
-            let &source = pkg_by_id.get(&node.id).unwrap();
+            let source = match pkg_by_id.get(&node.id) {
+                Some(&src) => src,
+                // FIXME: replace this and a similar branch below with `.unwrap`, once
+                // https://github.com/rust-lang/cargo/issues/7841
+                // is fixed and hits stable (around 1.43-is probably?).
+                None => {
+                    tracing::error!("Node id do not match in cargo metadata, ignoring {}", node.id);
+                    continue;
+                }
+            };
             node.deps.sort_by(|a, b| a.pkg.cmp(&b.pkg));
-            let dependencies = node
+            for (dep_node, kind) in node
                 .deps
                 .iter()
-                .flat_map(|dep| DepKind::iter(&dep.dep_kinds).map(move |kind| (dep, kind)));
-            for (dep_node, kind) in dependencies {
-                let &pkg = pkg_by_id.get(&dep_node.pkg).unwrap();
+                .flat_map(|dep| DepKind::iter(&dep.dep_kinds).map(move |kind| (dep, kind)))
+            {
+                let pkg = match pkg_by_id.get(&dep_node.pkg) {
+                    Some(&pkg) => pkg,
+                    None => {
+                        tracing::error!(
+                            "Dep node id do not match in cargo metadata, ignoring {}",
+                            dep_node.pkg
+                        );
+                        continue;
+                    }
+                };
                 let dep = PackageDependency { name: dep_node.name.clone(), pkg, kind };
                 packages[source].dependencies.push(dep);
             }
@@ -440,7 +456,10 @@ impl CargoWorkspace {
                     found = true
                 }
                 self[pkg].dependencies.iter().find_map(|dep| {
-                    (&self[dep.pkg].manifest == manifest_path).then(|| self[pkg].manifest.clone())
+                    if &self[dep.pkg].manifest == manifest_path {
+                        return Some(self[pkg].manifest.clone());
+                    }
+                    None
                 })
             })
             .collect::<Vec<ManifestPath>>();
@@ -466,12 +485,9 @@ impl CargoWorkspace {
     }
 }
 
-fn rustc_discover_host_triple(
-    cargo_toml: &ManifestPath,
-    extra_env: &FxHashMap<String, String>,
-) -> Option<String> {
+fn rustc_discover_host_triple(cargo_toml: &ManifestPath, config: &CargoConfig) -> Option<String> {
     let mut rustc = Command::new(toolchain::rustc());
-    rustc.envs(extra_env);
+    rustc.envs(&config.extra_env);
     rustc.current_dir(cargo_toml.parent()).arg("-vV");
     tracing::debug!("Discovering host platform by {:?}", rustc);
     match utf8_stdout(rustc) {
@@ -493,12 +509,9 @@ fn rustc_discover_host_triple(
     }
 }
 
-fn cargo_config_build_target(
-    cargo_toml: &ManifestPath,
-    extra_env: &FxHashMap<String, String>,
-) -> Option<String> {
+fn cargo_config_build_target(cargo_toml: &ManifestPath, config: &CargoConfig) -> Option<String> {
     let mut cargo_config = Command::new(toolchain::cargo());
-    cargo_config.envs(extra_env);
+    cargo_config.envs(&config.extra_env);
     cargo_config
         .current_dir(cargo_toml.parent())
         .args(&["-Z", "unstable-options", "config", "get", "build.target"])
diff --git a/crates/project-model/src/lib.rs b/crates/project-model/src/lib.rs
index ce78ce8569..b81b7432f6 100644
--- a/crates/project-model/src/lib.rs
+++ b/crates/project-model/src/lib.rs
@@ -42,8 +42,8 @@ use rustc_hash::FxHashSet;
 pub use crate::{
     build_scripts::WorkspaceBuildScripts,
     cargo_workspace::{
-        CargoConfig, CargoFeatures, CargoWorkspace, Package, PackageData, PackageDependency,
-        RustcSource, Target, TargetData, TargetKind, UnsetTestCrates,
+        CargoConfig, CargoWorkspace, Package, PackageData, PackageDependency, RustcSource, Target,
+        TargetData, TargetKind, UnsetTestCrates,
     },
     manifest_path::ManifestPath,
     project_json::{ProjectJson, ProjectJsonData},
diff --git a/crates/project-model/src/project_json.rs b/crates/project-model/src/project_json.rs
index 5133a14d53..63d1d0ace9 100644
--- a/crates/project-model/src/project_json.rs
+++ b/crates/project-model/src/project_json.rs
@@ -110,17 +110,14 @@ impl ProjectJson {
                 .collect::<Vec<_>>(),
         }
     }
-
     /// Returns the number of crates in the project.
     pub fn n_crates(&self) -> usize {
         self.crates.len()
     }
-
     /// Returns an iterator over the crates in the project.
     pub fn crates(&self) -> impl Iterator<Item = (CrateId, &Crate)> + '_ {
         self.crates.iter().enumerate().map(|(idx, krate)| (CrateId(idx as u32), krate))
     }
-
     /// Returns the path to the project's root folder.
     pub fn path(&self) -> &AbsPath {
         &self.project_root
diff --git a/crates/project-model/src/rustc_cfg.rs b/crates/project-model/src/rustc_cfg.rs
index 3231361836..486cb143b8 100644
--- a/crates/project-model/src/rustc_cfg.rs
+++ b/crates/project-model/src/rustc_cfg.rs
@@ -3,14 +3,13 @@
 use std::process::Command;
 
 use anyhow::Result;
-use rustc_hash::FxHashMap;
 
-use crate::{cfg_flag::CfgFlag, utf8_stdout, ManifestPath};
+use crate::{cfg_flag::CfgFlag, utf8_stdout, CargoConfig, ManifestPath};
 
 pub(crate) fn get(
     cargo_toml: Option<&ManifestPath>,
     target: Option<&str>,
-    extra_env: &FxHashMap<String, String>,
+    config: &CargoConfig,
 ) -> Vec<CfgFlag> {
     let _p = profile::span("rustc_cfg::get");
     let mut res = Vec::with_capacity(6 * 2 + 1);
@@ -23,7 +22,7 @@ pub(crate) fn get(
         }
     }
 
-    match get_rust_cfgs(cargo_toml, target, extra_env) {
+    match get_rust_cfgs(cargo_toml, target, config) {
         Ok(rustc_cfgs) => {
             tracing::debug!(
                 "rustc cfgs found: {:?}",
@@ -43,11 +42,11 @@ pub(crate) fn get(
 fn get_rust_cfgs(
     cargo_toml: Option<&ManifestPath>,
     target: Option<&str>,
-    extra_env: &FxHashMap<String, String>,
+    config: &CargoConfig,
 ) -> Result<String> {
     if let Some(cargo_toml) = cargo_toml {
         let mut cargo_config = Command::new(toolchain::cargo());
-        cargo_config.envs(extra_env);
+        cargo_config.envs(&config.extra_env);
         cargo_config
             .current_dir(cargo_toml.parent())
             .args(&["-Z", "unstable-options", "rustc", "--print", "cfg"])
@@ -62,7 +61,7 @@ fn get_rust_cfgs(
     }
     // using unstable cargo features failed, fall back to using plain rustc
     let mut cmd = Command::new(toolchain::rustc());
-    cmd.envs(extra_env);
+    cmd.envs(&config.extra_env);
     cmd.args(&["--print", "cfg", "-O"]);
     if let Some(target) = target {
         cmd.args(&["--target", target]);
diff --git a/crates/project-model/src/sysroot.rs b/crates/project-model/src/sysroot.rs
index f0d76aa922..3282719fef 100644
--- a/crates/project-model/src/sysroot.rs
+++ b/crates/project-model/src/sysroot.rs
@@ -9,9 +9,8 @@ use std::{env, fs, iter, ops, path::PathBuf, process::Command};
 use anyhow::{format_err, Result};
 use la_arena::{Arena, Idx};
 use paths::{AbsPath, AbsPathBuf};
-use rustc_hash::FxHashMap;
 
-use crate::{utf8_stdout, ManifestPath};
+use crate::{utf8_stdout, CargoConfig, ManifestPath};
 
 #[derive(Debug, Clone, Eq, PartialEq)]
 pub struct Sysroot {
@@ -68,21 +67,18 @@ impl Sysroot {
         self.crates.iter().map(|(id, _data)| id)
     }
 
-    pub fn discover(dir: &AbsPath, extra_env: &FxHashMap<String, String>) -> Result<Sysroot> {
+    pub fn discover(dir: &AbsPath, config: &CargoConfig) -> Result<Sysroot> {
         tracing::debug!("Discovering sysroot for {}", dir.display());
-        let sysroot_dir = discover_sysroot_dir(dir, extra_env)?;
-        let sysroot_src_dir = discover_sysroot_src_dir(&sysroot_dir, dir, extra_env)?;
+        let sysroot_dir = discover_sysroot_dir(dir, config)?;
+        let sysroot_src_dir = discover_sysroot_src_dir(&sysroot_dir, dir, config)?;
         let res = Sysroot::load(sysroot_dir, sysroot_src_dir)?;
         Ok(res)
     }
 
-    pub fn discover_rustc(
-        cargo_toml: &ManifestPath,
-        extra_env: &FxHashMap<String, String>,
-    ) -> Option<ManifestPath> {
+    pub fn discover_rustc(cargo_toml: &ManifestPath, config: &CargoConfig) -> Option<ManifestPath> {
         tracing::debug!("Discovering rustc source for {}", cargo_toml.display());
         let current_dir = cargo_toml.parent();
-        discover_sysroot_dir(current_dir, extra_env)
+        discover_sysroot_dir(current_dir, config)
             .ok()
             .and_then(|sysroot_dir| get_rustc_src(&sysroot_dir))
     }
@@ -150,12 +146,9 @@ impl Sysroot {
     }
 }
 
-fn discover_sysroot_dir(
-    current_dir: &AbsPath,
-    extra_env: &FxHashMap<String, String>,
-) -> Result<AbsPathBuf> {
+fn discover_sysroot_dir(current_dir: &AbsPath, config: &CargoConfig) -> Result<AbsPathBuf> {
     let mut rustc = Command::new(toolchain::rustc());
-    rustc.envs(extra_env);
+    rustc.envs(&config.extra_env);
     rustc.current_dir(current_dir).args(&["--print", "sysroot"]);
     tracing::debug!("Discovering sysroot by {:?}", rustc);
     let stdout = utf8_stdout(rustc)?;
@@ -165,7 +158,7 @@ fn discover_sysroot_dir(
 fn discover_sysroot_src_dir(
     sysroot_path: &AbsPathBuf,
     current_dir: &AbsPath,
-    extra_env: &FxHashMap<String, String>,
+    config: &CargoConfig,
 ) -> Result<AbsPathBuf> {
     if let Ok(path) = env::var("RUST_SRC_PATH") {
         let path = AbsPathBuf::try_from(path.as_str())
@@ -181,7 +174,7 @@ fn discover_sysroot_src_dir(
     get_rust_src(sysroot_path)
         .or_else(|| {
             let mut rustup = Command::new(toolchain::rustup());
-            rustup.envs(extra_env);
+            rustup.envs(&config.extra_env);
             rustup.current_dir(current_dir).args(&["component", "add", "rust-src"]);
             utf8_stdout(rustup).ok()?;
             get_rust_src(sysroot_path)
diff --git a/crates/project-model/src/workspace.rs b/crates/project-model/src/workspace.rs
index d9d3cab456..bc4ab45dae 100644
--- a/crates/project-model/src/workspace.rs
+++ b/crates/project-model/src/workspace.rs
@@ -21,8 +21,8 @@ use crate::{
     cfg_flag::CfgFlag,
     rustc_cfg,
     sysroot::SysrootCrate,
-    utf8_stdout, CargoConfig, CargoWorkspace, ManifestPath, Package, ProjectJson, ProjectManifest,
-    Sysroot, TargetKind, WorkspaceBuildScripts,
+    utf8_stdout, CargoConfig, CargoWorkspace, ManifestPath, ProjectJson, ProjectManifest, Sysroot,
+    TargetKind, WorkspaceBuildScripts,
 };
 
 /// A set of cfg-overrides per crate.
@@ -156,11 +156,7 @@ impl ProjectWorkspace {
                 })?;
                 let project_location = project_json.parent().to_path_buf();
                 let project_json = ProjectJson::new(&project_location, data);
-                ProjectWorkspace::load_inline(
-                    project_json,
-                    config.target.as_deref(),
-                    &config.extra_env,
-                )?
+                ProjectWorkspace::load_inline(project_json, config.target.as_deref(), config)?
             }
             ProjectManifest::CargoToml(cargo_toml) => {
                 let cargo_version = utf8_stdout({
@@ -191,21 +187,17 @@ impl ProjectWorkspace {
                 let sysroot = if config.no_sysroot {
                     None
                 } else {
-                    Some(Sysroot::discover(cargo_toml.parent(), &config.extra_env).with_context(
-                        || {
-                            format!(
+                    Some(Sysroot::discover(cargo_toml.parent(), config).with_context(|| {
+                        format!(
                             "Failed to find sysroot for Cargo.toml file {}. Is rust-src installed?",
                             cargo_toml.display()
                         )
-                        },
-                    )?)
+                    })?)
                 };
 
                 let rustc_dir = match &config.rustc_source {
                     Some(RustcSource::Path(path)) => ManifestPath::try_from(path.clone()).ok(),
-                    Some(RustcSource::Discover) => {
-                        Sysroot::discover_rustc(&cargo_toml, &config.extra_env)
-                    }
+                    Some(RustcSource::Discover) => Sysroot::discover_rustc(&cargo_toml, config),
                     None => None,
                 };
 
@@ -225,8 +217,7 @@ impl ProjectWorkspace {
                     None => None,
                 };
 
-                let rustc_cfg =
-                    rustc_cfg::get(Some(&cargo_toml), config.target.as_deref(), &config.extra_env);
+                let rustc_cfg = rustc_cfg::get(Some(&cargo_toml), config.target.as_deref(), config);
 
                 let cfg_overrides = config.cfg_overrides();
                 ProjectWorkspace::Cargo {
@@ -247,7 +238,7 @@ impl ProjectWorkspace {
     pub fn load_inline(
         project_json: ProjectJson,
         target: Option<&str>,
-        extra_env: &FxHashMap<String, String>,
+        config: &CargoConfig,
     ) -> Result<ProjectWorkspace> {
         let sysroot = match (project_json.sysroot.clone(), project_json.sysroot_src.clone()) {
             (Some(sysroot), Some(sysroot_src)) => Some(Sysroot::load(sysroot, sysroot_src)?),
@@ -269,7 +260,7 @@ impl ProjectWorkspace {
             (None, None) => None,
         };
 
-        let rustc_cfg = rustc_cfg::get(None, target, extra_env);
+        let rustc_cfg = rustc_cfg::get(None, target, config);
         Ok(ProjectWorkspace::Json { project: project_json, sysroot, rustc_cfg })
     }
 
@@ -279,9 +270,9 @@ impl ProjectWorkspace {
                 .first()
                 .and_then(|it| it.parent())
                 .ok_or_else(|| format_err!("No detached files to load"))?,
-            &Default::default(),
+            &CargoConfig::default(),
         )?;
-        let rustc_cfg = rustc_cfg::get(None, None, &Default::default());
+        let rustc_cfg = rustc_cfg::get(None, None, &CargoConfig::default());
         Ok(ProjectWorkspace::DetachedFiles { files: detached_files, sysroot, rustc_cfg })
     }
 
@@ -315,13 +306,6 @@ impl ProjectWorkspace {
     /// The return type contains the path and whether or not
     /// the root is a member of the current workspace
     pub fn to_roots(&self) -> Vec<PackageRoot> {
-        let mk_sysroot = |sysroot: Option<&Sysroot>| {
-            sysroot.map(|sysroot| PackageRoot {
-                is_local: false,
-                include: vec![sysroot.src_root().to_path_buf()],
-                exclude: Vec::new(),
-            })
-        };
         match self {
             ProjectWorkspace::Json { project, sysroot, rustc_cfg: _ } => project
                 .crates()
@@ -332,7 +316,13 @@ impl ProjectWorkspace {
                 })
                 .collect::<FxHashSet<_>>()
                 .into_iter()
-                .chain(mk_sysroot(sysroot.as_ref()))
+                .chain(sysroot.as_ref().into_iter().flat_map(|sysroot| {
+                    sysroot.crates().map(move |krate| PackageRoot {
+                        is_local: false,
+                        include: vec![sysroot[krate].root.parent().to_path_buf()],
+                        exclude: Vec::new(),
+                    })
+                }))
                 .collect::<Vec<_>>(),
             ProjectWorkspace::Cargo {
                 cargo,
@@ -381,7 +371,11 @@ impl ProjectWorkspace {
                         }
                         PackageRoot { is_local, include, exclude }
                     })
-                    .chain(mk_sysroot(sysroot.as_ref()))
+                    .chain(sysroot.iter().map(|sysroot| PackageRoot {
+                        is_local: false,
+                        include: vec![sysroot.src_root().to_path_buf()],
+                        exclude: Vec::new(),
+                    }))
                     .chain(rustc.iter().flat_map(|rustc| {
                         rustc.packages().map(move |krate| PackageRoot {
                             is_local: false,
@@ -398,7 +392,11 @@ impl ProjectWorkspace {
                     include: vec![detached_file.clone()],
                     exclude: Vec::new(),
                 })
-                .chain(mk_sysroot(Some(sysroot)))
+                .chain(sysroot.crates().map(|krate| PackageRoot {
+                    is_local: false,
+                    include: vec![sysroot[krate].root.parent().to_path_buf()],
+                    exclude: Vec::new(),
+                }))
                 .collect(),
         }
     }
@@ -421,7 +419,7 @@ impl ProjectWorkspace {
         &self,
         load_proc_macro: &mut dyn FnMut(&str, &AbsPath) -> ProcMacroLoadResult,
         load: &mut dyn FnMut(&AbsPath) -> Option<FileId>,
-        extra_env: &FxHashMap<String, String>,
+        config: &CargoConfig,
     ) -> CrateGraph {
         let _p = profile::span("ProjectWorkspace::to_crate_graph");
 
@@ -432,7 +430,7 @@ impl ProjectWorkspace {
                 load,
                 project,
                 sysroot,
-                extra_env,
+                config,
             ),
             ProjectWorkspace::Cargo {
                 cargo,
@@ -471,7 +469,7 @@ fn project_json_to_crate_graph(
     load: &mut dyn FnMut(&AbsPath) -> Option<FileId>,
     project: &ProjectJson,
     sysroot: &Option<Sysroot>,
-    extra_env: &FxHashMap<String, String>,
+    config: &CargoConfig,
 ) -> CrateGraph {
     let mut crate_graph = CrateGraph::default();
     let sysroot_deps = sysroot
@@ -499,7 +497,7 @@ fn project_json_to_crate_graph(
             let target_cfgs = match krate.target.as_deref() {
                 Some(target) => cfg_cache
                     .entry(target)
-                    .or_insert_with(|| rustc_cfg::get(None, Some(target), extra_env)),
+                    .or_insert_with(|| rustc_cfg::get(None, Some(target), config)),
                 None => &rustc_cfg,
             };
 
@@ -518,15 +516,9 @@ fn project_json_to_crate_graph(
                     proc_macro,
                     krate.is_proc_macro,
                     if krate.display_name.is_some() {
-                        CrateOrigin::CratesIo {
-                            repo: krate.repository.clone(),
-                            name: krate
-                                .display_name
-                                .clone()
-                                .map(|n| n.canonical_name().to_string()),
-                        }
+                        CrateOrigin::CratesIo { repo: krate.repository.clone() }
                     } else {
-                        CrateOrigin::CratesIo { repo: None, name: None }
+                        CrateOrigin::CratesIo { repo: None }
                     },
                 ),
             )
@@ -638,8 +630,6 @@ fn cargo_to_crate_graph(
                     lib_tgt = Some((crate_id, cargo[tgt].name.clone()));
                     pkg_to_lib_crate.insert(pkg, crate_id);
                 }
-                // Even crates that don't set proc-macro = true are allowed to depend on proc_macro
-                // (just none of the APIs work when called outside of a proc macro).
                 if let Some(proc_macro) = libproc_macro {
                     add_dep_with_prelude(
                         &mut crate_graph,
@@ -655,19 +645,19 @@ fn cargo_to_crate_graph(
         }
 
         // Set deps to the core, std and to the lib target of the current package
-        for &(from, kind) in pkg_crates.get(&pkg).into_iter().flatten() {
+        for (from, kind) in pkg_crates.get(&pkg).into_iter().flatten() {
             // Add sysroot deps first so that a lib target named `core` etc. can overwrite them.
-            public_deps.add(from, &mut crate_graph);
+            public_deps.add(*from, &mut crate_graph);
 
             if let Some((to, name)) = lib_tgt.clone() {
-                if to != from && kind != TargetKind::BuildScript {
+                if to != *from && *kind != TargetKind::BuildScript {
                     // (build script can not depend on its library target)
 
                     // For root projects with dashes in their name,
                     // cargo metadata does not do any normalization,
                     // so we do it ourselves currently
                     let name = CrateName::normalize_dashes(&name);
-                    add_dep(&mut crate_graph, from, name, to);
+                    add_dep(&mut crate_graph, *from, name, to);
                 }
             }
         }
@@ -679,17 +669,17 @@ fn cargo_to_crate_graph(
         for dep in cargo[pkg].dependencies.iter() {
             let name = CrateName::new(&dep.name).unwrap();
             if let Some(&to) = pkg_to_lib_crate.get(&dep.pkg) {
-                for &(from, kind) in pkg_crates.get(&pkg).into_iter().flatten() {
-                    if dep.kind == DepKind::Build && kind != TargetKind::BuildScript {
+                for (from, kind) in pkg_crates.get(&pkg).into_iter().flatten() {
+                    if dep.kind == DepKind::Build && *kind != TargetKind::BuildScript {
                         // Only build scripts may depend on build dependencies.
                         continue;
                     }
-                    if dep.kind != DepKind::Build && kind == TargetKind::BuildScript {
+                    if dep.kind != DepKind::Build && *kind == TargetKind::BuildScript {
                         // Build scripts may only depend on build dependencies.
                         continue;
                     }
 
-                    add_dep(&mut crate_graph, from, name.clone(), to)
+                    add_dep(&mut crate_graph, *from, name.clone(), to)
                 }
             }
         }
@@ -700,9 +690,9 @@ fn cargo_to_crate_graph(
         // and create dependencies on them for the crates which opt-in to that
         if let Some(rustc_workspace) = rustc {
             handle_rustc_crates(
-                &mut crate_graph,
                 rustc_workspace,
                 load,
+                &mut crate_graph,
                 &cfg_options,
                 override_cfg,
                 load_proc_macro,
@@ -746,17 +736,14 @@ fn detached_files_to_crate_graph(
         let detached_file_crate = crate_graph.add_crate_root(
             file_id,
             Edition::CURRENT,
-            display_name.clone(),
+            display_name,
             None,
             cfg_options.clone(),
             cfg_options.clone(),
             Env::default(),
             Ok(Vec::new()),
             false,
-            CrateOrigin::CratesIo {
-                repo: None,
-                name: display_name.map(|n| n.canonical_name().to_string()),
-            },
+            CrateOrigin::CratesIo { repo: None },
         );
 
         public_deps.add(detached_file_crate, &mut crate_graph);
@@ -765,16 +752,16 @@ fn detached_files_to_crate_graph(
 }
 
 fn handle_rustc_crates(
-    crate_graph: &mut CrateGraph,
     rustc_workspace: &CargoWorkspace,
     load: &mut dyn FnMut(&AbsPath) -> Option<FileId>,
+    crate_graph: &mut CrateGraph,
     cfg_options: &CfgOptions,
     override_cfg: &CfgOverrides,
     load_proc_macro: &mut dyn FnMut(&str, &AbsPath) -> ProcMacroLoadResult,
-    pkg_to_lib_crate: &mut FxHashMap<Package, CrateId>,
+    pkg_to_lib_crate: &mut FxHashMap<la_arena::Idx<crate::PackageData>, CrateId>,
     public_deps: &SysrootPublicDeps,
     cargo: &CargoWorkspace,
-    pkg_crates: &FxHashMap<Package, Vec<(CrateId, TargetKind)>>,
+    pkg_crates: &FxHashMap<la_arena::Idx<crate::PackageData>, Vec<(CrateId, TargetKind)>>,
     build_scripts: &WorkspaceBuildScripts,
 ) {
     let mut rustc_pkg_crates = FxHashMap::default();
@@ -788,8 +775,8 @@ fn handle_rustc_crates(
         let mut queue = VecDeque::new();
         queue.push_back(root_pkg);
         while let Some(pkg) = queue.pop_front() {
-            // Don't duplicate packages if they are dependent on a diamond pattern
-            // N.B. if this line is omitted, we try to analyze over 4_800_000 crates
+            // Don't duplicate packages if they are dependended on a diamond pattern
+            // N.B. if this line is omitted, we try to analyse over 4_800_000 crates
             // which is not ideal
             if rustc_pkg_crates.contains_key(&pkg) {
                 continue;
@@ -932,7 +919,7 @@ fn add_target_crate_root(
         env,
         proc_macro,
         is_proc_macro,
-        CrateOrigin::CratesIo { repo: pkg.repository.clone(), name: Some(pkg.name.clone()) },
+        CrateOrigin::CratesIo { repo: pkg.repository.clone() },
     )
 }
 
diff --git a/crates/rust-analyzer/Cargo.toml b/crates/rust-analyzer/Cargo.toml
index 71566d5de6..5392589186 100644
--- a/crates/rust-analyzer/Cargo.toml
+++ b/crates/rust-analyzer/Cargo.toml
@@ -34,7 +34,7 @@ threadpool = "1.8.1"
 rayon = "1.5.3"
 num_cpus = "1.13.1"
 mimalloc = { version = "0.1.29", default-features = false, optional = true }
-lsp-server = { version = "0.7.0", path = "../../lib/lsp-server" }
+lsp-server = { version = "0.6.0", path = "../../lib/lsp-server" }
 tracing = "0.1.35"
 tracing-subscriber = { version = "0.3.14", default-features = false, features = [
     "env-filter",
@@ -87,6 +87,7 @@ jemalloc = ["jemallocator", "profile/jemalloc"]
 force-always-assert = ["always-assert/force"]
 in-rust-tree = [
     "proc-macro-srv/sysroot-abi",
+    "sourcegen/in-rust-tree",
     "ide/in-rust-tree",
     "syntax/in-rust-tree",
 ]
diff --git a/crates/rust-analyzer/src/cargo_target_spec.rs b/crates/rust-analyzer/src/cargo_target_spec.rs
index e1675a030c..1c39e9391a 100644
--- a/crates/rust-analyzer/src/cargo_target_spec.rs
+++ b/crates/rust-analyzer/src/cargo_target_spec.rs
@@ -4,7 +4,7 @@ use std::mem;
 
 use cfg::{CfgAtom, CfgExpr};
 use ide::{FileId, RunnableKind, TestId};
-use project_model::{self, CargoFeatures, ManifestPath, TargetKind};
+use project_model::{self, ManifestPath, TargetKind};
 use vfs::AbsPathBuf;
 
 use crate::{global_state::GlobalStateSnapshot, Result};
@@ -35,41 +35,41 @@ impl CargoTargetSpec {
 
         match kind {
             RunnableKind::Test { test_id, attr } => {
-                args.push("test".to_owned());
+                args.push("test".to_string());
                 extra_args.push(test_id.to_string());
                 if let TestId::Path(_) = test_id {
-                    extra_args.push("--exact".to_owned());
+                    extra_args.push("--exact".to_string());
                 }
-                extra_args.push("--nocapture".to_owned());
+                extra_args.push("--nocapture".to_string());
                 if attr.ignore {
-                    extra_args.push("--ignored".to_owned());
+                    extra_args.push("--ignored".to_string());
                 }
             }
             RunnableKind::TestMod { path } => {
-                args.push("test".to_owned());
-                extra_args.push(path.clone());
-                extra_args.push("--nocapture".to_owned());
+                args.push("test".to_string());
+                extra_args.push(path.to_string());
+                extra_args.push("--nocapture".to_string());
             }
             RunnableKind::Bench { test_id } => {
-                args.push("bench".to_owned());
+                args.push("bench".to_string());
                 extra_args.push(test_id.to_string());
                 if let TestId::Path(_) = test_id {
-                    extra_args.push("--exact".to_owned());
+                    extra_args.push("--exact".to_string());
                 }
-                extra_args.push("--nocapture".to_owned());
+                extra_args.push("--nocapture".to_string());
             }
             RunnableKind::DocTest { test_id } => {
-                args.push("test".to_owned());
-                args.push("--doc".to_owned());
+                args.push("test".to_string());
+                args.push("--doc".to_string());
                 extra_args.push(test_id.to_string());
-                extra_args.push("--nocapture".to_owned());
+                extra_args.push("--nocapture".to_string());
             }
             RunnableKind::Bin => {
                 let subcommand = match spec {
                     Some(CargoTargetSpec { target_kind: TargetKind::Test, .. }) => "test",
                     _ => "run",
                 };
-                args.push(subcommand.to_owned());
+                args.push(subcommand.to_string());
             }
         }
 
@@ -82,35 +82,29 @@ impl CargoTargetSpec {
         };
 
         let cargo_config = snap.config.cargo();
+        if cargo_config.all_features {
+            args.push("--all-features".to_string());
 
-        match &cargo_config.features {
-            CargoFeatures::All => {
-                args.push("--all-features".to_owned());
-                for feature in target_required_features {
-                    args.push("--features".to_owned());
-                    args.push(feature);
-                }
+            for feature in target_required_features {
+                args.push("--features".to_string());
+                args.push(feature);
+            }
+        } else {
+            let mut features = Vec::new();
+            if let Some(cfg) = cfg.as_ref() {
+                required_features(cfg, &mut features);
             }
-            CargoFeatures::Selected { features, no_default_features } => {
-                let mut feats = Vec::new();
-                if let Some(cfg) = cfg.as_ref() {
-                    required_features(cfg, &mut feats);
-                }
-
-                feats.extend(features.iter().cloned());
-                feats.extend(target_required_features);
 
-                feats.dedup();
-                for feature in feats {
-                    args.push("--features".to_owned());
-                    args.push(feature);
-                }
+            features.extend(cargo_config.features);
+            features.extend(target_required_features);
 
-                if *no_default_features {
-                    args.push("--no-default-features".to_owned());
-                }
+            features.dedup();
+            for feature in features {
+                args.push("--features".to_string());
+                args.push(feature);
             }
         }
+
         Ok((args, extra_args))
     }
 
@@ -142,7 +136,7 @@ impl CargoTargetSpec {
     }
 
     pub(crate) fn push_to(self, buf: &mut Vec<String>, kind: &RunnableKind) {
-        buf.push("--package".to_owned());
+        buf.push("--package".to_string());
         buf.push(self.package);
 
         // Can't mix --doc with other target flags
@@ -151,23 +145,23 @@ impl CargoTargetSpec {
         }
         match self.target_kind {
             TargetKind::Bin => {
-                buf.push("--bin".to_owned());
+                buf.push("--bin".to_string());
                 buf.push(self.target);
             }
             TargetKind::Test => {
-                buf.push("--test".to_owned());
+                buf.push("--test".to_string());
                 buf.push(self.target);
             }
             TargetKind::Bench => {
-                buf.push("--bench".to_owned());
+                buf.push("--bench".to_string());
                 buf.push(self.target);
             }
             TargetKind::Example => {
-                buf.push("--example".to_owned());
+                buf.push("--example".to_string());
                 buf.push(self.target);
             }
             TargetKind::Lib => {
-                buf.push("--lib".to_owned());
+                buf.push("--lib".to_string());
             }
             TargetKind::Other | TargetKind::BuildScript => (),
         }
diff --git a/crates/rust-analyzer/src/cli/analysis_stats.rs b/crates/rust-analyzer/src/cli/analysis_stats.rs
index 81c393abdb..80128e43fd 100644
--- a/crates/rust-analyzer/src/cli/analysis_stats.rs
+++ b/crates/rust-analyzer/src/cli/analysis_stats.rs
@@ -81,7 +81,7 @@ impl flags::AnalysisStats {
         };
 
         let (host, vfs, _proc_macro) =
-            load_workspace(workspace, &cargo_config.extra_env, &load_cargo_config)?;
+            load_workspace(workspace, &cargo_config, &load_cargo_config)?;
         let db = host.raw_database();
         eprint!("{:<20} {}", "Database loaded:", db_load_sw.elapsed());
         eprint!(" (metadata {}", metadata_time);
diff --git a/crates/rust-analyzer/src/cli/load_cargo.rs b/crates/rust-analyzer/src/cli/load_cargo.rs
index 5dba545b87..88953096e2 100644
--- a/crates/rust-analyzer/src/cli/load_cargo.rs
+++ b/crates/rust-analyzer/src/cli/load_cargo.rs
@@ -6,7 +6,7 @@ use anyhow::Result;
 use crossbeam_channel::{unbounded, Receiver};
 use hir::db::DefDatabase;
 use ide::{AnalysisHost, Change};
-use ide_db::{base_db::CrateGraph, FxHashMap};
+use ide_db::base_db::CrateGraph;
 use proc_macro_api::ProcMacroServer;
 use project_model::{CargoConfig, ProjectManifest, ProjectWorkspace};
 use vfs::{loader::Handle, AbsPath, AbsPathBuf};
@@ -38,7 +38,7 @@ pub fn load_workspace_at(
         workspace.set_build_scripts(build_scripts)
     }
 
-    load_workspace(workspace, &cargo_config.extra_env, load_config)
+    load_workspace(workspace, cargo_config, load_config)
 }
 
 // Note: Since this function is used by external tools that use rust-analyzer as a library
@@ -48,7 +48,7 @@ pub fn load_workspace_at(
 // these tools need access to `ProjectWorkspace`, too, which `load_workspace_at` hides.
 pub fn load_workspace(
     ws: ProjectWorkspace,
-    extra_env: &FxHashMap<String, String>,
+    cargo_config: &CargoConfig,
     load_config: &LoadCargoConfig,
 ) -> Result<(AnalysisHost, vfs::Vfs, Option<ProcMacroServer>)> {
     let (sender, receiver) = unbounded();
@@ -60,26 +60,10 @@ pub fn load_workspace(
     };
 
     let proc_macro_client = if load_config.with_proc_macro {
-        let mut path = AbsPathBuf::assert(std::env::current_exe()?);
-        let mut args = vec!["proc-macro"];
-
-        if let ProjectWorkspace::Cargo { sysroot, .. } | ProjectWorkspace::Json { sysroot, .. } =
-            &ws
-        {
-            if let Some(sysroot) = sysroot.as_ref() {
-                let standalone_server_name =
-                    format!("rust-analyzer-proc-macro-srv{}", std::env::consts::EXE_SUFFIX);
-                let server_path = sysroot.root().join("libexec").join(&standalone_server_name);
-                if std::fs::metadata(&server_path).is_ok() {
-                    path = server_path;
-                    args = vec![];
-                }
-            }
-        }
-
-        ProcMacroServer::spawn(path.clone(), args.clone()).map_err(|e| e.to_string())
+        let path = AbsPathBuf::assert(std::env::current_exe()?);
+        Ok(ProcMacroServer::spawn(path, &["proc-macro"]).unwrap())
     } else {
-        Err("proc macro server disabled".to_owned())
+        Err("proc macro server not started".to_owned())
     };
 
     let crate_graph = ws.to_crate_graph(
@@ -92,7 +76,7 @@ pub fn load_workspace(
             vfs.set_file_contents(path.clone(), contents);
             vfs.file_id(&path)
         },
-        extra_env,
+        cargo_config,
     );
 
     let project_folders = ProjectFolders::new(&[ws], &[]);
diff --git a/crates/rust-analyzer/src/cli/lsif.rs b/crates/rust-analyzer/src/cli/lsif.rs
index 748306ea57..79577bf78c 100644
--- a/crates/rust-analyzer/src/cli/lsif.rs
+++ b/crates/rust-analyzer/src/cli/lsif.rs
@@ -300,7 +300,7 @@ impl flags::Lsif {
         let workspace = ProjectWorkspace::load(manifest, &cargo_config, no_progress)?;
 
         let (host, vfs, _proc_macro) =
-            load_workspace(workspace, &cargo_config.extra_env, &load_cargo_config)?;
+            load_workspace(workspace, &cargo_config, &load_cargo_config)?;
         let db = host.raw_database();
         let analysis = host.analysis();
 
diff --git a/crates/rust-analyzer/src/cli/scip.rs b/crates/rust-analyzer/src/cli/scip.rs
index 2c29b3ee3a..05c16bb39e 100644
--- a/crates/rust-analyzer/src/cli/scip.rs
+++ b/crates/rust-analyzer/src/cli/scip.rs
@@ -40,8 +40,7 @@ impl flags::Scip {
 
         let workspace = ProjectWorkspace::load(manifest, &cargo_config, no_progress)?;
 
-        let (host, vfs, _) =
-            load_workspace(workspace, &cargo_config.extra_env, &load_cargo_config)?;
+        let (host, vfs, _) = load_workspace(workspace, &cargo_config, &load_cargo_config)?;
         let db = host.raw_database();
         let analysis = host.analysis();
 
diff --git a/crates/rust-analyzer/src/config.rs b/crates/rust-analyzer/src/config.rs
index 5d99d2fb11..9ef79e6f38 100644
--- a/crates/rust-analyzer/src/config.rs
+++ b/crates/rust-analyzer/src/config.rs
@@ -22,8 +22,7 @@ use ide_db::{
 use itertools::Itertools;
 use lsp_types::{ClientCapabilities, MarkupKind};
 use project_model::{
-    CargoConfig, CargoFeatures, ProjectJson, ProjectJsonData, ProjectManifest, RustcSource,
-    UnsetTestCrates,
+    CargoConfig, ProjectJson, ProjectJsonData, ProjectManifest, RustcSource, UnsetTestCrates,
 };
 use rustc_hash::{FxHashMap, FxHashSet};
 use serde::{de::DeserializeOwned, Deserialize};
@@ -91,7 +90,7 @@ config_data! {
         /// List of features to activate.
         ///
         /// Set this to `"all"` to pass `--all-features` to cargo.
-        cargo_features: CargoFeaturesDef      = "[]",
+        cargo_features: CargoFeatures      = "[]",
         /// Whether to pass `--no-default-features` to cargo.
         cargo_noDefaultFeatures: bool    = "false",
         /// Internal config for debugging, disables loading of sysroot crates.
@@ -110,13 +109,12 @@ config_data! {
         /// Extra arguments for `cargo check`.
         checkOnSave_extraArgs: Vec<String>               = "[]",
         /// Extra environment variables that will be set when running `cargo check`.
-        /// Extends `#rust-analyzer.cargo.extraEnv#`.
         checkOnSave_extraEnv: FxHashMap<String, String> = "{}",
         /// List of features to activate. Defaults to
         /// `#rust-analyzer.cargo.features#`.
         ///
         /// Set to `"all"` to pass `--all-features` to Cargo.
-        checkOnSave_features: Option<CargoFeaturesDef>      = "null",
+        checkOnSave_features: Option<CargoFeatures>      = "null",
         /// Whether to pass `--no-default-features` to Cargo. Defaults to
         /// `#rust-analyzer.cargo.noDefaultFeatures#`.
         checkOnSave_noDefaultFeatures: Option<bool>      = "null",
@@ -1030,12 +1028,11 @@ impl Config {
         });
 
         CargoConfig {
+            no_default_features: self.data.cargo_noDefaultFeatures,
+            all_features: matches!(self.data.cargo_features, CargoFeatures::All),
             features: match &self.data.cargo_features {
-                CargoFeaturesDef::All => CargoFeatures::All,
-                CargoFeaturesDef::Selected(features) => CargoFeatures::Selected {
-                    features: features.clone(),
-                    no_default_features: self.data.cargo_noDefaultFeatures,
-                },
+                CargoFeatures::All => vec![],
+                CargoFeatures::Listed(it) => it.clone(),
             },
             target: self.data.cargo_target.clone(),
             no_sysroot: self.data.cargo_noSysroot,
@@ -1089,7 +1086,7 @@ impl Config {
                     .unwrap_or(self.data.cargo_noDefaultFeatures),
                 all_features: matches!(
                     self.data.checkOnSave_features.as_ref().unwrap_or(&self.data.cargo_features),
-                    CargoFeaturesDef::All
+                    CargoFeatures::All
                 ),
                 features: match self
                     .data
@@ -1097,8 +1094,8 @@ impl Config {
                     .clone()
                     .unwrap_or_else(|| self.data.cargo_features.clone())
                 {
-                    CargoFeaturesDef::All => vec![],
-                    CargoFeaturesDef::Selected(it) => it,
+                    CargoFeatures::All => vec![],
+                    CargoFeatures::Listed(it) => it,
                 },
                 extra_args: self.data.checkOnSave_extraArgs.clone(),
                 extra_env: self.check_on_save_extra_env(),
@@ -1567,10 +1564,10 @@ enum CallableCompletionDef {
 
 #[derive(Deserialize, Debug, Clone)]
 #[serde(untagged)]
-enum CargoFeaturesDef {
+enum CargoFeatures {
     #[serde(deserialize_with = "de_unit_v::all")]
     All,
-    Selected(Vec<String>),
+    Listed(Vec<String>),
 }
 
 #[derive(Deserialize, Debug, Clone)]
@@ -1915,7 +1912,7 @@ fn field_props(field: &str, ty: &str, doc: &[&str], default: &str) -> serde_json
                 "Only show mutable reborrow hints."
             ]
         },
-        "CargoFeaturesDef" => set! {
+        "CargoFeatures" => set! {
             "anyOf": [
                 {
                     "type": "string",
@@ -1932,7 +1929,7 @@ fn field_props(field: &str, ty: &str, doc: &[&str], default: &str) -> serde_json
                 }
             ],
         },
-        "Option<CargoFeaturesDef>" => set! {
+        "Option<CargoFeatures>" => set! {
             "anyOf": [
                 {
                     "type": "string",
diff --git a/crates/rust-analyzer/src/global_state.rs b/crates/rust-analyzer/src/global_state.rs
index 000ff88e45..92df4d70fd 100644
--- a/crates/rust-analyzer/src/global_state.rs
+++ b/crates/rust-analyzer/src/global_state.rs
@@ -185,48 +185,11 @@ impl GlobalState {
         let (change, changed_files) = {
             let mut change = Change::new();
             let (vfs, line_endings_map) = &mut *self.vfs.write();
-            let mut changed_files = vfs.take_changes();
+            let changed_files = vfs.take_changes();
             if changed_files.is_empty() {
                 return false;
             }
 
-            // important: this needs to be a stable sort, the order between changes is relevant
-            // for the same file ids
-            changed_files.sort_by_key(|file| file.file_id);
-            // We need to fix up the changed events a bit, if we have a create or modify for a file
-            // id that is followed by a delete we actually no longer observe the file text from the
-            // create or modify which may cause problems later on
-            changed_files.dedup_by(|a, b| {
-                use vfs::ChangeKind::*;
-
-                if a.file_id != b.file_id {
-                    return false;
-                }
-
-                match (a.change_kind, b.change_kind) {
-                    // duplicate can be merged
-                    (Create, Create) | (Modify, Modify) | (Delete, Delete) => true,
-                    // just leave the create, modify is irrelevant
-                    (Create, Modify) => {
-                        std::mem::swap(a, b);
-                        true
-                    }
-                    // modify becomes irrelevant if the file is deleted
-                    (Modify, Delete) => true,
-                    // we should fully remove this occurrence,
-                    // but leaving just a delete works as well
-                    (Create, Delete) => true,
-                    // this is equivalent to a modify
-                    (Delete, Create) => {
-                        a.change_kind = Modify;
-                        true
-                    }
-                    // can't really occur
-                    (Modify, Create) => false,
-                    (Delete, Modify) => false,
-                }
-            });
-
             for file in &changed_files {
                 if let Some(path) = vfs.file_path(file.file_id).as_path() {
                     let path = path.to_path_buf();
@@ -354,10 +317,6 @@ impl GlobalState {
         }
     }
 
-    pub(crate) fn is_completed(&self, request: &lsp_server::Request) -> bool {
-        self.req_queue.incoming.is_completed(&request.id)
-    }
-
     fn send(&mut self, message: lsp_server::Message) {
         self.sender.send(message).unwrap()
     }
diff --git a/crates/rust-analyzer/src/main_loop.rs b/crates/rust-analyzer/src/main_loop.rs
index c64d557a11..3cfbc2e4e4 100644
--- a/crates/rust-analyzer/src/main_loop.rs
+++ b/crates/rust-analyzer/src/main_loop.rs
@@ -425,9 +425,7 @@ impl GlobalState {
     fn handle_task(&mut self, prime_caches_progress: &mut Vec<PrimeCachesProgress>, task: Task) {
         match task {
             Task::Response(response) => self.respond(response),
-            // Only retry requests that haven't been cancelled. Otherwise we do unnecessary work.
-            Task::Retry(req) if self.is_completed(&req) => self.on_request(req),
-            Task::Retry(_) => (),
+            Task::Retry(req) => self.on_request(req),
             Task::Diagnostics(diagnostics_per_file) => {
                 for (file_id, diagnostics) in diagnostics_per_file {
                     self.diagnostics.set_native_diagnostics(file_id, diagnostics)
diff --git a/crates/rust-analyzer/src/reload.rs b/crates/rust-analyzer/src/reload.rs
index e7f7972e9a..4cf5de46c4 100644
--- a/crates/rust-analyzer/src/reload.rs
+++ b/crates/rust-analyzer/src/reload.rs
@@ -143,7 +143,7 @@ impl GlobalState {
                             project_model::ProjectWorkspace::load_inline(
                                 it.clone(),
                                 cargo_config.target.as_deref(),
-                                &cargo_config.extra_env,
+                                &cargo_config,
                             )
                         }
                     })
@@ -402,7 +402,7 @@ impl GlobalState {
                 crate_graph.extend(ws.to_crate_graph(
                     &mut load_proc_macro,
                     &mut load,
-                    &self.config.cargo().extra_env,
+                    &self.config.cargo(),
                 ));
             }
             crate_graph
diff --git a/crates/sourcegen/Cargo.toml b/crates/sourcegen/Cargo.toml
index e75867e2d8..a84110d940 100644
--- a/crates/sourcegen/Cargo.toml
+++ b/crates/sourcegen/Cargo.toml
@@ -11,3 +11,6 @@ doctest = false
 
 [dependencies]
 xshell = "0.2.2"
+
+[features]
+in-rust-tree = []
diff --git a/crates/syntax/src/ast/node_ext.rs b/crates/syntax/src/ast/node_ext.rs
index fe82aa9072..bb92c51e9a 100644
--- a/crates/syntax/src/ast/node_ext.rs
+++ b/crates/syntax/src/ast/node_ext.rs
@@ -873,33 +873,3 @@ impl ast::MatchGuard {
         support::child(&self.syntax)
     }
 }
-
-impl From<ast::Item> for ast::AnyHasAttrs {
-    fn from(node: ast::Item) -> Self {
-        Self::new(node)
-    }
-}
-
-impl From<ast::AssocItem> for ast::AnyHasAttrs {
-    fn from(node: ast::AssocItem) -> Self {
-        Self::new(node)
-    }
-}
-
-impl From<ast::Variant> for ast::AnyHasAttrs {
-    fn from(node: ast::Variant) -> Self {
-        Self::new(node)
-    }
-}
-
-impl From<ast::RecordField> for ast::AnyHasAttrs {
-    fn from(node: ast::RecordField) -> Self {
-        Self::new(node)
-    }
-}
-
-impl From<ast::TupleField> for ast::AnyHasAttrs {
-    fn from(node: ast::TupleField) -> Self {
-        Self::new(node)
-    }
-}
diff --git a/docs/dev/guide.md b/docs/dev/guide.md
index c9ff0b6c29..808eb5d10b 100644
--- a/docs/dev/guide.md
+++ b/docs/dev/guide.md
@@ -40,8 +40,8 @@ terms of files and offsets, and **not** in terms of Rust concepts like structs,
 traits, etc. The "typed" API with Rust specific types is slightly lower in the
 stack, we'll talk about it later.
 
-[`AnalysisHost`]: https://github.com/rust-lang/rust-analyzer/blob/guide-2019-01/crates/ra_ide_api/src/lib.rs#L265-L284
-[`Analysis`]: https://github.com/rust-lang/rust-analyzer/blob/guide-2019-01/crates/ra_ide_api/src/lib.rs#L291-L478
+[`AnalysisHost`]: https://github.com/rust-lang/rust-analyzer/blob/guide-2019-01/crates/ide_api/src/lib.rs#L265-L284
+[`Analysis`]: https://github.com/rust-lang/rust-analyzer/blob/guide-2019-01/crates/ide_api/src/lib.rs#L291-L478
 
 The reason for this separation of `Analysis` and `AnalysisHost` is that we want to apply
 changes "uniquely", but we might also want to fork an `Analysis` and send it to
diff --git a/docs/user/generated_config.adoc b/docs/user/generated_config.adoc
index a34f4d5093..996d4c023d 100644
--- a/docs/user/generated_config.adoc
+++ b/docs/user/generated_config.adoc
@@ -103,7 +103,6 @@ Extra arguments for `cargo check`.
 +
 --
 Extra environment variables that will be set when running `cargo check`.
-Extends `#rust-analyzer.cargo.extraEnv#`.
 --
 [[rust-analyzer.checkOnSave.features]]rust-analyzer.checkOnSave.features (default: `null`)::
 +
diff --git a/editors/code/package.json b/editors/code/package.json
index f8eec9f62e..94b41c049b 100644
--- a/editors/code/package.json
+++ b/editors/code/package.json
@@ -515,7 +515,7 @@
                     }
                 },
                 "rust-analyzer.checkOnSave.extraEnv": {
-                    "markdownDescription": "Extra environment variables that will be set when running `cargo check`.\nExtends `#rust-analyzer.cargo.extraEnv#`.",
+                    "markdownDescription": "Extra environment variables that will be set when running `cargo check`.",
                     "default": {},
                     "type": "object"
                 },
diff --git a/lib/lsp-server/Cargo.toml b/lib/lsp-server/Cargo.toml
index b236b156cf..204d120d07 100644
--- a/lib/lsp-server/Cargo.toml
+++ b/lib/lsp-server/Cargo.toml
@@ -1,6 +1,6 @@
 [package]
 name = "lsp-server"
-version = "0.7.0"
+version = "0.6.0"
 description = "Generic LSP server scaffold."
 license = "MIT OR Apache-2.0"
 repository = "https://github.com/rust-lang/rust-analyzer/tree/master/lib/lsp-server"
@@ -8,9 +8,9 @@ edition = "2021"
 
 [dependencies]
 log = "0.4.17"
-serde_json = "1.0.85"
-serde = { version = "1.0.144", features = ["derive"] }
-crossbeam-channel = "0.5.6"
+serde_json = "1.0.81"
+serde = { version = "1.0.137", features = ["derive"] }
+crossbeam-channel = "0.5.5"
 
 [dev-dependencies]
-lsp-types = "0.93.1"
+lsp-types = "0.93.0"
diff --git a/lib/lsp-server/src/msg.rs b/lib/lsp-server/src/msg.rs
index b241561f9c..97e5bd35ce 100644
--- a/lib/lsp-server/src/msg.rs
+++ b/lib/lsp-server/src/msg.rs
@@ -98,7 +98,7 @@ pub struct ResponseError {
 }
 
 #[derive(Clone, Copy, Debug)]
-#[non_exhaustive]
+#[allow(unused)]
 pub enum ErrorCode {
     // Defined by JSON RPC:
     ParseError = -32700,
@@ -135,14 +135,6 @@ pub enum ErrorCode {
     ///
     /// @since 3.17.0
     ServerCancelled = -32802,
-
-    /// A request failed but it was syntactically correct, e.g the
-    /// method name was known and the parameters were valid. The error
-    /// message should contain human readable information about why
-    /// the request failed.
-    ///
-    /// @since 3.17.0
-    RequestFailed = -32803,
 }
 
 #[derive(Debug, Serialize, Deserialize, Clone)]
diff --git a/lib/lsp-server/src/req_queue.rs b/lib/lsp-server/src/req_queue.rs
index e5f19be20b..1f3d447153 100644
--- a/lib/lsp-server/src/req_queue.rs
+++ b/lib/lsp-server/src/req_queue.rs
@@ -35,7 +35,6 @@ impl<I> Incoming<I> {
     pub fn register(&mut self, id: RequestId, data: I) {
         self.pending.insert(id, data);
     }
-
     pub fn cancel(&mut self, id: RequestId) -> Option<Response> {
         let _data = self.complete(id.clone())?;
         let error = ResponseError {
@@ -45,14 +44,9 @@ impl<I> Incoming<I> {
         };
         Some(Response { id, result: None, error: Some(error) })
     }
-
     pub fn complete(&mut self, id: RequestId) -> Option<I> {
         self.pending.remove(&id)
     }
-
-    pub fn is_completed(&self, id: &RequestId) -> bool {
-        !self.pending.contains_key(id)
-    }
 }
 
 impl<O> Outgoing<O> {
@@ -62,7 +56,6 @@ impl<O> Outgoing<O> {
         self.next_id += 1;
         Request::new(id, method, params)
     }
-
     pub fn complete(&mut self, id: RequestId) -> Option<O> {
         self.pending.remove(&id)
     }


Test patch:
diff --git a/crates/hir-ty/src/consteval/tests.rs b/crates/hir-ty/src/consteval/tests.rs
index b76506f6eb..4a052851af 100644
--- a/crates/hir-ty/src/consteval/tests.rs
+++ b/crates/hir-ty/src/consteval/tests.rs
@@ -87,49 +87,6 @@ fn consts() {
     );
 }
 
-#[test]
-fn enums() {
-    check_number(
-        r#"
-    enum E {
-        F1 = 1,
-        F2 = 2 * E::F1 as u8,
-        F3 = 3 * E::F2 as u8,
-    }
-    const GOAL: i32 = E::F3 as u8;
-    "#,
-        6,
-    );
-    check_number(
-        r#"
-    enum E { F1 = 1, F2, }
-    const GOAL: i32 = E::F2 as u8;
-    "#,
-        2,
-    );
-    check_number(
-        r#"
-    enum E { F1, }
-    const GOAL: i32 = E::F1 as u8;
-    "#,
-        0,
-    );
-    let r = eval_goal(
-        r#"
-        enum E { A = 1, }
-        const GOAL: E = E::A;
-        "#,
-    )
-    .unwrap();
-    match r {
-        ComputedExpr::Enum(name, _, Literal::Uint(val, _)) => {
-            assert_eq!(name, "E::A");
-            assert_eq!(val, 1);
-        }
-        x => panic!("Expected enum but found {:?}", x),
-    }
-}
-
 #[test]
 fn const_loop() {
     check_fail(
diff --git a/crates/hir-ty/src/tests.rs b/crates/hir-ty/src/tests.rs
index ebbc541014..d2f13e4351 100644
--- a/crates/hir-ty/src/tests.rs
+++ b/crates/hir-ty/src/tests.rs
@@ -16,7 +16,7 @@ use base_db::{fixture::WithFixture, FileRange, SourceDatabaseExt};
 use expect_test::Expect;
 use hir_def::{
     body::{Body, BodySourceMap, SyntheticSyntax},
-    db::{DefDatabase, InternDatabase},
+    db::DefDatabase,
     expr::{ExprId, PatId},
     item_scope::ItemScope,
     nameres::DefMap,
@@ -135,10 +135,6 @@ fn check_impl(ra_fixture: &str, allow_none: bool, only_types: bool, display_sour
             let loc = it.lookup(&db);
             loc.source(&db).value.syntax().text_range().start()
         }
-        DefWithBodyId::VariantId(it) => {
-            let loc = db.lookup_intern_enum(it.parent);
-            loc.source(&db).value.syntax().text_range().start()
-        }
     });
     let mut unexpected_type_mismatches = String::new();
     for def in defs {
@@ -392,10 +388,6 @@ fn infer_with_mismatches(content: &str, include_mismatches: bool) -> String {
             let loc = it.lookup(&db);
             loc.source(&db).value.syntax().text_range().start()
         }
-        DefWithBodyId::VariantId(it) => {
-            let loc = db.lookup_intern_enum(it.parent);
-            loc.source(&db).value.syntax().text_range().start()
-        }
     });
     for def in defs {
         let (_body, source_map) = db.body_with_source_map(def);
@@ -461,18 +453,6 @@ fn visit_module(
                     let body = db.body(def);
                     visit_body(db, &body, cb);
                 }
-                ModuleDefId::AdtId(hir_def::AdtId::EnumId(it)) => {
-                    db.enum_data(it)
-                        .variants
-                        .iter()
-                        .map(|(id, _)| hir_def::EnumVariantId { parent: it, local_id: id })
-                        .for_each(|it| {
-                            let def = it.into();
-                            cb(def);
-                            let body = db.body(def);
-                            visit_body(db, &body, cb);
-                        });
-                }
                 ModuleDefId::TraitId(it) => {
                     let trait_data = db.trait_data(it);
                     for &(_, item) in trait_data.items.iter() {
diff --git a/crates/hir-ty/src/tests/coercion.rs b/crates/hir-ty/src/tests/coercion.rs
index d301595bcd..bf59fadc2c 100644
--- a/crates/hir-ty/src/tests/coercion.rs
+++ b/crates/hir-ty/src/tests/coercion.rs
@@ -294,24 +294,6 @@ fn foo() {
     );
 }
 
-#[test]
-fn generator_yield_return_coerce() {
-    check_no_mismatches(
-        r#"
-fn test() {
-    let g = || {
-        yield &1u32;
-        yield &&1u32;
-        if true {
-            return &1u32;
-        }
-        &&1u32
-    };
-}
-        "#,
-    );
-}
-
 #[test]
 fn assign_coerce() {
     check_no_mismatches(
diff --git a/crates/hir-ty/src/tests/regression.rs b/crates/hir-ty/src/tests/regression.rs
index 47cc3341e7..23e51a9c16 100644
--- a/crates/hir-ty/src/tests/regression.rs
+++ b/crates/hir-ty/src/tests/regression.rs
@@ -1691,15 +1691,3 @@ fn macrostmts() -> u8 {
     "#,
     );
 }
-
-#[test]
-fn dyn_with_unresolved_trait() {
-    check_types(
-        r#"
-fn foo(a: &dyn DoesNotExist) {
-    a.bar();
-  //^&{unknown}
-}
-        "#,
-    );
-}
diff --git a/crates/hir-ty/src/tests/simple.rs b/crates/hir-ty/src/tests/simple.rs
index 080e2ac1b8..4ea103e5d9 100644
--- a/crates/hir-ty/src/tests/simple.rs
+++ b/crates/hir-ty/src/tests/simple.rs
@@ -1693,16 +1693,16 @@ fn infer_type_param() {
 fn infer_const() {
     check_infer(
         r#"
-struct Foo;
-impl Foo { const ASSOC_CONST: u32 = 0; }
-const GLOBAL_CONST: u32 = 101;
-fn test() {
-    const LOCAL_CONST: u32 = 99;
-    let x = LOCAL_CONST;
-    let z = GLOBAL_CONST;
-    let id = Foo::ASSOC_CONST;
-}
-"#,
+        struct Foo;
+        impl Foo { const ASSOC_CONST: u32 = 0; }
+        const GLOBAL_CONST: u32 = 101;
+        fn test() {
+            const LOCAL_CONST: u32 = 99;
+            let x = LOCAL_CONST;
+            let z = GLOBAL_CONST;
+            let id = Foo::ASSOC_CONST;
+        }
+        "#,
         expect![[r#"
             48..49 '0': u32
             79..82 '101': u32
@@ -1722,17 +1722,17 @@ fn test() {
 fn infer_static() {
     check_infer(
         r#"
-static GLOBAL_STATIC: u32 = 101;
-static mut GLOBAL_STATIC_MUT: u32 = 101;
-fn test() {
-    static LOCAL_STATIC: u32 = 99;
-    static mut LOCAL_STATIC_MUT: u32 = 99;
-    let x = LOCAL_STATIC;
-    let y = LOCAL_STATIC_MUT;
-    let z = GLOBAL_STATIC;
-    let w = GLOBAL_STATIC_MUT;
-}
-"#,
+        static GLOBAL_STATIC: u32 = 101;
+        static mut GLOBAL_STATIC_MUT: u32 = 101;
+        fn test() {
+            static LOCAL_STATIC: u32 = 99;
+            static mut LOCAL_STATIC_MUT: u32 = 99;
+            let x = LOCAL_STATIC;
+            let y = LOCAL_STATIC_MUT;
+            let z = GLOBAL_STATIC;
+            let w = GLOBAL_STATIC_MUT;
+        }
+        "#,
         expect![[r#"
             28..31 '101': u32
             69..72 '101': u32
@@ -1751,41 +1751,6 @@ fn test() {
     );
 }
 
-#[test]
-fn infer_enum_variant() {
-    check_infer(
-        r#"
-enum Foo {
-    A = 15,
-    B = Foo::A as isize + 1
-}
-"#,
-        expect![[r#"
-            19..21 '15': isize
-            31..37 'Foo::A': Foo
-            31..46 'Foo::A as isize': isize
-            31..50 'Foo::A...ze + 1': isize
-            49..50 '1': isize
-        "#]],
-    );
-    check_infer(
-        r#"
-#[repr(u32)]
-enum Foo {
-    A = 15,
-    B = Foo::A as u32 + 1
-}
-"#,
-        expect![[r#"
-            32..34 '15': u32
-            44..50 'Foo::A': Foo
-            44..57 'Foo::A as u32': u32
-            44..61 'Foo::A...32 + 1': u32
-            60..61 '1': u32
-        "#]],
-    );
-}
-
 #[test]
 fn shadowing_primitive() {
     check_types(
@@ -1952,88 +1917,6 @@ fn closure_return_inferred() {
     );
 }
 
-#[test]
-fn generator_types_inferred() {
-    check_infer(
-        r#"
-//- minicore: generator, deref
-use core::ops::{Generator, GeneratorState};
-use core::pin::Pin;
-
-fn f(v: i64) {}
-fn test() {
-    let mut g = |r| {
-        let a = yield 0;
-        let a = yield 1;
-        let a = yield 2;
-        "return value"
-    };
-
-    match Pin::new(&mut g).resume(0usize) {
-        GeneratorState::Yielded(y) => { f(y); }
-        GeneratorState::Complete(r) => {}
-    }
-}
-        "#,
-        expect![[r#"
-            70..71 'v': i64
-            78..80 '{}': ()
-            91..362 '{     ...   } }': ()
-            101..106 'mut g': |usize| yields i64 -> &str
-            109..218 '|r| { ...     }': |usize| yields i64 -> &str
-            110..111 'r': usize
-            113..218 '{     ...     }': &str
-            127..128 'a': usize
-            131..138 'yield 0': usize
-            137..138 '0': i64
-            152..153 'a': usize
-            156..163 'yield 1': usize
-            162..163 '1': i64
-            177..178 'a': usize
-            181..188 'yield 2': usize
-            187..188 '2': i64
-            198..212 '"return value"': &str
-            225..360 'match ...     }': ()
-            231..239 'Pin::new': fn new<&mut |usize| yields i64 -> &str>(&mut |usize| yields i64 -> &str) -> Pin<&mut |usize| yields i64 -> &str>
-            231..247 'Pin::n...mut g)': Pin<&mut |usize| yields i64 -> &str>
-            231..262 'Pin::n...usize)': GeneratorState<i64, &str>
-            240..246 '&mut g': &mut |usize| yields i64 -> &str
-            245..246 'g': |usize| yields i64 -> &str
-            255..261 '0usize': usize
-            273..299 'Genera...ded(y)': GeneratorState<i64, &str>
-            297..298 'y': i64
-            303..312 '{ f(y); }': ()
-            305..306 'f': fn f(i64)
-            305..309 'f(y)': ()
-            307..308 'y': i64
-            321..348 'Genera...ete(r)': GeneratorState<i64, &str>
-            346..347 'r': &str
-            352..354 '{}': ()
-        "#]],
-    );
-}
-
-#[test]
-fn generator_resume_yield_return_unit() {
-    check_no_mismatches(
-        r#"
-//- minicore: generator, deref
-use core::ops::{Generator, GeneratorState};
-use core::pin::Pin;
-fn test() {
-    let mut g = || {
-        let () = yield;
-    };
-
-    match Pin::new(&mut g).resume(()) {
-        GeneratorState::Yielded(()) => {}
-        GeneratorState::Complete(()) => {}
-    }
-}
-        "#,
-    );
-}
-
 #[test]
 fn fn_pointer_return() {
     check_infer(
diff --git a/crates/hir-ty/src/tests/traits.rs b/crates/hir-ty/src/tests/traits.rs
index 555b6972fb..21a8631976 100644
--- a/crates/hir-ty/src/tests/traits.rs
+++ b/crates/hir-ty/src/tests/traits.rs
@@ -279,10 +279,6 @@ fn test() {
 pub mod iter {
     pub trait IntoIterator {
         type Item;
-        type IntoIter: Iterator<Item = Self::Item>;
-    }
-    pub trait Iterator {
-        type Item;
     }
 }
 pub mod prelude {
@@ -301,13 +297,7 @@ pub mod collections {
     }
 
     impl<T> IntoIterator for Vec<T> {
-        type Item = T;
-        type IntoIter = IntoIter<T>;
-    }
-
-    struct IntoIter<T> {}
-    impl<T> Iterator for IntoIter<T> {
-        type Item = T;
+        type Item=T;
     }
 }
 "#,
diff --git a/crates/ide-assists/src/tests.rs b/crates/ide-assists/src/tests.rs
index a3bb66e379..258144bae3 100644
--- a/crates/ide-assists/src/tests.rs
+++ b/crates/ide-assists/src/tests.rs
@@ -96,10 +96,8 @@ fn check_doc_test(assist_id: &str, before: &str, after: &str) {
         });
 
     let actual = {
-        let source_change = assist
-            .source_change
-            .filter(|it| !it.source_file_edits.is_empty() || !it.file_system_edits.is_empty())
-            .expect("Assist did not contain any source changes");
+        let source_change =
+            assist.source_change.expect("Assist did not contain any source changes");
         let mut actual = before;
         if let Some(source_file_edit) = source_change.get_source_edit(file_id) {
             source_file_edit.apply(&mut actual);
@@ -142,10 +140,8 @@ fn check(handler: Handler, before: &str, expected: ExpectedResult<'_>, assist_la
 
     match (assist, expected) {
         (Some(assist), ExpectedResult::After(after)) => {
-            let source_change = assist
-                .source_change
-                .filter(|it| !it.source_file_edits.is_empty() || !it.file_system_edits.is_empty())
-                .expect("Assist did not contain any source changes");
+            let source_change =
+                assist.source_change.expect("Assist did not contain any source changes");
             let skip_header = source_change.source_file_edits.len() == 1
                 && source_change.file_system_edits.len() == 0;
 
diff --git a/crates/ide-assists/src/tests/generated.rs b/crates/ide-assists/src/tests/generated.rs
index d403f86c6d..3a696635af 100644
--- a/crates/ide-assists/src/tests/generated.rs
+++ b/crates/ide-assists/src/tests/generated.rs
@@ -2386,25 +2386,6 @@ fn foo() -> i32 { 42i32 }
     )
 }
 
-#[test]
-fn doctest_unwrap_tuple() {
-    check_doc_test(
-        "unwrap_tuple",
-        r#####"
-//- minicore: result
-fn main() {
-    $0let (foo, bar) = ("Foo", "Bar");
-}
-"#####,
-        r#####"
-fn main() {
-    let foo = "Foo";
-    let bar = "Bar";
-}
-"#####,
-    )
-}
-
 #[test]
 fn doctest_wrap_return_type_in_result() {
     check_doc_test(
diff --git a/crates/ide/src/hover/tests.rs b/crates/ide/src/hover/tests.rs
index eb997e6fef..4b8b47783d 100644
--- a/crates/ide/src/hover/tests.rs
+++ b/crates/ide/src/hover/tests.rs
@@ -698,7 +698,6 @@ fn hover_enum_variant() {
     check(
         r#"
 enum Option<T> {
-    Some(T)
     /// The None variant
     Non$0e
 }
@@ -3528,112 +3527,6 @@ impl<const LEN: usize> Foo<LEN$0> {}
     );
 }
 
-#[test]
-fn hover_const_eval_variant() {
-    // show hex for <10
-    check(
-        r#"
-#[repr(u8)]
-enum E {
-    /// This is a doc
-    A$0 = 1 << 3,
-}
-"#,
-        expect![[r#"
-            *A*
-
-            ```rust
-            test::E
-            ```
-
-            ```rust
-            A = 8
-            ```
-
-            ---
-
-            This is a doc
-        "#]],
-    );
-    // show hex for >10
-    check(
-        r#"
-#[repr(u8)]
-enum E {
-    /// This is a doc
-    A$0 = (1 << 3) + (1 << 2),
-}
-"#,
-        expect![[r#"
-            *A*
-
-            ```rust
-            test::E
-            ```
-
-            ```rust
-            A = 12 (0xC)
-            ```
-
-            ---
-
-            This is a doc
-        "#]],
-    );
-    // enums in const eval
-    check(
-        r#"
-#[repr(u8)]
-enum E {
-    A = 1,
-    /// This is a doc
-    B$0 = E::A as u8 + 1,
-}
-"#,
-        expect![[r#"
-            *B*
-
-            ```rust
-            test::E
-            ```
-
-            ```rust
-            B = 2
-            ```
-
-            ---
-
-            This is a doc
-        "#]],
-    );
-    // unspecified variant should increment by one
-    check(
-        r#"
-#[repr(u8)]
-enum E {
-    A = 4,
-    /// This is a doc
-    B$0,
-}
-"#,
-        expect![[r#"
-            *B*
-
-            ```rust
-            test::E
-            ```
-
-            ```rust
-            B = 5
-            ```
-
-            ---
-
-            This is a doc
-        "#]],
-    );
-}
-
 #[test]
 fn hover_const_eval() {
     // show hex for <10
@@ -3927,35 +3820,6 @@ fn foo() {
 
             ---
 
-            This is a doc
-        "#]],
-    );
-    check(
-        r#"
-enum E {
-    /// This is a doc
-    A = 3,
-}
-fn foo(e: E) {
-    match e {
-        E::A$0 => (),
-        _ => ()
-    }
-}
-"#,
-        expect![[r#"
-            *A*
-
-            ```rust
-            test::E
-            ```
-
-            ```rust
-            A = 3
-            ```
-
-            ---
-
             This is a doc
         "#]],
     );
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 9ed65fbc85..e07fd3925c 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
@@ -48,15 +48,15 @@ pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
 
 <span class="keyword">impl</span> <span class="struct">foo</span> <span class="brace">{</span>
     <span class="keyword">pub</span> <span class="keyword">fn</span> <span class="function associated declaration public static">is_static</span><span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="brace">{</span><span class="brace">}</span>
-    <span class="keyword">pub</span> <span class="keyword">fn</span> <span class="function associated declaration public reference">is_not_static</span><span class="parenthesis">(</span><span class="punctuation">&</span><span class="self_keyword declaration reference">self</span><span class="parenthesis">)</span> <span class="brace">{</span><span class="brace">}</span>
+    <span class="keyword">pub</span> <span class="keyword">fn</span> <span class="function associated declaration public reference">is_not_static</span><span class="parenthesis">(</span><span class="operator">&</span><span class="self_keyword declaration reference">self</span><span class="parenthesis">)</span> <span class="brace">{</span><span class="brace">}</span>
 <span class="brace">}</span>
 
 <span class="keyword">trait</span> <span class="trait declaration">t</span> <span class="brace">{</span>
     <span class="keyword">fn</span> <span class="function associated declaration static trait">t_is_static</span><span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="brace">{</span><span class="brace">}</span>
-    <span class="keyword">fn</span> <span class="function associated declaration reference trait">t_is_not_static</span><span class="parenthesis">(</span><span class="punctuation">&</span><span class="self_keyword declaration reference">self</span><span class="parenthesis">)</span> <span class="brace">{</span><span class="brace">}</span>
+    <span class="keyword">fn</span> <span class="function associated declaration reference trait">t_is_not_static</span><span class="parenthesis">(</span><span class="operator">&</span><span class="self_keyword declaration reference">self</span><span class="parenthesis">)</span> <span class="brace">{</span><span class="brace">}</span>
 <span class="brace">}</span>
 
 <span class="keyword">impl</span> <span class="trait">t</span> <span class="keyword">for</span> <span class="struct">foo</span> <span class="brace">{</span>
     <span class="keyword">pub</span> <span class="keyword">fn</span> <span class="function associated declaration public static trait">is_static</span><span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="brace">{</span><span class="brace">}</span>
-    <span class="keyword">pub</span> <span class="keyword">fn</span> <span class="function associated declaration public reference trait">is_not_static</span><span class="parenthesis">(</span><span class="punctuation">&</span><span class="self_keyword declaration reference">self</span><span class="parenthesis">)</span> <span class="brace">{</span><span class="brace">}</span>
+    <span class="keyword">pub</span> <span class="keyword">fn</span> <span class="function associated declaration public reference trait">is_not_static</span><span class="parenthesis">(</span><span class="operator">&</span><span class="self_keyword declaration reference">self</span><span class="parenthesis">)</span> <span class="brace">{</span><span class="brace">}</span>
 <span class="brace">}</span></code></pre>
\ No newline at end of file
diff --git a/crates/ide/src/syntax_highlighting/test_data/highlight_doctest.html b/crates/ide/src/syntax_highlighting/test_data/highlight_doctest.html
index 18045f1f55..eef5baea98 100644
--- a/crates/ide/src/syntax_highlighting/test_data/highlight_doctest.html
+++ b/crates/ide/src/syntax_highlighting/test_data/highlight_doctest.html
@@ -125,7 +125,7 @@ pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
     <span class="comment documentation">/// ```sh</span>
     <span class="comment documentation">/// echo 1</span>
     <span class="comment documentation">/// ```</span>
-    <span class="keyword">pub</span> <span class="keyword">fn</span> <span class="function associated declaration public reference">foo</span><span class="parenthesis">(</span><span class="punctuation">&</span><span class="self_keyword declaration reference">self</span><span class="parenthesis">)</span> <span class="operator">-&gt;</span> <span class="builtin_type">bool</span> <span class="brace">{</span>
+    <span class="keyword">pub</span> <span class="keyword">fn</span> <span class="function associated declaration public reference">foo</span><span class="parenthesis">(</span><span class="operator">&</span><span class="self_keyword declaration reference">self</span><span class="parenthesis">)</span> <span class="operator">-&gt;</span> <span class="builtin_type">bool</span> <span class="brace">{</span>
         <span class="bool_literal">true</span>
     <span class="brace">}</span>
 <span class="brace">}</span>
diff --git a/crates/ide/src/syntax_highlighting/test_data/highlight_general.html b/crates/ide/src/syntax_highlighting/test_data/highlight_general.html
index 9f2b1926b5..a97802cbbd 100644
--- a/crates/ide/src/syntax_highlighting/test_data/highlight_general.html
+++ b/crates/ide/src/syntax_highlighting/test_data/highlight_general.html
@@ -61,11 +61,11 @@ pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
 <span class="brace">}</span>
 
 <span class="keyword">trait</span> <span class="trait declaration">Bar</span> <span class="brace">{</span>
-    <span class="keyword">fn</span> <span class="function associated declaration reference trait">bar</span><span class="parenthesis">(</span><span class="punctuation">&</span><span class="self_keyword declaration reference">self</span><span class="parenthesis">)</span> <span class="operator">-&gt;</span> <span class="builtin_type">i32</span><span class="semicolon">;</span>
+    <span class="keyword">fn</span> <span class="function associated declaration reference trait">bar</span><span class="parenthesis">(</span><span class="operator">&</span><span class="self_keyword declaration reference">self</span><span class="parenthesis">)</span> <span class="operator">-&gt;</span> <span class="builtin_type">i32</span><span class="semicolon">;</span>
 <span class="brace">}</span>
 
 <span class="keyword">impl</span> <span class="trait">Bar</span> <span class="keyword">for</span> <span class="struct">Foo</span> <span class="brace">{</span>
-    <span class="keyword">fn</span> <span class="function associated declaration reference trait">bar</span><span class="parenthesis">(</span><span class="punctuation">&</span><span class="self_keyword declaration reference">self</span><span class="parenthesis">)</span> <span class="operator">-&gt;</span> <span class="builtin_type">i32</span> <span class="brace">{</span>
+    <span class="keyword">fn</span> <span class="function associated declaration reference trait">bar</span><span class="parenthesis">(</span><span class="operator">&</span><span class="self_keyword declaration reference">self</span><span class="parenthesis">)</span> <span class="operator">-&gt;</span> <span class="builtin_type">i32</span> <span class="brace">{</span>
         <span class="self_keyword reference">self</span><span class="operator">.</span><span class="field">x</span>
     <span class="brace">}</span>
 <span class="brace">}</span>
@@ -75,11 +75,11 @@ pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
         <span class="value_param">f</span><span class="operator">.</span><span class="function associated consuming">baz</span><span class="parenthesis">(</span><span class="self_keyword consuming mutable">self</span><span class="parenthesis">)</span>
     <span class="brace">}</span>
 
-    <span class="keyword">fn</span> <span class="function associated declaration mutable reference">qux</span><span class="parenthesis">(</span><span class="punctuation">&</span><span class="keyword">mut</span> <span class="self_keyword declaration mutable reference">self</span><span class="parenthesis">)</span> <span class="brace">{</span>
+    <span class="keyword">fn</span> <span class="function associated declaration mutable reference">qux</span><span class="parenthesis">(</span><span class="operator">&</span><span class="keyword">mut</span> <span class="self_keyword declaration mutable reference">self</span><span class="parenthesis">)</span> <span class="brace">{</span>
         <span class="self_keyword mutable reference">self</span><span class="operator">.</span><span class="field">x</span> <span class="operator">=</span> <span class="numeric_literal">0</span><span class="semicolon">;</span>
     <span class="brace">}</span>
 
-    <span class="keyword">fn</span> <span class="function associated declaration reference">quop</span><span class="parenthesis">(</span><span class="punctuation">&</span><span class="self_keyword declaration reference">self</span><span class="parenthesis">)</span> <span class="operator">-&gt;</span> <span class="builtin_type">i32</span> <span class="brace">{</span>
+    <span class="keyword">fn</span> <span class="function associated declaration reference">quop</span><span class="parenthesis">(</span><span class="operator">&</span><span class="self_keyword declaration reference">self</span><span class="parenthesis">)</span> <span class="operator">-&gt;</span> <span class="builtin_type">i32</span> <span class="brace">{</span>
         <span class="self_keyword reference">self</span><span class="operator">.</span><span class="field">x</span>
     <span class="brace">}</span>
 <span class="brace">}</span>
@@ -96,11 +96,11 @@ pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
         <span class="value_param">f</span><span class="operator">.</span><span class="function associated">baz</span><span class="parenthesis">(</span><span class="self_keyword">self</span><span class="parenthesis">)</span>
     <span class="brace">}</span>
 
-    <span class="keyword">fn</span> <span class="function associated declaration mutable reference">qux</span><span class="parenthesis">(</span><span class="punctuation">&</span><span class="keyword">mut</span> <span class="self_keyword declaration mutable reference">self</span><span class="parenthesis">)</span> <span class="brace">{</span>
+    <span class="keyword">fn</span> <span class="function associated declaration mutable reference">qux</span><span class="parenthesis">(</span><span class="operator">&</span><span class="keyword">mut</span> <span class="self_keyword declaration mutable reference">self</span><span class="parenthesis">)</span> <span class="brace">{</span>
         <span class="self_keyword mutable reference">self</span><span class="operator">.</span><span class="field">x</span> <span class="operator">=</span> <span class="numeric_literal">0</span><span class="semicolon">;</span>
     <span class="brace">}</span>
 
-    <span class="keyword">fn</span> <span class="function associated declaration reference">quop</span><span class="parenthesis">(</span><span class="punctuation">&</span><span class="self_keyword declaration reference">self</span><span class="parenthesis">)</span> <span class="operator">-&gt;</span> <span class="builtin_type">u32</span> <span class="brace">{</span>
+    <span class="keyword">fn</span> <span class="function associated declaration reference">quop</span><span class="parenthesis">(</span><span class="operator">&</span><span class="self_keyword declaration reference">self</span><span class="parenthesis">)</span> <span class="operator">-&gt;</span> <span class="builtin_type">u32</span> <span class="brace">{</span>
         <span class="self_keyword reference">self</span><span class="operator">.</span><span class="field">x</span>
     <span class="brace">}</span>
 <span class="brace">}</span>
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 abcd80c280..ced7d22f03 100644
--- a/crates/ide/src/syntax_highlighting/test_data/highlight_injection.html
+++ b/crates/ide/src/syntax_highlighting/test_data/highlight_injection.html
@@ -42,7 +42,7 @@ pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
 
 .unresolved_reference { color: #FC5555; text-decoration: wavy underline; }
 </style>
-<pre><code><span class="keyword">fn</span> <span class="function declaration">fixture</span><span class="parenthesis">(</span><span class="value_param declaration reference">ra_fixture</span><span class="colon">:</span> <span class="punctuation">&</span><span class="builtin_type">str</span><span class="parenthesis">)</span> <span class="brace">{</span><span class="brace">}</span>
+<pre><code><span class="keyword">fn</span> <span class="function declaration">fixture</span><span class="parenthesis">(</span><span class="value_param declaration reference">ra_fixture</span><span class="colon">:</span> <span class="operator">&</span><span class="builtin_type">str</span><span class="parenthesis">)</span> <span class="brace">{</span><span class="brace">}</span>
 
 <span class="keyword">fn</span> <span class="function declaration">main</span><span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="brace">{</span>
     <span class="function">fixture</span><span class="parenthesis">(</span><span class="string_literal">r#"</span>
diff --git a/crates/ide/src/syntax_highlighting/test_data/highlight_lifetimes.html b/crates/ide/src/syntax_highlighting/test_data/highlight_lifetimes.html
index f98e0b1cda..2d85fc8c92 100644
--- a/crates/ide/src/syntax_highlighting/test_data/highlight_lifetimes.html
+++ b/crates/ide/src/syntax_highlighting/test_data/highlight_lifetimes.html
@@ -45,8 +45,8 @@ pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
 <pre><code>
 <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="parenthesis attribute">)</span><span class="attribute_bracket attribute">]</span>
 <span class="keyword">struct</span> <span class="struct declaration">Foo</span><span class="angle">&lt;</span><span class="lifetime declaration">'a</span><span class="comma">,</span> <span class="lifetime declaration">'b</span><span class="comma">,</span> <span class="lifetime declaration">'c</span><span class="angle">&gt;</span> <span class="keyword">where</span> <span class="lifetime">'a</span><span class="colon">:</span> <span class="lifetime">'a</span><span class="comma">,</span> <span class="lifetime">'static</span><span class="colon">:</span> <span class="lifetime">'static</span> <span class="brace">{</span>
-    <span class="field declaration">field</span><span class="colon">:</span> <span class="punctuation">&</span><span class="lifetime">'a</span> <span class="parenthesis">(</span><span class="parenthesis">)</span><span class="comma">,</span>
-    <span class="field declaration">field2</span><span class="colon">:</span> <span class="punctuation">&</span><span class="lifetime">'static</span> <span class="parenthesis">(</span><span class="parenthesis">)</span><span class="comma">,</span>
+    <span class="field declaration">field</span><span class="colon">:</span> <span class="operator">&</span><span class="lifetime">'a</span> <span class="parenthesis">(</span><span class="parenthesis">)</span><span class="comma">,</span>
+    <span class="field declaration">field2</span><span class="colon">:</span> <span class="operator">&</span><span class="lifetime">'static</span> <span class="parenthesis">(</span><span class="parenthesis">)</span><span class="comma">,</span>
 <span class="brace">}</span>
 <span class="keyword">impl</span><span class="angle">&lt;</span><span class="lifetime declaration">'a</span><span class="angle">&gt;</span> <span class="struct">Foo</span><span class="angle">&lt;</span><span class="lifetime">'_</span><span class="comma">,</span> <span class="lifetime">'a</span><span class="comma">,</span> <span class="lifetime">'static</span><span class="angle">&gt;</span>
 <span class="keyword">where</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 a626cda3fe..c627bc9b09 100644
--- a/crates/ide/src/syntax_highlighting/test_data/highlight_strings.html
+++ b/crates/ide/src/syntax_highlighting/test_data/highlight_strings.html
@@ -62,16 +62,16 @@ pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
         <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>panicking<span class="colon">:</span><span class="colon">:</span>panic<span class="parenthesis">(</span><span class="string_literal">"explicit panic"</span><span class="parenthesis">)</span>
         <span class="parenthesis">)</span><span class="comma">,</span>
-        <span class="parenthesis">(</span><span class="punctuation">$</span>msg<span class="colon">:</span>literal <span class="punctuation">$</span><span class="parenthesis">(</span><span class="comma">,</span><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="parenthesis">(</span><span class="punctuation">$</span>msg<span class="colon">:</span>literal <span class="punctuation">$</span><span class="parenthesis">(</span><span class="comma">,</span><span class="parenthesis">)</span><span class="operator control">?</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>panicking<span class="colon">:</span><span class="colon">:</span>panic<span class="parenthesis">(</span><span class="punctuation">$</span>msg<span class="parenthesis">)</span>
         <span class="parenthesis">)</span><span class="comma">,</span>
         <span class="comment">// Use `panic_str` instead of `panic_display::&lt;&str&gt;` for non_fmt_panic lint.</span>
-        <span class="parenthesis">(</span><span class="punctuation">$</span>msg<span class="colon">:</span>expr <span class="punctuation">$</span><span class="parenthesis">(</span><span class="comma">,</span><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="parenthesis">(</span><span class="punctuation">$</span>msg<span class="colon">:</span>expr <span class="punctuation">$</span><span class="parenthesis">(</span><span class="comma">,</span><span class="parenthesis">)</span><span class="operator control">?</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>panicking<span class="colon">:</span><span class="colon">:</span>panic_str<span class="parenthesis">(</span><span class="punctuation">$</span>msg<span class="parenthesis">)</span>
         <span class="parenthesis">)</span><span class="comma">,</span>
         <span class="comment">// Special-case the single-argument case for const_panic.</span>
-        <span class="parenthesis">(</span><span class="string_literal">"{}"</span><span class="comma">,</span> <span class="punctuation">$</span>arg<span class="colon">:</span>expr <span class="punctuation">$</span><span class="parenthesis">(</span><span class="comma">,</span><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>panicking<span class="colon">:</span><span class="colon">:</span>panic_display<span class="parenthesis">(</span><span class="punctuation">&</span><span class="punctuation">$</span>arg<span class="parenthesis">)</span>
+        <span class="parenthesis">(</span><span class="string_literal">"{}"</span><span class="comma">,</span> <span class="punctuation">$</span>arg<span class="colon">:</span>expr <span class="punctuation">$</span><span class="parenthesis">(</span><span class="comma">,</span><span class="parenthesis">)</span><span class="operator control">?</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>panicking<span class="colon">:</span><span class="colon">:</span>panic_display<span class="parenthesis">(</span><span class="operator">&</span><span class="punctuation">$</span>arg<span class="parenthesis">)</span>
         <span class="parenthesis">)</span><span class="comma">,</span>
         <span class="parenthesis">(</span><span class="punctuation">$</span>fmt<span class="colon">:</span>expr<span class="comma">,</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>panicking<span class="colon">:</span><span class="colon">:</span>panic_fmt<span class="parenthesis">(</span><span class="punctuation">$</span>crate<span class="colon">:</span><span class="colon">:</span>const_format_args<span class="punctuation">!</span><span class="parenthesis">(</span><span class="punctuation">$</span>fmt<span class="comma">,</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>
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 1992bdc6ae..0716bae751 100644
--- a/crates/ide/src/syntax_highlighting/test_data/highlight_unsafe.html
+++ b/crates/ide/src/syntax_highlighting/test_data/highlight_unsafe.html
@@ -49,7 +49,7 @@ pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
 <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="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="punctuation">&</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="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>
 <span class="brace">}</span>
 <span class="keyword">static</span> <span class="keyword">mut</span> <span class="static declaration mutable unsafe">MUT_GLOBAL</span><span class="colon">:</span> <span class="struct">Struct</span> <span class="operator">=</span> <span class="struct">Struct</span> <span class="brace">{</span> <span class="field">field</span><span class="colon">:</span> <span class="numeric_literal">0</span> <span class="brace">}</span><span class="semicolon">;</span>
@@ -63,7 +63,7 @@ pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
 
 <span class="keyword">struct</span> <span class="struct declaration">Struct</span> <span class="brace">{</span> <span class="field declaration">field</span><span class="colon">:</span> <span class="builtin_type">i32</span> <span class="brace">}</span>
 <span class="keyword">impl</span> <span class="struct">Struct</span> <span class="brace">{</span>
-    <span class="keyword unsafe">unsafe</span> <span class="keyword">fn</span> <span class="function associated declaration reference unsafe">unsafe_method</span><span class="parenthesis">(</span><span class="punctuation">&</span><span class="self_keyword declaration reference">self</span><span class="parenthesis">)</span> <span class="brace">{</span><span class="brace">}</span>
+    <span class="keyword unsafe">unsafe</span> <span class="keyword">fn</span> <span class="function associated declaration reference unsafe">unsafe_method</span><span class="parenthesis">(</span><span class="operator">&</span><span class="self_keyword declaration reference">self</span><span class="parenthesis">)</span> <span class="brace">{</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">repr</span><span class="parenthesis attribute">(</span><span class="none attribute">packed</span><span class="parenthesis attribute">)</span><span class="attribute_bracket attribute">]</span>
@@ -78,11 +78,11 @@ pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
 <span class="keyword">fn</span> <span class="function declaration">unsafe_trait_bound</span><span class="angle">&lt;</span><span class="type_param declaration">T</span><span class="colon">:</span> <span class="trait">UnsafeTrait</span><span class="angle">&gt;</span><span class="parenthesis">(</span><span class="punctuation">_</span><span class="colon">:</span> <span class="type_param">T</span><span class="parenthesis">)</span> <span class="brace">{</span><span class="brace">}</span>
 
 <span class="keyword">trait</span> <span class="trait declaration">DoTheAutoref</span> <span class="brace">{</span>
-    <span class="keyword">fn</span> <span class="function associated declaration reference trait">calls_autoref</span><span class="parenthesis">(</span><span class="punctuation">&</span><span class="self_keyword declaration reference">self</span><span class="parenthesis">)</span><span class="semicolon">;</span>
+    <span class="keyword">fn</span> <span class="function associated declaration reference trait">calls_autoref</span><span class="parenthesis">(</span><span class="operator">&</span><span class="self_keyword declaration reference">self</span><span class="parenthesis">)</span><span class="semicolon">;</span>
 <span class="brace">}</span>
 
 <span class="keyword">impl</span> <span class="trait">DoTheAutoref</span> <span class="keyword">for</span> <span class="builtin_type">u16</span> <span class="brace">{</span>
-    <span class="keyword">fn</span> <span class="function associated declaration reference trait">calls_autoref</span><span class="parenthesis">(</span><span class="punctuation">&</span><span class="self_keyword declaration reference">self</span><span class="parenthesis">)</span> <span class="brace">{</span><span class="brace">}</span>
+    <span class="keyword">fn</span> <span class="function associated declaration reference trait">calls_autoref</span><span class="parenthesis">(</span><span class="operator">&</span><span class="self_keyword declaration reference">self</span><span class="parenthesis">)</span> <span class="brace">{</span><span class="brace">}</span>
 <span class="brace">}</span>
 
 <span class="keyword">fn</span> <span class="function declaration">main</span><span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="brace">{</span>
diff --git a/crates/proc-macro-srv/src/tests/mod.rs b/crates/proc-macro-srv/src/tests/mod.rs
index b46cdddcf6..6339d56d01 100644
--- a/crates/proc-macro-srv/src/tests/mod.rs
+++ b/crates/proc-macro-srv/src/tests/mod.rs
@@ -2,9 +2,9 @@
 
 #[macro_use]
 mod utils;
-use utils::*;
-
 use expect_test::expect;
+use paths::AbsPathBuf;
+use utils::*;
 
 #[test]
 fn test_derive_empty() {
@@ -157,3 +157,10 @@ fn list_test_macros() {
         DeriveError [CustomDerive]"#]]
     .assert_eq(&res);
 }
+
+#[test]
+fn test_version_check() {
+    let path = AbsPathBuf::assert(fixtures::proc_macro_test_dylib_path());
+    let info = proc_macro_api::read_dylib_info(&path).unwrap();
+    assert!(info.version.1 >= 50);
+}
diff --git a/crates/proc-macro-srv/src/tests/utils.rs b/crates/proc-macro-srv/src/tests/utils.rs
index 44b1b6588d..f881fe8684 100644
--- a/crates/proc-macro-srv/src/tests/utils.rs
+++ b/crates/proc-macro-srv/src/tests/utils.rs
@@ -1,9 +1,15 @@
 //! utils used in proc-macro tests
 
+use crate::dylib;
+use crate::ProcMacroSrv;
 use expect_test::Expect;
 use std::str::FromStr;
 
-use crate::{dylib, proc_macro_test_dylib_path, ProcMacroSrv};
+pub mod fixtures {
+    pub fn proc_macro_test_dylib_path() -> std::path::PathBuf {
+        proc_macro_test::PROC_MACRO_TEST_LOCATION.into()
+    }
+}
 
 fn parse_string(code: &str) -> Option<crate::abis::TestTokenStream> {
     // This is a bit strange. We need to parse a string into a token stream into
@@ -24,7 +30,7 @@ pub fn assert_expand_attr(macro_name: &str, ra_fixture: &str, attr_args: &str, e
 }
 
 fn assert_expand_impl(macro_name: &str, input: &str, attr: Option<&str>, expect: Expect) {
-    let path = proc_macro_test_dylib_path();
+    let path = fixtures::proc_macro_test_dylib_path();
     let expander = dylib::Expander::new(&path).unwrap();
     let fixture = parse_string(input).unwrap();
     let attr = attr.map(|attr| parse_string(attr).unwrap().into_subtree());
@@ -34,7 +40,7 @@ fn assert_expand_impl(macro_name: &str, input: &str, attr: Option<&str>, expect:
 }
 
 pub(crate) fn list() -> Vec<String> {
-    let dylib_path = proc_macro_test_dylib_path();
+    let dylib_path = fixtures::proc_macro_test_dylib_path();
     let mut srv = ProcMacroSrv::default();
     let res = srv.list_macros(&dylib_path).unwrap();
     res.into_iter().map(|(name, kind)| format!("{} [{:?}]", name, kind)).collect()
diff --git a/crates/project-model/src/tests.rs b/crates/project-model/src/tests.rs
index e2444e2497..bea624bd54 100644
--- a/crates/project-model/src/tests.rs
+++ b/crates/project-model/src/tests.rs
@@ -10,8 +10,8 @@ use paths::{AbsPath, AbsPathBuf};
 use serde::de::DeserializeOwned;
 
 use crate::{
-    CargoWorkspace, CfgOverrides, ProjectJson, ProjectJsonData, ProjectWorkspace, Sysroot,
-    WorkspaceBuildScripts,
+    CargoConfig, CargoWorkspace, CfgOverrides, ProjectJson, ProjectJsonData, ProjectWorkspace,
+    Sysroot, WorkspaceBuildScripts,
 };
 
 fn load_cargo(file: &str) -> CrateGraph {
@@ -101,7 +101,7 @@ fn to_crate_graph(project_workspace: ProjectWorkspace) -> CrateGraph {
                 Some(FileId(counter))
             }
         },
-        &Default::default(),
+        &CargoConfig::default(),
     )
 }
 
@@ -185,9 +185,6 @@ fn cargo_hello_world_project_model_with_wildcard_overrides() {
                         ),
                         origin: CratesIo {
                             repo: None,
-                            name: Some(
-                                "hello-world",
-                            ),
                         },
                         is_proc_macro: false,
                     },
@@ -263,9 +260,6 @@ fn cargo_hello_world_project_model_with_wildcard_overrides() {
                         ),
                         origin: CratesIo {
                             repo: None,
-                            name: Some(
-                                "hello-world",
-                            ),
                         },
                         is_proc_macro: false,
                     },
@@ -341,9 +335,6 @@ fn cargo_hello_world_project_model_with_wildcard_overrides() {
                         ),
                         origin: CratesIo {
                             repo: None,
-                            name: Some(
-                                "hello-world",
-                            ),
                         },
                         is_proc_macro: false,
                     },
@@ -419,9 +410,6 @@ fn cargo_hello_world_project_model_with_wildcard_overrides() {
                         ),
                         origin: CratesIo {
                             repo: None,
-                            name: Some(
-                                "hello-world",
-                            ),
                         },
                         is_proc_macro: false,
                     },
@@ -489,9 +477,6 @@ fn cargo_hello_world_project_model_with_wildcard_overrides() {
                             repo: Some(
                                 "https://github.com/rust-lang/libc",
                             ),
-                            name: Some(
-                                "libc",
-                            ),
                         },
                         is_proc_macro: false,
                     },
@@ -582,9 +567,6 @@ fn cargo_hello_world_project_model_with_selective_overrides() {
                         ),
                         origin: CratesIo {
                             repo: None,
-                            name: Some(
-                                "hello-world",
-                            ),
                         },
                         is_proc_macro: false,
                     },
@@ -662,9 +644,6 @@ fn cargo_hello_world_project_model_with_selective_overrides() {
                         ),
                         origin: CratesIo {
                             repo: None,
-                            name: Some(
-                                "hello-world",
-                            ),
                         },
                         is_proc_macro: false,
                     },
@@ -742,9 +721,6 @@ fn cargo_hello_world_project_model_with_selective_overrides() {
                         ),
                         origin: CratesIo {
                             repo: None,
-                            name: Some(
-                                "hello-world",
-                            ),
                         },
                         is_proc_macro: false,
                     },
@@ -822,9 +798,6 @@ fn cargo_hello_world_project_model_with_selective_overrides() {
                         ),
                         origin: CratesIo {
                             repo: None,
-                            name: Some(
-                                "hello-world",
-                            ),
                         },
                         is_proc_macro: false,
                     },
@@ -892,9 +865,6 @@ fn cargo_hello_world_project_model_with_selective_overrides() {
                             repo: Some(
                                 "https://github.com/rust-lang/libc",
                             ),
-                            name: Some(
-                                "libc",
-                            ),
                         },
                         is_proc_macro: false,
                     },
@@ -976,9 +946,6 @@ fn cargo_hello_world_project_model() {
                         ),
                         origin: CratesIo {
                             repo: None,
-                            name: Some(
-                                "hello-world",
-                            ),
                         },
                         is_proc_macro: false,
                     },
@@ -1056,9 +1023,6 @@ fn cargo_hello_world_project_model() {
                         ),
                         origin: CratesIo {
                             repo: None,
-                            name: Some(
-                                "hello-world",
-                            ),
                         },
                         is_proc_macro: false,
                     },
@@ -1136,9 +1100,6 @@ fn cargo_hello_world_project_model() {
                         ),
                         origin: CratesIo {
                             repo: None,
-                            name: Some(
-                                "hello-world",
-                            ),
                         },
                         is_proc_macro: false,
                     },
@@ -1216,9 +1177,6 @@ fn cargo_hello_world_project_model() {
                         ),
                         origin: CratesIo {
                             repo: None,
-                            name: Some(
-                                "hello-world",
-                            ),
                         },
                         is_proc_macro: false,
                     },
@@ -1286,9 +1244,6 @@ fn cargo_hello_world_project_model() {
                             repo: Some(
                                 "https://github.com/rust-lang/libc",
                             ),
-                            name: Some(
-                                "libc",
-                            ),
                         },
                         is_proc_macro: false,
                     },
@@ -1849,9 +1804,6 @@ fn rust_project_hello_world_project_model() {
                         ),
                         origin: CratesIo {
                             repo: None,
-                            name: Some(
-                                "hello_world",
-                            ),
                         },
                         is_proc_macro: false,
                     },
diff --git a/crates/rust-analyzer/tests/slow-tests/main.rs b/crates/rust-analyzer/tests/slow-tests/main.rs
index 9032c21d09..4cc46af1b1 100644
--- a/crates/rust-analyzer/tests/slow-tests/main.rs
+++ b/crates/rust-analyzer/tests/slow-tests/main.rs
@@ -18,6 +18,7 @@ mod tidy;
 
 use std::{collections::HashMap, path::PathBuf, time::Instant};
 
+use expect_test::expect;
 use lsp_types::{
     notification::DidOpenTextDocument,
     request::{
@@ -820,10 +821,7 @@ fn main() {
 }
 
 #[test]
-// FIXME: Re-enable once we can run proc-macro tests on rust-lang/rust-analyzer again
-#[cfg(any())]
 fn resolve_proc_macro() {
-    use expect_test::expect;
     if skip_slow_tests() {
         return;
     }
diff --git a/crates/test-utils/src/minicore.rs b/crates/test-utils/src/minicore.rs
index 10386b5b7b..6df29db474 100644
--- a/crates/test-utils/src/minicore.rs
+++ b/crates/test-utils/src/minicore.rs
@@ -37,7 +37,6 @@
 //!     add:
 //!     as_ref: sized
 //!     drop:
-//!     generator: pin
 
 pub mod marker {
     // region:sized
@@ -183,19 +182,6 @@ pub mod ops {
             type Target: ?Sized;
             fn deref(&self) -> &Self::Target;
         }
-
-        impl<T: ?Sized> Deref for &T {
-            type Target = T;
-            fn deref(&self) -> &T {
-                loop {}
-            }
-        }
-        impl<T: ?Sized> Deref for &mut T {
-            type Target = T;
-            fn deref(&self) -> &T {
-                loop {}
-            }
-        }
         // region:deref_mut
         #[lang = "deref_mut"]
         pub trait DerefMut: Deref {
@@ -361,27 +347,6 @@ pub mod ops {
         fn add(self, rhs: Rhs) -> Self::Output;
     }
     // endregion:add
-
-    // region:generator
-    mod generator {
-        use crate::pin::Pin;
-
-        #[lang = "generator"]
-        pub trait Generator<R = ()> {
-            type Yield;
-            #[lang = "generator_return"]
-            type Return;
-            fn resume(self: Pin<&mut Self>, arg: R) -> GeneratorState<Self::Yield, Self::Return>;
-        }
-
-        #[lang = "generator_state"]
-        pub enum GeneratorState<Y, R> {
-            Yielded(Y),
-            Complete(R),
-        }
-    }
-    pub use self::generator::{Generator, GeneratorState};
-    // endregion:generator
 }
 
 // region:eq
@@ -490,19 +455,6 @@ pub mod pin {
     pub struct Pin<P> {
         pointer: P,
     }
-    impl<P> Pin<P> {
-        pub fn new(pointer: P) -> Pin<P> {
-            loop {}
-        }
-    }
-    // region:deref
-    impl<P: crate::ops::Deref> crate::ops::Deref for Pin<P> {
-        type Target = P::Target;
-        fn deref(&self) -> &P::Target {
-            loop {}
-        }
-    }
-    // endregion:deref
 }
 // endregion:pin