Repository: rust-analyzer/rust-analyzer
Pull request #6845 (2020-12-12 17:23:21)

Don't HirDisplay unknown types when displaying for source
Was wondering why the add missing impl assist didn't do anything here:
![Code_JCA1Qo0V9P](https://user-images.githubusercontent.com/3757771/101990300-7af44a80-3ca6-11eb-8431-e5eb4de4e78c.png)
Turns out me forgetting to set the Index::Idx type in the trait causes RA to panic due to it trying to to create an unparsable type in the `make` module.
Now we get this instead which imo is definitely better to have.
![Code_MUFPJUCULY](https://user-images.githubusercontent.com/3757771/101990347-c9094e00-3ca6-11eb-9c6a-146bddf64b7c.png)



matklad: Hey, I see someone's solving AOC :D Hit the same bug, but was  too lazy to submit a fix/issue.

lgtm!
matklad: Hm, maybe just add a test for this case to the corresponding assist? 

Patch:
diff --git a/Cargo.lock b/Cargo.lock
index 8cb5fd7ad3..d3aec4c996 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -261,9 +261,9 @@ dependencies = [
 
 [[package]]
 name = "const_fn"
-version = "0.4.4"
+version = "0.4.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cd51eab21ab4fd6a3bf889e2d0958c0a6e3a61ad04260325e919e652a2a62826"
+checksum = "c478836e029dcef17fb47c89023448c64f781a046e0300e257ad8225ae59afab"
 
 [[package]]
 name = "crc32fast"
@@ -990,9 +990,9 @@ dependencies = [
 
 [[package]]
 name = "net2"
-version = "0.2.37"
+version = "0.2.36"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "391630d12b68002ae1e25e8f974306474966550ad82dac6886fb8910c19568ae"
+checksum = "d7cf75f38f16cb05ea017784dc6dbfd354f76c223dba37701734c4f5a9337d02"
 dependencies = [
  "cfg-if 0.1.10",
  "libc",
@@ -2021,18 +2021,18 @@ dependencies = [
 
 [[package]]
 name = "xshell"
-version = "0.1.7"
+version = "0.1.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ed0728d188f2ae530490b7d92435728aba53c6aed06d07e1951da9bd4c1d0798"
+checksum = "3e9bbfccbb2233e6b0473b7870d4b0811a402e9e249a5e8394e768e5a5c9c37d"
 dependencies = [
  "xshell-macros",
 ]
 
 [[package]]
 name = "xshell-macros"
-version = "0.1.7"
+version = "0.1.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "367f903cc3f8bc4f4b2400d47dfa6c9e3e121ffb51a30cf0fb67a72c0a0f9617"
+checksum = "b94f1c632d730a1704b21dc551a4c74fbed713cfa59593708f94943548206134"
 
 [[package]]
 name = "xtask"
diff --git a/crates/assists/src/ast_transform.rs b/crates/assists/src/ast_transform.rs
index da94e9987c..66e4634b1d 100644
--- a/crates/assists/src/ast_transform.rs
+++ b/crates/assists/src/ast_transform.rs
@@ -89,7 +89,7 @@ impl<'a> SubstituteTypeParams<'a> {
         let substs = get_syntactic_substs(impl_def).unwrap_or_default();
         let generic_def: hir::GenericDef = trait_.into();
         let substs_by_param: FxHashMap<_, _> = generic_def
-            .type_params(source_scope.db)
+            .params(source_scope.db)
             .into_iter()
             // this is a trait impl, so we need to skip the first type parameter -- this is a bit hacky
             .skip(1)
diff --git a/crates/assists/src/handlers/add_missing_impl_members.rs b/crates/assists/src/handlers/add_missing_impl_members.rs
index bbb71e261f..e413505d3e 100644
--- a/crates/assists/src/handlers/add_missing_impl_members.rs
+++ b/crates/assists/src/handlers/add_missing_impl_members.rs
@@ -781,6 +781,31 @@ impl Test for () {
         ${0:todo!()}
     }
 }
+"#,
+        )
+    }
+
+    #[test]
+    fn missing_generic_type() {
+        check_assist(
+            add_missing_impl_members,
+            r#"
+trait Foo<BAR> {
+    fn foo(&self, bar: BAR);
+}
+impl Foo for () {
+    <|>
+}
+"#,
+            r#"
+trait Foo<BAR> {
+    fn foo(&self, bar: BAR);
+}
+impl Foo for () {
+    fn foo(&self, bar: BAR) {
+        ${0:todo!()}
+    }
+}
 "#,
         )
     }
diff --git a/crates/assists/src/handlers/extract_struct_from_enum_variant.rs b/crates/assists/src/handlers/extract_struct_from_enum_variant.rs
index 2e56bd7ffc..d85767b4ec 100644
--- a/crates/assists/src/handlers/extract_struct_from_enum_variant.rs
+++ b/crates/assists/src/handlers/extract_struct_from_enum_variant.rs
@@ -212,7 +212,7 @@ fn update_reference(
         find_node_at_offset::<ast::PathExpr>(source_file.syntax(), offset)
     {
         // tuple variant
-        (path_expr.path()?.segment()?, path_expr.syntax().parent()?)
+        (path_expr.path()?.segment()?, path_expr.syntax().parent()?.clone())
     } else if let Some(record_expr) =
         find_node_at_offset::<ast::RecordExpr>(source_file.syntax(), offset)
     {
diff --git a/crates/assists/src/handlers/qualify_path.rs b/crates/assists/src/handlers/qualify_path.rs
index 98cb09214c..6f9810fe88 100644
--- a/crates/assists/src/handlers/qualify_path.rs
+++ b/crates/assists/src/handlers/qualify_path.rs
@@ -150,7 +150,7 @@ impl QualifyCandidate<'_> {
                 import,
                 trait_method_name,
                 generics,
-                match arg_list {
+                match arg_list.clone() {
                     Some(args) => make::arg_list(iter::once(receiver).chain(args)),
                     None => make::arg_list(iter::once(receiver)),
                 }
diff --git a/crates/cfg/src/dnf.rs b/crates/cfg/src/dnf.rs
index 30f4bcdf79..580c9a9a2c 100644
--- a/crates/cfg/src/dnf.rs
+++ b/crates/cfg/src/dnf.rs
@@ -30,7 +30,7 @@ impl DnfExpr {
     pub fn new(expr: CfgExpr) -> Self {
         let builder = Builder { expr: DnfExpr { conjunctions: Vec::new() } };
 
-        builder.lower(expr)
+        builder.lower(expr.clone())
     }
 
     /// Computes a list of present or absent atoms in `opts` that cause this expression to evaluate
diff --git a/crates/completion/src/completions/unqualified_path.rs b/crates/completion/src/completions/unqualified_path.rs
index b9315f6c04..2b0924ae5a 100644
--- a/crates/completion/src/completions/unqualified_path.rs
+++ b/crates/completion/src/completions/unqualified_path.rs
@@ -147,7 +147,7 @@ fn fuzzy_completion(acc: &mut Completions, ctx: &CompletionContext) -> Option<()
     .filter_map(|(import_path, definition)| {
         render_resolution_with_import(
             RenderContext::new(ctx),
-            ImportEdit { import_path, import_scope: import_scope.clone() },
+            ImportEdit { import_path: import_path.clone(), import_scope: import_scope.clone() },
             &definition,
         )
     });
diff --git a/crates/completion/src/render/function.rs b/crates/completion/src/render/function.rs
index 316e05b529..d16005249c 100644
--- a/crates/completion/src/render/function.rs
+++ b/crates/completion/src/render/function.rs
@@ -91,7 +91,7 @@ impl<'a> FunctionRender<'a> {
             .zip(params_ty)
             .flat_map(|(pat, param_ty)| {
                 let pat = pat?;
-                let name = pat;
+                let name = pat.to_string();
                 let arg = name.trim_start_matches("mut ").trim_start_matches('_');
                 Some(self.add_arg(arg, param_ty.ty()))
             })
diff --git a/crates/hir/src/code_model.rs b/crates/hir/src/code_model.rs
index fcc42c6bbc..9a1e9ba496 100644
--- a/crates/hir/src/code_model.rs
+++ b/crates/hir/src/code_model.rs
@@ -19,9 +19,8 @@ use hir_def::{
     src::HasSource as _,
     type_ref::{Mutability, TypeRef},
     AdtId, AssocContainerId, AssocItemId, AssocItemLoc, AttrDefId, ConstId, DefWithBodyId, EnumId,
-    FunctionId, GenericDefId, HasModule, ImplId, LifetimeParamId, LocalEnumVariantId, LocalFieldId,
-    LocalModuleId, Lookup, ModuleId, StaticId, StructId, TraitId, TypeAliasId, TypeParamId,
-    UnionId,
+    FunctionId, GenericDefId, HasModule, ImplId, LocalEnumVariantId, LocalFieldId, LocalModuleId,
+    Lookup, ModuleId, StaticId, StructId, TraitId, TypeAliasId, TypeParamId, UnionId,
 };
 use hir_def::{find_path::PrefixKind, item_scope::ItemInNs, visibility::Visibility};
 use hir_expand::{
@@ -832,7 +831,7 @@ impl SelfParam {
             .params
             .first()
             .map(|param| match *param {
-                TypeRef::Reference(.., mutability) => mutability.into(),
+                TypeRef::Reference(_, mutability) => mutability.into(),
                 _ => Access::Owned,
             })
             .unwrap_or(Access::Owned)
@@ -1099,25 +1098,8 @@ impl_from!(
 );
 
 impl GenericDef {
-    pub fn params(self, db: &dyn HirDatabase) -> Vec<GenericParam> {
-        let generics = db.generic_params(self.into());
-        let ty_params = generics
-            .types
-            .iter()
-            .map(|(local_id, _)| TypeParam { id: TypeParamId { parent: self.into(), local_id } })
-            .map(GenericParam::TypeParam);
-        let lt_params = generics
-            .lifetimes
-            .iter()
-            .map(|(local_id, _)| LifetimeParam {
-                id: LifetimeParamId { parent: self.into(), local_id },
-            })
-            .map(GenericParam::LifetimeParam);
-        ty_params.chain(lt_params).collect()
-    }
-
-    pub fn type_params(self, db: &dyn HirDatabase) -> Vec<TypeParam> {
-        let generics = db.generic_params(self.into());
+    pub fn params(self, db: &dyn HirDatabase) -> Vec<TypeParam> {
+        let generics: Arc<hir_def::generics::GenericParams> = db.generic_params(self.into());
         generics
             .types
             .iter()
@@ -1193,13 +1175,6 @@ impl Local {
     }
 }
 
-#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
-pub enum GenericParam {
-    TypeParam(TypeParam),
-    LifetimeParam(LifetimeParam),
-}
-impl_from!(TypeParam, LifetimeParam for GenericParam);
-
 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
 pub struct TypeParam {
     pub(crate) id: TypeParamId,
@@ -1240,18 +1215,6 @@ impl TypeParam {
     }
 }
 
-#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
-pub struct LifetimeParam {
-    pub(crate) id: LifetimeParamId,
-}
-
-impl LifetimeParam {
-    pub fn name(self, db: &dyn HirDatabase) -> Name {
-        let params = db.generic_params(self.id.parent);
-        params.lifetimes[self.id.local_id].name.clone()
-    }
-}
-
 // FIXME: rename from `ImplDef` to `Impl`
 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
 pub struct ImplDef {
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs
index 0f399a2c6e..302a524918 100644
--- a/crates/hir/src/lib.rs
+++ b/crates/hir/src/lib.rs
@@ -35,8 +35,8 @@ pub use crate::{
     code_model::{
         Access, Adt, AsAssocItem, AssocItem, AssocItemContainer, Callable, CallableKind, Const,
         Crate, CrateDependency, DefWithBody, Enum, EnumVariant, Field, FieldSource, Function,
-        GenericDef, HasVisibility, ImplDef, LifetimeParam, Local, MacroDef, Module, ModuleDef,
-        ScopeDef, Static, Struct, Trait, Type, TypeAlias, TypeParam, Union, VariantDef,
+        GenericDef, HasVisibility, ImplDef, Local, MacroDef, Module, ModuleDef, ScopeDef, Static,
+        Struct, Trait, Type, TypeAlias, TypeParam, Union, VariantDef,
     },
     has_source::HasSource,
     semantics::{PathResolution, Semantics, SemanticsScope},
@@ -56,9 +56,8 @@ pub use hir_def::{
     visibility::Visibility,
 };
 pub use hir_expand::{
-    name::{known, AsName, Name},
-    ExpandResult, HirFileId, InFile, MacroCallId, MacroCallLoc, /* FIXME */ MacroDefId,
-    MacroFile, Origin,
+    name::known, name::AsName, name::Name, ExpandResult, HirFileId, InFile, MacroCallId,
+    MacroCallLoc, /* FIXME */ MacroDefId, MacroFile, Origin,
 };
 pub use hir_ty::display::HirDisplay;
 
diff --git a/crates/hir_def/src/attr.rs b/crates/hir_def/src/attr.rs
index c64b78445c..ff8fb74831 100644
--- a/crates/hir_def/src/attr.rs
+++ b/crates/hir_def/src/attr.rs
@@ -23,7 +23,7 @@ use crate::{
 };
 
 /// Holds documentation
-#[derive(Debug, Clone, PartialEq, Eq, Hash)]
+#[derive(Debug, Clone, PartialEq, Eq)]
 pub struct Documentation(String);
 
 impl Documentation {
diff --git a/crates/hir_def/src/generics.rs b/crates/hir_def/src/generics.rs
index 5189c7e9f3..835fe3fbdc 100644
--- a/crates/hir_def/src/generics.rs
+++ b/crates/hir_def/src/generics.rs
@@ -21,7 +21,7 @@ use crate::{
     keys,
     src::HasChildSource,
     src::HasSource,
-    type_ref::{LifetimeRef, TypeBound, TypeRef},
+    type_ref::{TypeBound, TypeRef},
     AdtId, GenericDefId, LocalTypeParamId, Lookup, TypeParamId,
 };
 
@@ -33,12 +33,6 @@ pub struct TypeParamData {
     pub provenance: TypeParamProvenance,
 }
 
-/// Data about a generic parameter (to a function, struct, impl, ...).
-#[derive(Clone, PartialEq, Eq, Debug)]
-pub struct LifetimeParamData {
-    pub name: Name,
-}
-
 #[derive(Copy, Clone, PartialEq, Eq, Debug)]
 pub enum TypeParamProvenance {
     TypeParamList,
@@ -50,7 +44,7 @@ pub enum TypeParamProvenance {
 #[derive(Clone, PartialEq, Eq, Debug, Default)]
 pub struct GenericParams {
     pub types: Arena<TypeParamData>,
-    pub lifetimes: Arena<LifetimeParamData>,
+    // lifetimes: Arena<LocalLifetimeParamId, LifetimeParamData>,
     pub where_predicates: Vec<WherePredicate>,
 }
 
@@ -59,17 +53,16 @@ pub struct GenericParams {
 /// It might still result in multiple actual predicates though, because of
 /// associated type bindings like `Iterator<Item = u32>`.
 #[derive(Clone, PartialEq, Eq, Debug)]
-pub enum WherePredicate {
-    TypeBound { target: WherePredicateTypeTarget, bound: TypeBound },
-    Lifetime { target: LifetimeRef, bound: LifetimeRef },
+pub struct WherePredicate {
+    pub target: WherePredicateTarget,
+    pub bound: TypeBound,
 }
 
 #[derive(Clone, PartialEq, Eq, Debug)]
-pub enum WherePredicateTypeTarget {
+pub enum WherePredicateTarget {
     TypeRef(TypeRef),
     /// For desugared where predicates that can directly refer to a type param.
     TypeParam(LocalTypeParamId),
-    // FIXME: ForLifetime(Vec<LifetimeParamId>, TypeRef)
 }
 
 type SourceMap = ArenaMap<LocalTypeParamId, Either<ast::Trait, ast::TypeParam>>;
@@ -130,7 +123,7 @@ impl GenericParams {
     }
 
     fn new(db: &dyn DefDatabase, def: GenericDefId) -> (GenericParams, InFile<SourceMap>) {
-        let mut generics = GenericParams::default();
+        let mut generics = GenericParams { types: Arena::default(), where_predicates: Vec::new() };
         let mut sm = ArenaMap::default();
 
         // FIXME: add `: Sized` bound for everything except for `Self` in traits
@@ -178,7 +171,7 @@ impl GenericParams {
                 // add super traits as bounds on Self
                 // i.e., trait Foo: Bar is equivalent to trait Foo where Self: Bar
                 let self_param = TypeRef::Path(name![Self].into());
-                generics.fill_bounds(&lower_ctx, &src.value, Either::Left(self_param));
+                generics.fill_bounds(&lower_ctx, &src.value, self_param);
 
                 generics.fill(&lower_ctx, &mut sm, &src.value);
                 src.file_id
@@ -225,12 +218,12 @@ impl GenericParams {
         &mut self,
         lower_ctx: &LowerCtx,
         node: &dyn ast::TypeBoundsOwner,
-        target: Either<TypeRef, LifetimeRef>,
+        type_ref: TypeRef,
     ) {
         for bound in
             node.type_bound_list().iter().flat_map(|type_bound_list| type_bound_list.bounds())
         {
-            self.add_where_predicate_from_bound(lower_ctx, bound, target.clone());
+            self.add_where_predicate_from_bound(lower_ctx, bound, type_ref.clone());
         }
     }
 
@@ -253,30 +246,19 @@ impl GenericParams {
             sm.insert(param_id, Either::Right(type_param.clone()));
 
             let type_ref = TypeRef::Path(name.into());
-            self.fill_bounds(&lower_ctx, &type_param, Either::Left(type_ref));
-        }
-        for lifetime_param in params.lifetime_params() {
-            let name = lifetime_param
-                .lifetime_token()
-                .map_or_else(Name::missing, |tok| Name::new_lifetime(&tok));
-            let param = LifetimeParamData { name: name.clone() };
-            let _param_id = self.lifetimes.alloc(param);
-            let lifetime_ref = LifetimeRef::new_name(name);
-            self.fill_bounds(&lower_ctx, &lifetime_param, Either::Right(lifetime_ref));
+            self.fill_bounds(&lower_ctx, &type_param, type_ref);
         }
     }
 
     fn fill_where_predicates(&mut self, lower_ctx: &LowerCtx, where_clause: ast::WhereClause) {
         for pred in where_clause.predicates() {
-            let target = if let Some(type_ref) = pred.ty() {
-                Either::Left(TypeRef::from_ast(lower_ctx, type_ref))
-            } else if let Some(lifetime_tok) = pred.lifetime_token() {
-                Either::Right(LifetimeRef::from_token(lifetime_tok))
-            } else {
-                continue;
+            let type_ref = match pred.ty() {
+                Some(type_ref) => type_ref,
+                None => continue,
             };
+            let type_ref = TypeRef::from_ast(lower_ctx, type_ref);
             for bound in pred.type_bound_list().iter().flat_map(|l| l.bounds()) {
-                self.add_where_predicate_from_bound(lower_ctx, bound, target.clone());
+                self.add_where_predicate_from_bound(lower_ctx, bound, type_ref.clone());
             }
         }
     }
@@ -285,24 +267,15 @@ impl GenericParams {
         &mut self,
         lower_ctx: &LowerCtx,
         bound: ast::TypeBound,
-        target: Either<TypeRef, LifetimeRef>,
+        type_ref: TypeRef,
     ) {
         if bound.question_mark_token().is_some() {
             // FIXME: remove this bound
             return;
         }
         let bound = TypeBound::from_ast(lower_ctx, bound);
-        let predicate = match (target, bound) {
-            (Either::Left(type_ref), bound) => WherePredicate::TypeBound {
-                target: WherePredicateTypeTarget::TypeRef(type_ref),
-                bound,
-            },
-            (Either::Right(lifetime), TypeBound::Lifetime(bound)) => {
-                WherePredicate::Lifetime { target: lifetime, bound }
-            }
-            _ => return,
-        };
-        self.where_predicates.push(predicate);
+        self.where_predicates
+            .push(WherePredicate { target: WherePredicateTarget::TypeRef(type_ref), bound });
     }
 
     pub(crate) fn fill_implicit_impl_trait_args(&mut self, type_ref: &TypeRef) {
@@ -315,8 +288,8 @@ impl GenericParams {
                 };
                 let param_id = self.types.alloc(param);
                 for bound in bounds {
-                    self.where_predicates.push(WherePredicate::TypeBound {
-                        target: WherePredicateTypeTarget::TypeParam(param_id),
+                    self.where_predicates.push(WherePredicate {
+                        target: WherePredicateTarget::TypeParam(param_id),
                         bound: bound.clone(),
                     });
                 }
diff --git a/crates/hir_def/src/item_tree.rs b/crates/hir_def/src/item_tree.rs
index c6ada271e9..c017b352d8 100644
--- a/crates/hir_def/src/item_tree.rs
+++ b/crates/hir_def/src/item_tree.rs
@@ -255,7 +255,7 @@ impl GenericParamsStorage {
 }
 
 static EMPTY_GENERICS: GenericParams =
-    GenericParams { types: Arena::new(), lifetimes: Arena::new(), where_predicates: Vec::new() };
+    GenericParams { types: Arena::new(), where_predicates: Vec::new() };
 
 #[derive(Default, Debug, Eq, PartialEq)]
 struct ItemTreeData {
diff --git a/crates/hir_def/src/item_tree/lower.rs b/crates/hir_def/src/item_tree/lower.rs
index f7ce2e26df..63b2826f85 100644
--- a/crates/hir_def/src/item_tree/lower.rs
+++ b/crates/hir_def/src/item_tree/lower.rs
@@ -13,7 +13,6 @@ use syntax::{
 use crate::{
     attr::Attrs,
     generics::{GenericParams, TypeParamData, TypeParamProvenance},
-    type_ref::LifetimeRef,
 };
 
 use super::*;
@@ -293,16 +292,12 @@ impl Ctx {
                         let self_type = TypeRef::Path(name![Self].into());
                         match self_param.kind() {
                             ast::SelfParamKind::Owned => self_type,
-                            ast::SelfParamKind::Ref => TypeRef::Reference(
-                                Box::new(self_type),
-                                self_param.lifetime_token().map(LifetimeRef::from_token),
-                                Mutability::Shared,
-                            ),
-                            ast::SelfParamKind::MutRef => TypeRef::Reference(
-                                Box::new(self_type),
-                                self_param.lifetime_token().map(LifetimeRef::from_token),
-                                Mutability::Mut,
-                            ),
+                            ast::SelfParamKind::Ref => {
+                                TypeRef::Reference(Box::new(self_type), Mutability::Shared)
+                            }
+                            ast::SelfParamKind::MutRef => {
+                                TypeRef::Reference(Box::new(self_type), Mutability::Mut)
+                            }
                         }
                     }
                 };
@@ -634,7 +629,8 @@ impl Ctx {
                 // add super traits as bounds on Self
                 // i.e., trait Foo: Bar is equivalent to trait Foo where Self: Bar
                 let self_param = TypeRef::Path(name![Self].into());
-                generics.fill_bounds(&self.body_ctx, trait_def, Either::Left(self_param));
+                generics.fill_bounds(&self.body_ctx, trait_def, self_param);
+
                 generics.fill(&self.body_ctx, &mut sm, node);
             }
             GenericsOwner::Impl => {
diff --git a/crates/hir_def/src/lib.rs b/crates/hir_def/src/lib.rs
index 7e2199a9c7..a75d4d302f 100644
--- a/crates/hir_def/src/lib.rs
+++ b/crates/hir_def/src/lib.rs
@@ -224,13 +224,6 @@ pub struct TypeParamId {
 
 pub type LocalTypeParamId = Idx<generics::TypeParamData>;
 
-#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
-pub struct LifetimeParamId {
-    pub parent: GenericDefId,
-    pub local_id: LocalLifetimeParamId,
-}
-pub type LocalLifetimeParamId = Idx<generics::LifetimeParamData>;
-
 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
 pub enum ContainerId {
     ModuleId(ModuleId),
diff --git a/crates/hir_def/src/path.rs b/crates/hir_def/src/path.rs
index 00a69a8a63..5b8c1e449e 100644
--- a/crates/hir_def/src/path.rs
+++ b/crates/hir_def/src/path.rs
@@ -7,7 +7,7 @@ use std::{
     sync::Arc,
 };
 
-use crate::{body::LowerCtx, type_ref::LifetimeRef};
+use crate::body::LowerCtx;
 use base_db::CrateId;
 use hir_expand::{
     hygiene::Hygiene,
@@ -145,7 +145,7 @@ pub struct AssociatedTypeBinding {
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
 pub enum GenericArg {
     Type(TypeRef),
-    Lifetime(LifetimeRef),
+    // or lifetime...
 }
 
 impl Path {
diff --git a/crates/hir_def/src/path/lower.rs b/crates/hir_def/src/path/lower.rs
index 60fa7646b2..07b9723ce0 100644
--- a/crates/hir_def/src/path/lower.rs
+++ b/crates/hir_def/src/path/lower.rs
@@ -15,7 +15,7 @@ use super::AssociatedTypeBinding;
 use crate::{
     body::LowerCtx,
     path::{GenericArg, GenericArgs, ModPath, Path, PathKind},
-    type_ref::{LifetimeRef, TypeBound, TypeRef},
+    type_ref::{TypeBound, TypeRef},
 };
 
 pub(super) use lower_use::lower_use_tree;
@@ -170,14 +170,8 @@ pub(super) fn lower_generic_args(
                     bindings.push(AssociatedTypeBinding { name, type_ref, bounds });
                 }
             }
-            ast::GenericArg::LifetimeArg(lifetime_arg) => {
-                if let Some(lifetime) = lifetime_arg.lifetime_token() {
-                    let lifetime_ref = LifetimeRef::from_token(lifetime);
-                    args.push(GenericArg::Lifetime(lifetime_ref))
-                }
-            }
-            // constants are ignored for now.
-            ast::GenericArg::ConstArg(_) => (),
+            // Lifetimes and constants are ignored for now.
+            ast::GenericArg::LifetimeArg(_) | ast::GenericArg::ConstArg(_) => (),
         }
     }
 
diff --git a/crates/hir_def/src/type_ref.rs b/crates/hir_def/src/type_ref.rs
index 347ceabb9b..1a78c1444c 100644
--- a/crates/hir_def/src/type_ref.rs
+++ b/crates/hir_def/src/type_ref.rs
@@ -1,7 +1,6 @@
 //! HIR for references to types. Paths in these are not yet resolved. They can
 //! be directly created from an ast::TypeRef, without further queries.
-use hir_expand::name::Name;
-use syntax::{ast, SyntaxToken};
+use syntax::ast::{self};
 
 use crate::{body::LowerCtx, path::Path};
 
@@ -59,7 +58,7 @@ pub enum TypeRef {
     Tuple(Vec<TypeRef>),
     Path(Path),
     RawPtr(Box<TypeRef>, Mutability),
-    Reference(Box<TypeRef>, Option<LifetimeRef>, Mutability),
+    Reference(Box<TypeRef>, Mutability),
     Array(Box<TypeRef> /*, Expr*/),
     Slice(Box<TypeRef>),
     /// A fn pointer. Last element of the vector is the return type.
@@ -70,30 +69,11 @@ pub enum TypeRef {
     Error,
 }
 
-#[derive(Clone, PartialEq, Eq, Hash, Debug)]
-pub struct LifetimeRef {
-    pub name: Name,
-}
-
-impl LifetimeRef {
-    pub(crate) fn new_name(name: Name) -> Self {
-        LifetimeRef { name }
-    }
-
-    pub(crate) fn from_token(token: SyntaxToken) -> Self {
-        LifetimeRef { name: Name::new_lifetime(&token) }
-    }
-
-    pub fn missing() -> LifetimeRef {
-        LifetimeRef { name: Name::missing() }
-    }
-}
-
 #[derive(Clone, PartialEq, Eq, Hash, Debug)]
 pub enum TypeBound {
     Path(Path),
-    // ForLifetime(Vec<LifetimeRef>, Path), FIXME ForLifetime
-    Lifetime(LifetimeRef),
+    // also for<> bounds
+    // also Lifetimes
     Error,
 }
 
@@ -127,9 +107,8 @@ impl TypeRef {
             }
             ast::Type::RefType(inner) => {
                 let inner_ty = TypeRef::from_ast_opt(&ctx, inner.ty());
-                let lifetime = inner.lifetime_token().map(|t| LifetimeRef::from_token(t));
                 let mutability = Mutability::from_mutable(inner.mut_token().is_some());
-                TypeRef::Reference(Box::new(inner_ty), lifetime, mutability)
+                TypeRef::Reference(Box::new(inner_ty), mutability)
             }
             ast::Type::InferType(_inner) => TypeRef::Placeholder,
             ast::Type::FnPtrType(inner) => {
@@ -184,14 +163,14 @@ impl TypeRef {
                     types.iter().for_each(|t| go(t, f))
                 }
                 TypeRef::RawPtr(type_ref, _)
-                | TypeRef::Reference(type_ref, ..)
+                | TypeRef::Reference(type_ref, _)
                 | TypeRef::Array(type_ref)
                 | TypeRef::Slice(type_ref) => go(&type_ref, f),
                 TypeRef::ImplTrait(bounds) | TypeRef::DynTrait(bounds) => {
                     for bound in bounds {
                         match bound {
                             TypeBound::Path(path) => go_path(path, f),
-                            TypeBound::Lifetime(_) | TypeBound::Error => (),
+                            TypeBound::Error => (),
                         }
                     }
                 }
@@ -207,12 +186,8 @@ impl TypeRef {
             for segment in path.segments().iter() {
                 if let Some(args_and_bindings) = segment.args_and_bindings {
                     for arg in &args_and_bindings.args {
-                        match arg {
-                            crate::path::GenericArg::Type(type_ref) => {
-                                go(type_ref, f);
-                            }
-                            crate::path::GenericArg::Lifetime(_) => {}
-                        }
+                        let crate::path::GenericArg::Type(type_ref) = arg;
+                        go(type_ref, f);
                     }
                     for binding in &args_and_bindings.bindings {
                         if let Some(type_ref) = &binding.type_ref {
@@ -221,7 +196,7 @@ impl TypeRef {
                         for bound in &binding.bounds {
                             match bound {
                                 TypeBound::Path(path) => go_path(path, f),
-                                TypeBound::Lifetime(_) | TypeBound::Error => (),
+                                TypeBound::Error => (),
                             }
                         }
                     }
@@ -257,10 +232,7 @@ impl TypeBound {
                 };
                 TypeBound::Path(path)
             }
-            ast::TypeBoundKind::ForType(_) => TypeBound::Error, // FIXME ForType
-            ast::TypeBoundKind::Lifetime(lifetime) => {
-                TypeBound::Lifetime(LifetimeRef::from_token(lifetime))
-            }
+            ast::TypeBoundKind::ForType(_) | ast::TypeBoundKind::Lifetime(_) => TypeBound::Error,
         }
     }
 
diff --git a/crates/hir_expand/src/name.rs b/crates/hir_expand/src/name.rs
index 583ed6142b..b26ffa1ef2 100644
--- a/crates/hir_expand/src/name.rs
+++ b/crates/hir_expand/src/name.rs
@@ -38,7 +38,7 @@ impl Name {
     }
 
     pub fn new_lifetime(lt: &syntax::SyntaxToken) -> Name {
-        assert_eq!(lt.kind(), syntax::SyntaxKind::LIFETIME);
+        assert!(lt.kind() == syntax::SyntaxKind::LIFETIME);
         Name(Repr::Text(lt.text().clone()))
     }
 
@@ -250,8 +250,6 @@ pub mod known {
     pub const SELF_PARAM: super::Name = super::Name::new_inline("self");
     pub const SELF_TYPE: super::Name = super::Name::new_inline("Self");
 
-    pub const STATIC_LIFETIME: super::Name = super::Name::new_inline("'static");
-
     #[macro_export]
     macro_rules! name {
         (self) => {
@@ -260,9 +258,6 @@ pub mod known {
         (Self) => {
             $crate::name::known::SELF_TYPE
         };
-        ('static) => {
-            $crate::name::known::STATIC_LIFETIME
-        };
         ($ident:ident) => {
             $crate::name::known::$ident
         };
diff --git a/crates/hir_ty/src/diagnostics.rs b/crates/hir_ty/src/diagnostics.rs
index 1c72f766ea..e59487e544 100644
--- a/crates/hir_ty/src/diagnostics.rs
+++ b/crates/hir_ty/src/diagnostics.rs
@@ -624,14 +624,4 @@ fn foo() { break; }
 "#,
         );
     }
-
-    #[test]
-    fn missing_semicolon() {
-        check_diagnostics(
-            r#"
-                fn test() -> i32 { 123; }
-                                 //^^^ Remove this semicolon
-            "#,
-        );
-    }
 }
diff --git a/crates/hir_ty/src/display.rs b/crates/hir_ty/src/display.rs
index 0d968cc686..aa286c8c2a 100644
--- a/crates/hir_ty/src/display.rs
+++ b/crates/hir_ty/src/display.rs
@@ -4,7 +4,7 @@ use std::fmt;
 
 use crate::{
     db::HirDatabase, utils::generics, ApplicationTy, CallableDefId, FnSig, GenericPredicate,
-    Lifetime, Obligation, OpaqueTyId, ProjectionTy, Substs, TraitRef, Ty, TypeCtor,
+    Obligation, OpaqueTyId, ProjectionTy, Substs, TraitRef, Ty, TypeCtor,
 };
 use hir_def::{
     find_path, generics::TypeParamProvenance, item_scope::ItemInNs, AdtId, AssocContainerId,
@@ -178,6 +178,7 @@ impl DisplayTarget {
 #[derive(Debug)]
 pub enum DisplaySourceCodeError {
     PathNotFound,
+    UnknownType,
 }
 
 pub enum HirDisplayError {
@@ -558,7 +559,14 @@ impl HirDisplay for Ty {
                     }
                 };
             }
-            Ty::Unknown => write!(f, "{{unknown}}")?,
+            Ty::Unknown => {
+                if f.display_target.is_source_code() {
+                    return Err(HirDisplayError::DisplaySourceCodeError(
+                        DisplaySourceCodeError::UnknownType,
+                    ));
+                }
+                write!(f, "{{unknown}}")?;
+            }
             Ty::Infer(..) => write!(f, "_")?,
         }
         Ok(())
@@ -710,19 +718,6 @@ impl HirDisplay for GenericPredicate {
     }
 }
 
-impl HirDisplay for Lifetime {
-    fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
-        match self {
-            Lifetime::Parameter(id) => {
-                let generics = generics(f.db.upcast(), id.parent);
-                let param_data = &generics.params.lifetimes[id.local_id];
-                write!(f, "{}", &param_data.name)
-            }
-            Lifetime::Static => write!(f, "'static"),
-        }
-    }
-}
-
 impl HirDisplay for Obligation {
     fn hir_fmt(&self, f: &mut HirFormatter) -> Result<(), HirDisplayError> {
         match self {
diff --git a/crates/hir_ty/src/infer/expr.rs b/crates/hir_ty/src/infer/expr.rs
index ca005bc99d..605951b103 100644
--- a/crates/hir_ty/src/infer/expr.rs
+++ b/crates/hir_ty/src/infer/expr.rs
@@ -137,24 +137,10 @@ impl<'a> InferenceContext<'a> {
 
                 self.coerce_merge_branch(&then_ty, &else_ty)
             }
-            Expr::Block { statements, tail, label } => match label {
-                Some(_) => {
-                    let break_ty = self.table.new_type_var();
-                    self.breakables.push(BreakableContext {
-                        may_break: false,
-                        break_ty: break_ty.clone(),
-                        label: label.clone(),
-                    });
-                    let ty = self.infer_block(statements, *tail, &Expectation::has_type(break_ty));
-                    let ctxt = self.breakables.pop().expect("breakable stack broken");
-                    if ctxt.may_break {
-                        ctxt.break_ty
-                    } else {
-                        ty
-                    }
-                }
-                None => self.infer_block(statements, *tail, expected),
-            },
+            Expr::Block { statements, tail, .. } => {
+                // FIXME: Breakable block inference
+                self.infer_block(statements, *tail, expected)
+            }
             Expr::Unsafe { body } => self.infer_expr(*body, expected),
             Expr::TryBlock { body } => {
                 let _inner = self.infer_expr(*body, expected);
@@ -862,7 +848,6 @@ impl<'a> InferenceContext<'a> {
                         let ty = self.make_ty(type_ref);
                         substs.push(ty);
                     }
-                    GenericArg::Lifetime(_) => {}
                 }
             }
         };
diff --git a/crates/hir_ty/src/lib.rs b/crates/hir_ty/src/lib.rs
index 357bd92f99..5a8c971985 100644
--- a/crates/hir_ty/src/lib.rs
+++ b/crates/hir_ty/src/lib.rs
@@ -29,8 +29,8 @@ use base_db::{salsa, CrateId};
 use hir_def::{
     expr::ExprId,
     type_ref::{Mutability, Rawness},
-    AdtId, AssocContainerId, DefWithBodyId, GenericDefId, HasModule, LifetimeParamId, Lookup,
-    TraitId, TypeAliasId, TypeParamId,
+    AdtId, AssocContainerId, DefWithBodyId, GenericDefId, HasModule, Lookup, TraitId, TypeAliasId,
+    TypeParamId,
 };
 use itertools::Itertools;
 
@@ -52,12 +52,6 @@ pub use traits::{InEnvironment, Obligation, ProjectionPredicate, TraitEnvironmen
 
 pub use chalk_ir::{BoundVar, DebruijnIndex};
 
-#[derive(Clone, PartialEq, Eq, Debug, Hash)]
-pub enum Lifetime {
-    Parameter(LifetimeParamId),
-    Static,
-}
-
 /// A type constructor or type name: this might be something like the primitive
 /// type `bool`, a struct like `Vec`, or things like function pointers or
 /// tuples.
diff --git a/crates/hir_ty/src/lower.rs b/crates/hir_ty/src/lower.rs
index 92f779360f..708e2af0fa 100644
--- a/crates/hir_ty/src/lower.rs
+++ b/crates/hir_ty/src/lower.rs
@@ -12,7 +12,7 @@ use base_db::CrateId;
 use hir_def::{
     adt::StructKind,
     builtin_type::BuiltinType,
-    generics::{TypeParamProvenance, WherePredicate, WherePredicateTypeTarget},
+    generics::{TypeParamProvenance, WherePredicate, WherePredicateTarget},
     path::{GenericArg, Path, PathSegment, PathSegments},
     resolver::{HasResolver, Resolver, TypeNs},
     type_ref::{TypeBound, TypeRef},
@@ -171,7 +171,7 @@ impl Ty {
                 let inner_ty = Ty::from_hir(ctx, inner);
                 Ty::apply_one(TypeCtor::Slice, inner_ty)
             }
-            TypeRef::Reference(inner, _, mutability) => {
+            TypeRef::Reference(inner, mutability) => {
                 let inner_ty = Ty::from_hir(ctx, inner);
                 Ty::apply_one(TypeCtor::Ref(*mutability), inner_ty)
             }
@@ -555,7 +555,7 @@ fn substs_from_path_segment(
 
     substs.extend(iter::repeat(Ty::Unknown).take(parent_params));
 
-    let mut had_explicit_type_args = false;
+    let mut had_explicit_args = false;
 
     if let Some(generic_args) = &segment.args_and_bindings {
         if !generic_args.has_self_type {
@@ -568,11 +568,10 @@ fn substs_from_path_segment(
         for arg in generic_args.args.iter().skip(skip).take(expected_num) {
             match arg {
                 GenericArg::Type(type_ref) => {
-                    had_explicit_type_args = true;
+                    had_explicit_args = true;
                     let ty = Ty::from_hir(ctx, type_ref);
                     substs.push(ty);
                 }
-                GenericArg::Lifetime(_) => {}
             }
         }
     }
@@ -580,7 +579,7 @@ fn substs_from_path_segment(
     // handle defaults. In expression or pattern path segments without
     // explicitly specified type arguments, missing type arguments are inferred
     // (i.e. defaults aren't used).
-    if !infer_args || had_explicit_type_args {
+    if !infer_args || had_explicit_args {
         if let Some(def_generic) = def_generic {
             let defaults = ctx.db.generic_defaults(def_generic);
             assert_eq!(total_len, defaults.len());
@@ -658,7 +657,7 @@ impl TraitRef {
     ) -> Option<TraitRef> {
         match bound {
             TypeBound::Path(path) => TraitRef::from_path(ctx, path, Some(self_ty)),
-            TypeBound::Lifetime(_) | TypeBound::Error => None,
+            TypeBound::Error => None,
         }
     }
 }
@@ -668,30 +667,22 @@ impl GenericPredicate {
         ctx: &'a TyLoweringContext<'a>,
         where_predicate: &'a WherePredicate,
     ) -> impl Iterator<Item = GenericPredicate> + 'a {
-        match where_predicate {
-            WherePredicate::TypeBound { target, bound } => {
-                let self_ty = match target {
-                    WherePredicateTypeTarget::TypeRef(type_ref) => Ty::from_hir(ctx, type_ref),
-                    WherePredicateTypeTarget::TypeParam(param_id) => {
-                        let generic_def = ctx.resolver.generic_def().expect("generics in scope");
-                        let generics = generics(ctx.db.upcast(), generic_def);
-                        let param_id =
-                            hir_def::TypeParamId { parent: generic_def, local_id: *param_id };
-                        match ctx.type_param_mode {
-                            TypeParamLoweringMode::Placeholder => Ty::Placeholder(param_id),
-                            TypeParamLoweringMode::Variable => {
-                                let idx = generics.param_idx(param_id).expect("matching generics");
-                                Ty::Bound(BoundVar::new(DebruijnIndex::INNERMOST, idx))
-                            }
-                        }
+        let self_ty = match &where_predicate.target {
+            WherePredicateTarget::TypeRef(type_ref) => Ty::from_hir(ctx, type_ref),
+            WherePredicateTarget::TypeParam(param_id) => {
+                let generic_def = ctx.resolver.generic_def().expect("generics in scope");
+                let generics = generics(ctx.db.upcast(), generic_def);
+                let param_id = hir_def::TypeParamId { parent: generic_def, local_id: *param_id };
+                match ctx.type_param_mode {
+                    TypeParamLoweringMode::Placeholder => Ty::Placeholder(param_id),
+                    TypeParamLoweringMode::Variable => {
+                        let idx = generics.param_idx(param_id).expect("matching generics");
+                        Ty::Bound(BoundVar::new(DebruijnIndex::INNERMOST, idx))
                     }
-                };
-                GenericPredicate::from_type_bound(ctx, bound, self_ty)
-                    .collect::<Vec<_>>()
-                    .into_iter()
+                }
             }
-            WherePredicate::Lifetime { .. } => vec![].into_iter(),
-        }
+        };
+        GenericPredicate::from_type_bound(ctx, &where_predicate.bound, self_ty)
     }
 
     pub(crate) fn from_type_bound<'a>(
@@ -716,7 +707,7 @@ fn assoc_type_bindings_from_type_bound<'a>(
 ) -> impl Iterator<Item = GenericPredicate> + 'a {
     let last_segment = match bound {
         TypeBound::Path(path) => path.segments().last(),
-        TypeBound::Error | TypeBound::Lifetime(_) => None,
+        TypeBound::Error => None,
     };
     last_segment
         .into_iter()
@@ -881,16 +872,11 @@ pub(crate) fn generic_predicates_for_param_query(
     resolver
         .where_predicates_in_scope()
         // we have to filter out all other predicates *first*, before attempting to lower them
-        .filter(|pred| match pred {
-            WherePredicate::TypeBound {
-                target: WherePredicateTypeTarget::TypeRef(type_ref),
-                ..
-            } => Ty::from_hir_only_param(&ctx, type_ref) == Some(param_id),
-            WherePredicate::TypeBound {
-                target: WherePredicateTypeTarget::TypeParam(local_id),
-                ..
-            } => *local_id == param_id.local_id,
-            WherePredicate::Lifetime { .. } => false,
+        .filter(|pred| match &pred.target {
+            WherePredicateTarget::TypeRef(type_ref) => {
+                Ty::from_hir_only_param(&ctx, type_ref) == Some(param_id)
+            }
+            WherePredicateTarget::TypeParam(local_id) => *local_id == param_id.local_id,
         })
         .flat_map(|pred| {
             GenericPredicate::from_where_predicate(&ctx, pred)
diff --git a/crates/hir_ty/src/utils.rs b/crates/hir_ty/src/utils.rs
index af880c0658..e3e2442680 100644
--- a/crates/hir_ty/src/utils.rs
+++ b/crates/hir_ty/src/utils.rs
@@ -2,10 +2,11 @@
 //! query, but can't be computed directly from `*Data` (ie, which need a `db`).
 use std::sync::Arc;
 
+use hir_def::generics::WherePredicateTarget;
 use hir_def::{
     adt::VariantData,
     db::DefDatabase,
-    generics::{GenericParams, TypeParamData, TypeParamProvenance, WherePredicateTypeTarget},
+    generics::{GenericParams, TypeParamData, TypeParamProvenance},
     path::Path,
     resolver::{HasResolver, TypeNs},
     type_ref::TypeRef,
@@ -26,19 +27,14 @@ fn direct_super_traits(db: &dyn DefDatabase, trait_: TraitId) -> Vec<TraitId> {
     generic_params
         .where_predicates
         .iter()
-        .filter_map(|pred| match pred {
-            hir_def::generics::WherePredicate::TypeBound { target, bound } => match target {
-                WherePredicateTypeTarget::TypeRef(TypeRef::Path(p))
-                    if p == &Path::from(name![Self]) =>
-                {
-                    bound.as_path()
-                }
-                WherePredicateTypeTarget::TypeParam(local_id) if Some(*local_id) == trait_self => {
-                    bound.as_path()
-                }
-                _ => None,
-            },
-            hir_def::generics::WherePredicate::Lifetime { .. } => None,
+        .filter_map(|pred| match &pred.target {
+            WherePredicateTarget::TypeRef(TypeRef::Path(p)) if p == &Path::from(name![Self]) => {
+                pred.bound.as_path()
+            }
+            WherePredicateTarget::TypeParam(local_id) if Some(*local_id) == trait_self => {
+                pred.bound.as_path()
+            }
+            _ => None,
         })
         .filter_map(|path| match resolver.resolve_path_in_type_ns_fully(db, path.mod_path()) {
             Some(TypeNs::TraitId(t)) => Some(t),
diff --git a/crates/ide/src/display/navigation_target.rs b/crates/ide/src/display/navigation_target.rs
index 234f80a3a5..4790d648a8 100644
--- a/crates/ide/src/display/navigation_target.rs
+++ b/crates/ide/src/display/navigation_target.rs
@@ -1,13 +1,11 @@
 //! FIXME: write short doc here
 
 use either::Either;
-use hir::{
-    AssocItem, Documentation, FieldSource, HasAttrs, HasSource, HirFileId, InFile, ModuleSource,
-};
+use hir::{AssocItem, FieldSource, HasSource, InFile, ModuleSource};
 use ide_db::base_db::{FileId, SourceDatabase};
 use ide_db::{defs::Definition, RootDatabase};
 use syntax::{
-    ast::{self, NameOwner},
+    ast::{self, DocCommentsOwner, NameOwner},
     match_ast, AstNode, SmolStr,
     SyntaxKind::{self, IDENT_PAT, TYPE_PARAM},
     TextRange,
@@ -45,7 +43,7 @@ pub struct NavigationTarget {
     pub kind: SyntaxKind,
     pub container_name: Option<SmolStr>,
     pub description: Option<String>,
-    pub docs: Option<Documentation>,
+    pub docs: Option<String>,
 }
 
 pub(crate) trait ToNav {
@@ -73,7 +71,7 @@ impl NavigationTarget {
                 frange.range,
                 src.value.syntax().kind(),
             );
-            res.docs = module.attrs(db).docs();
+            res.docs = src.value.doc_comment_text();
             res.description = src.value.short_label();
             return res;
         }
@@ -216,14 +214,14 @@ impl ToNavFromAst for hir::Trait {}
 
 impl<D> ToNav for D
 where
-    D: HasSource + ToNavFromAst + Copy + HasAttrs,
-    D::Ast: ast::NameOwner + ShortLabel,
+    D: HasSource + ToNavFromAst + Copy,
+    D::Ast: ast::DocCommentsOwner + ast::NameOwner + ShortLabel,
 {
     fn to_nav(&self, db: &RootDatabase) -> NavigationTarget {
         let src = self.source(db);
         let mut res =
             NavigationTarget::from_named(db, src.as_ref().map(|it| it as &dyn ast::NameOwner));
-        res.docs = self.docs(db);
+        res.docs = src.value.doc_comment_text();
         res.description = src.value.short_label();
         res
     }
@@ -276,7 +274,7 @@ impl ToNav for hir::Field {
         match &src.value {
             FieldSource::Named(it) => {
                 let mut res = NavigationTarget::from_named(db, src.with_value(it));
-                res.docs = self.docs(db);
+                res.docs = it.doc_comment_text();
                 res.description = it.short_label();
                 res
             }
@@ -300,7 +298,7 @@ impl ToNav for hir::MacroDef {
         log::debug!("nav target {:#?}", src.value.syntax());
         let mut res =
             NavigationTarget::from_named(db, src.as_ref().map(|it| it as &dyn ast::NameOwner));
-        res.docs = self.docs(db);
+        res.docs = src.value.doc_comment_text();
         res
     }
 }
@@ -376,28 +374,26 @@ impl ToNav for hir::TypeParam {
     }
 }
 
-pub(crate) fn docs_from_symbol(db: &RootDatabase, symbol: &FileSymbol) -> Option<Documentation> {
+pub(crate) fn docs_from_symbol(db: &RootDatabase, symbol: &FileSymbol) -> Option<String> {
     let parse = db.parse(symbol.file_id);
     let node = symbol.ptr.to_node(parse.tree().syntax());
-    let file_id = HirFileId::from(symbol.file_id);
 
-    let it = match_ast! {
+    match_ast! {
         match node {
-            ast::Fn(it) => hir::Attrs::from_attrs_owner(db, InFile::new(file_id, &it)),
-            ast::Struct(it) => hir::Attrs::from_attrs_owner(db, InFile::new(file_id, &it)),
-            ast::Enum(it) => hir::Attrs::from_attrs_owner(db, InFile::new(file_id, &it)),
-            ast::Trait(it) => hir::Attrs::from_attrs_owner(db, InFile::new(file_id, &it)),
-            ast::Module(it) => hir::Attrs::from_attrs_owner(db, InFile::new(file_id, &it)),
-            ast::TypeAlias(it) => hir::Attrs::from_attrs_owner(db, InFile::new(file_id, &it)),
-            ast::Const(it) => hir::Attrs::from_attrs_owner(db, InFile::new(file_id, &it)),
-            ast::Static(it) => hir::Attrs::from_attrs_owner(db, InFile::new(file_id, &it)),
-            ast::RecordField(it) => hir::Attrs::from_attrs_owner(db, InFile::new(file_id, &it)),
-            ast::Variant(it) => hir::Attrs::from_attrs_owner(db, InFile::new(file_id, &it)),
-            ast::MacroCall(it) => hir::Attrs::from_attrs_owner(db, InFile::new(file_id, &it)),
-            _ => return None,
+            ast::Fn(it) => it.doc_comment_text(),
+            ast::Struct(it) => it.doc_comment_text(),
+            ast::Enum(it) => it.doc_comment_text(),
+            ast::Trait(it) => it.doc_comment_text(),
+            ast::Module(it) => it.doc_comment_text(),
+            ast::TypeAlias(it) => it.doc_comment_text(),
+            ast::Const(it) => it.doc_comment_text(),
+            ast::Static(it) => it.doc_comment_text(),
+            ast::RecordField(it) => it.doc_comment_text(),
+            ast::Variant(it) => it.doc_comment_text(),
+            ast::MacroCall(it) => it.doc_comment_text(),
+            _ => None,
         }
-    };
-    it.docs()
+    }
 }
 
 /// Get a description of a symbol.
diff --git a/crates/mbe/src/mbe_expander/matcher.rs b/crates/mbe/src/mbe_expander/matcher.rs
index 93ee779086..3f84458977 100644
--- a/crates/mbe/src/mbe_expander/matcher.rs
+++ b/crates/mbe/src/mbe_expander/matcher.rs
@@ -356,18 +356,6 @@ impl<'a> TtIter<'a> {
             ExpandResult { value: _, err: Some(_) } => None,
         }
     }
-
-    pub(crate) fn eat_char(&mut self, c: char) -> Option<tt::TokenTree> {
-        let mut fork = self.clone();
-        match fork.expect_char(c) {
-            Ok(_) => {
-                let tt = self.next().cloned();
-                *self = fork;
-                tt
-            }
-            Err(_) => None,
-        }
-    }
 }
 
 pub(super) fn match_repeat(
@@ -459,22 +447,10 @@ fn match_meta_var(kind: &str, input: &mut TtIter) -> ExpandResult<Option<Fragmen
                     .expect_lifetime()
                     .map(|tt| Some(tt))
                     .map_err(|()| err!("expected lifetime")),
-                "literal" => {
-                    let neg = input.eat_char('-');
-                    input
-                        .expect_literal()
-                        .map(|literal| {
-                            let lit = tt::Leaf::from(literal.clone());
-                            match neg {
-                                None => Some(lit.into()),
-                                Some(neg) => Some(tt::TokenTree::Subtree(tt::Subtree {
-                                    delimiter: None,
-                                    token_trees: vec![neg, lit.into()],
-                                })),
-                            }
-                        })
-                        .map_err(|()| err!())
-                }
+                "literal" => input
+                    .expect_literal()
+                    .map(|literal| Some(tt::Leaf::from(literal.clone()).into()))
+                    .map_err(|()| err!()),
                 // `vis` is optional
                 "vis" => match input.eat_vis() {
                     Some(vis) => Ok(Some(vis)),
diff --git a/crates/project_model/src/workspace.rs b/crates/project_model/src/workspace.rs
index 68a235ce3c..7f4a7e56b3 100644
--- a/crates/project_model/src/workspace.rs
+++ b/crates/project_model/src/workspace.rs
@@ -475,7 +475,7 @@ fn add_target_crate_root(
         Some(display_name),
         cfg_options,
         env,
-        proc_macro,
+        proc_macro.clone(),
     );
 
     crate_id
diff --git a/crates/rust-analyzer/src/main_loop.rs b/crates/rust-analyzer/src/main_loop.rs
index ec3d5e0600..a5f7647b80 100644
--- a/crates/rust-analyzer/src/main_loop.rs
+++ b/crates/rust-analyzer/src/main_loop.rs
@@ -658,6 +658,7 @@ impl GlobalState {
         log::trace!("updating notifications for {:?}", subscriptions);
         if self.config.publish_diagnostics {
             let snapshot = self.snapshot();
+            let subscriptions = subscriptions.clone();
             self.task_pool.handle.spawn(move || {
                 let diagnostics = subscriptions
                     .into_iter()
diff --git a/crates/syntax/src/ast/node_ext.rs b/crates/syntax/src/ast/node_ext.rs
index 820af2d20b..aa3a4b6065 100644
--- a/crates/syntax/src/ast/node_ext.rs
+++ b/crates/syntax/src/ast/node_ext.rs
@@ -55,7 +55,7 @@ impl ast::Attr {
         let key = self.simple_name()?;
         let value_token = lit.syntax().first_token()?;
 
-        let value: SmolStr = ast::String::cast(value_token)?.value()?.into();
+        let value: SmolStr = ast::String::cast(value_token.clone())?.value()?.into();
 
         Some((key, value))
     }
diff --git a/crates/syntax/src/ast/token_ext.rs b/crates/syntax/src/ast/token_ext.rs
index 5e9620a40d..52b7285dde 100644
--- a/crates/syntax/src/ast/token_ext.rs
+++ b/crates/syntax/src/ast/token_ext.rs
@@ -599,7 +599,7 @@ impl ast::IntNumber {
         text = &text[radix.prefix_len()..];
 
         let buf;
-        if text.contains('_') {
+        if text.contains("_") {
             buf = text.replace('_', "");
             text = buf.as_str();
         };
diff --git a/xtask/src/codegen/gen_assists_docs.rs b/xtask/src/codegen/gen_assists_docs.rs
index be218dea15..d7c85ebe9f 100644
--- a/xtask/src/codegen/gen_assists_docs.rs
+++ b/xtask/src/codegen/gen_assists_docs.rs
@@ -134,7 +134,7 @@ r#####"
 
         buf.push_str(&test)
     }
-    let buf = reformat(&buf)?;
+    let buf = reformat(&buf.to_string())?;
     codegen::update(&project_root().join("crates/assists/src/tests/generated.rs"), &buf, mode)
 }
 


Test patch:
diff --git a/crates/hir_ty/src/tests/simple.rs b/crates/hir_ty/src/tests/simple.rs
index a569223b4b..4f72582b6b 100644
--- a/crates/hir_ty/src/tests/simple.rs
+++ b/crates/hir_ty/src/tests/simple.rs
@@ -2074,62 +2074,6 @@ fn infer_labelled_break_with_val() {
     );
 }
 
-#[test]
-fn infer_labelled_block_break_with_val() {
-    check_infer(
-        r#"
-        fn default<T>() -> T { loop {} }
-        fn foo() {
-            let _x = 'outer: {
-                let inner = 'inner: {
-                    let i = default();
-                    if (break 'outer i) {
-                        break 'inner 5i8;
-                    } else if true {
-                        break 'inner 6;
-                    }
-                    break 'inner 'innermost: { 0 };
-                    42
-                };
-                break 'outer inner < 8;
-            };
-        }
-        "#,
-        expect![[r#"
-            21..32 '{ loop {} }': T
-            23..30 'loop {}': !
-            28..30 '{}': ()
-            42..381 '{     ...  }; }': ()
-            52..54 '_x': bool
-            65..378 '{     ...     }': bool
-            79..84 'inner': i8
-            95..339 '{     ...     }': i8
-            113..114 'i': bool
-            117..124 'default': fn default<bool>() -> bool
-            117..126 'default()': bool
-            140..270 'if (br...     }': ()
-            144..158 'break 'outer i': !
-            157..158 'i': bool
-            160..209 '{     ...     }': ()
-            178..194 'break ...er 5i8': !
-            191..194 '5i8': i8
-            215..270 'if tru...     }': ()
-            218..222 'true': bool
-            223..270 '{     ...     }': ()
-            241..255 'break 'inner 6': !
-            254..255 '6': i8
-            283..313 'break ... { 0 }': !
-            308..313 '{ 0 }': i8
-            310..311 '0': i8
-            327..329 '42': i8
-            349..371 'break ...er < 8': !
-            362..367 'inner': i8
-            362..371 'inner < 8': bool
-            370..371 '8': i8
-        "#]],
-    );
-}
-
 #[test]
 fn generic_default() {
     check_infer(
diff --git a/crates/mbe/src/tests.rs b/crates/mbe/src/tests.rs
index 843054fe85..0796ceee1a 100644
--- a/crates/mbe/src/tests.rs
+++ b/crates/mbe/src/tests.rs
@@ -1008,20 +1008,11 @@ fn test_literal() {
     parse_macro(
         r#"
         macro_rules! foo {
-              ($ type:ty , $ lit:literal) => { const VALUE: $ type = $ lit;};
+              ($ type:ty $ lit:literal) => { const VALUE: $ type = $ lit;};
         }
 "#,
     )
-    .assert_expand_items(r#"foo!(u8,0);"#, r#"const VALUE : u8 = 0 ;"#);
-
-    parse_macro(
-        r#"
-        macro_rules! foo {
-              ($ type:ty , $ lit:literal) => { const VALUE: $ type = $ lit;};
-        }
-"#,
-    )
-    .assert_expand_items(r#"foo!(i32,-1);"#, r#"const VALUE : i32 = - 1 ;"#);
+    .assert_expand_items(r#"foo!(u8 0);"#, r#"const VALUE : u8 = 0 ;"#);
 }
 
 #[test]