Repository: rust-analyzer/rust-analyzer
Pull request #7029 (2020-12-24 13:40:09)

Flush stdout when clearing the progress bar
To prevent this from happening:

```
Database loaded 496.24ms, 288mi
Crates in this dir: 1
Total modules found: 14
Total declarations: 159
Total functions: 122
Item Collection: 6.02s, 61846mi
122/122 100% processing: archive::sizeTotal expressions: 6592       
Expressions of unknown type: 4 (0%)
Expressions of partially unknown type: 104 (1%)
Type mismatches: 3
Inference: 1.03s, 8622mi
Total: 7.05s, 70468mi
```


Patch:
diff --git a/crates/hir/src/code_model.rs b/crates/hir/src/code_model.rs
index b7ded34788..1d7e5ddd7f 100644
--- a/crates/hir/src/code_model.rs
+++ b/crates/hir/src/code_model.rs
@@ -9,7 +9,7 @@ use hir_def::{
     adt::StructKind,
     adt::VariantData,
     builtin_type::BuiltinType,
-    expr::{BindingAnnotation, LabelId, Pat, PatId},
+    expr::{BindingAnnotation, Pat, PatId},
     import_map,
     item_tree::ItemTreeNode,
     lang_item::LangItemTarget,
@@ -374,6 +374,8 @@ impl Module {
         let crate_def_map = db.crate_def_map(self.id.krate);
         crate_def_map.add_diagnostics(db.upcast(), self.id.local_id, sink);
         for decl in self.declarations(db) {
+            decl.diagnostics(db, sink);
+
             match decl {
                 crate::ModuleDef::Function(f) => f.diagnostics(db, sink),
                 crate::ModuleDef::Module(m) => {
@@ -382,9 +384,7 @@ impl Module {
                         m.diagnostics(db, sink)
                     }
                 }
-                _ => {
-                    decl.diagnostics(db, sink);
-                }
+                _ => (),
             }
         }
 
@@ -1205,34 +1205,6 @@ impl Local {
     }
 }
 
-#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
-pub struct Label {
-    pub(crate) parent: DefWithBodyId,
-    pub(crate) label_id: LabelId,
-}
-
-impl Label {
-    pub fn module(self, db: &dyn HirDatabase) -> Module {
-        self.parent(db).module(db)
-    }
-
-    pub fn parent(self, _db: &dyn HirDatabase) -> DefWithBody {
-        self.parent.into()
-    }
-
-    pub fn name(self, db: &dyn HirDatabase) -> Name {
-        let body = db.body(self.parent.into());
-        body[self.label_id].name.clone()
-    }
-
-    pub fn source(self, db: &dyn HirDatabase) -> InFile<ast::Label> {
-        let (_body, source_map) = db.body_with_source_map(self.parent.into());
-        let src = source_map.label_syntax(self.label_id);
-        let root = src.file_syntax(db.upcast());
-        src.map(|ast| ast.to_node(&root))
-    }
-}
-
 #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
 pub enum GenericParam {
     TypeParam(TypeParam),
diff --git a/crates/hir/src/from_id.rs b/crates/hir/src/from_id.rs
index a0792b9a66..8e0c571b85 100644
--- a/crates/hir/src/from_id.rs
+++ b/crates/hir/src/from_id.rs
@@ -4,15 +4,12 @@
 //! are splitting the hir.
 
 use hir_def::{
-    expr::{LabelId, PatId},
-    item_scope::ItemInNs,
-    AdtId, AssocItemId, DefWithBodyId, EnumVariantId, FieldId, GenericDefId, ModuleDefId,
-    VariantId,
+    expr::PatId, item_scope::ItemInNs, AdtId, AssocItemId, DefWithBodyId, EnumVariantId, FieldId,
+    GenericDefId, ModuleDefId, VariantId,
 };
 
 use crate::{
-    Adt, AssocItem, DefWithBody, Field, GenericDef, Label, Local, MacroDef, ModuleDef, Variant,
-    VariantDef,
+    Adt, AssocItem, DefWithBody, Field, GenericDef, Local, MacroDef, ModuleDef, Variant, VariantDef,
 };
 
 macro_rules! from_id {
@@ -231,12 +228,6 @@ impl From<(DefWithBodyId, PatId)> for Local {
     }
 }
 
-impl From<(DefWithBodyId, LabelId)> for Label {
-    fn from((parent, label_id): (DefWithBodyId, LabelId)) -> Self {
-        Label { parent, label_id }
-    }
-}
-
 impl From<MacroDef> for ItemInNs {
     fn from(macro_def: MacroDef) -> Self {
         ItemInNs::Macros(macro_def.into())
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs
index 7ac9fd5079..bdd270c58d 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, Field, FieldSource, Function, GenericDef,
-        HasVisibility, Impl, Label, LifetimeParam, Local, MacroDef, Module, ModuleDef, ScopeDef,
-        Static, Struct, Trait, Type, TypeAlias, TypeParam, Union, Variant, VariantDef,
+        HasVisibility, Impl, LifetimeParam, Local, MacroDef, Module, ModuleDef, ScopeDef, Static,
+        Struct, Trait, Type, TypeAlias, TypeParam, Union, Variant, VariantDef,
     },
     has_source::HasSource,
     semantics::{PathResolution, Semantics, SemanticsScope},
diff --git a/crates/hir/src/semantics.rs b/crates/hir/src/semantics.rs
index 67cd16e311..25ebf73d88 100644
--- a/crates/hir/src/semantics.rs
+++ b/crates/hir/src/semantics.rs
@@ -15,7 +15,7 @@ use itertools::Itertools;
 use rustc_hash::{FxHashMap, FxHashSet};
 use syntax::{
     algo::find_node_at_offset,
-    ast::{self, GenericParamsOwner, LoopBodyOwner},
+    ast::{self, GenericParamsOwner},
     match_ast, AstNode, SyntaxNode, SyntaxToken, TextSize,
 };
 
@@ -25,8 +25,8 @@ use crate::{
     diagnostics::Diagnostic,
     semantics::source_to_def::{ChildContainer, SourceToDefCache, SourceToDefCtx},
     source_analyzer::{resolve_hir_path, SourceAnalyzer},
-    AssocItem, Callable, Crate, Field, Function, HirFileId, Impl, InFile, Label, LifetimeParam,
-    Local, MacroDef, Module, ModuleDef, Name, Path, ScopeDef, Trait, Type, TypeAlias, TypeParam,
+    AssocItem, Callable, Crate, Field, Function, HirFileId, Impl, InFile, LifetimeParam, Local,
+    MacroDef, Module, ModuleDef, Name, Path, ScopeDef, Trait, Type, TypeAlias, TypeParam,
     VariantDef,
 };
 
@@ -182,10 +182,6 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> {
         self.imp.resolve_lifetime_param(lifetime)
     }
 
-    pub fn resolve_label(&self, lifetime: &ast::Lifetime) -> Option<Label> {
-        self.imp.resolve_label(lifetime)
-    }
-
     pub fn type_of_expr(&self, expr: &ast::Expr) -> Option<Type> {
         self.imp.type_of_expr(expr)
     }
@@ -429,28 +425,6 @@ impl<'db> SemanticsImpl<'db> {
         ToDef::to_def(self, src)
     }
 
-    fn resolve_label(&self, lifetime: &ast::Lifetime) -> Option<Label> {
-        let text = lifetime.text();
-        let label = lifetime.syntax().ancestors().find_map(|syn| {
-            let label = match_ast! {
-                match syn {
-                    ast::ForExpr(it) => it.label(),
-                    ast::WhileExpr(it) => it.label(),
-                    ast::LoopExpr(it) => it.label(),
-                    ast::EffectExpr(it) => it.label(),
-                    _ => None,
-                }
-            };
-            label.filter(|l| {
-                l.lifetime()
-                    .and_then(|lt| lt.lifetime_ident_token())
-                    .map_or(false, |lt| lt.text() == text)
-            })
-        })?;
-        let src = self.find_file(label.syntax().clone()).with_value(label);
-        ToDef::to_def(self, src)
-    }
-
     fn type_of_expr(&self, expr: &ast::Expr) -> Option<Type> {
         self.analyze(expr.syntax()).type_of_expr(self.db, expr)
     }
@@ -746,7 +720,6 @@ to_def_impls![
     (crate::LifetimeParam, ast::LifetimeParam, lifetime_param_to_def),
     (crate::MacroDef, ast::MacroRules, macro_rules_to_def),
     (crate::Local, ast::IdentPat, bind_pat_to_def),
-    (crate::Label, ast::Label, label_to_def),
 ];
 
 fn find_root(node: &SyntaxNode) -> SyntaxNode {
diff --git a/crates/hir/src/semantics/source_to_def.rs b/crates/hir/src/semantics/source_to_def.rs
index 424e6e8a94..3efca5baa5 100644
--- a/crates/hir/src/semantics/source_to_def.rs
+++ b/crates/hir/src/semantics/source_to_def.rs
@@ -4,7 +4,7 @@ use base_db::FileId;
 use hir_def::{
     child_by_source::ChildBySource,
     dyn_map::DynMap,
-    expr::{LabelId, PatId},
+    expr::PatId,
     keys::{self, Key},
     ConstId, DefWithBodyId, EnumId, EnumVariantId, FieldId, FunctionId, GenericDefId, ImplId,
     LifetimeParamId, ModuleId, StaticId, StructId, TraitId, TypeAliasId, TypeParamId, UnionId,
@@ -108,21 +108,12 @@ impl SourceToDefCtx<'_, '_> {
         &mut self,
         src: InFile<ast::IdentPat>,
     ) -> Option<(DefWithBodyId, PatId)> {
-        let container = self.find_pat_or_label_container(src.as_ref().map(|it| it.syntax()))?;
+        let container = self.find_pat_container(src.as_ref().map(|it| it.syntax()))?;
         let (_body, source_map) = self.db.body_with_source_map(container);
         let src = src.map(ast::Pat::from);
         let pat_id = source_map.node_pat(src.as_ref())?;
         Some((container, pat_id))
     }
-    pub(super) fn label_to_def(
-        &mut self,
-        src: InFile<ast::Label>,
-    ) -> Option<(DefWithBodyId, LabelId)> {
-        let container = self.find_pat_or_label_container(src.as_ref().map(|it| it.syntax()))?;
-        let (_body, source_map) = self.db.body_with_source_map(container);
-        let label_id = source_map.node_label(src.as_ref())?;
-        Some((container, label_id))
-    }
 
     fn to_def<Ast: AstNode + 'static, ID: Copy + 'static>(
         &mut self,
@@ -246,7 +237,7 @@ impl SourceToDefCtx<'_, '_> {
         None
     }
 
-    fn find_pat_or_label_container(&mut self, src: InFile<&SyntaxNode>) -> Option<DefWithBodyId> {
+    fn find_pat_container(&mut self, src: InFile<&SyntaxNode>) -> Option<DefWithBodyId> {
         for container in src.cloned().ancestors_with_macros(self.db.upcast()).skip(1) {
             let res: DefWithBodyId = match_ast! {
                 match (container.value) {
diff --git a/crates/hir_def/src/body.rs b/crates/hir_def/src/body.rs
index d07004b9d7..998b826010 100644
--- a/crates/hir_def/src/body.rs
+++ b/crates/hir_def/src/body.rs
@@ -26,7 +26,7 @@ pub(crate) use lower::LowerCtx;
 use crate::{
     attr::{Attrs, RawAttrs},
     db::DefDatabase,
-    expr::{Expr, ExprId, Label, LabelId, Pat, PatId},
+    expr::{Expr, ExprId, Pat, PatId},
     item_scope::BuiltinShadowMode,
     item_scope::ItemScope,
     nameres::CrateDefMap,
@@ -226,7 +226,6 @@ pub(crate) struct Mark {
 pub struct Body {
     pub exprs: Arena<Expr>,
     pub pats: Arena<Pat>,
-    pub labels: Arena<Label>,
     /// The patterns for the function's parameters. While the parameter types are
     /// part of the function signature, the patterns are not (they don't change
     /// the external type of the function).
@@ -245,8 +244,6 @@ pub type ExprSource = InFile<ExprPtr>;
 pub type PatPtr = Either<AstPtr<ast::Pat>, AstPtr<ast::SelfParam>>;
 pub type PatSource = InFile<PatPtr>;
 
-pub type LabelPtr = AstPtr<ast::Label>;
-pub type LabelSource = InFile<LabelPtr>;
 /// An item body together with the mapping from syntax nodes to HIR expression
 /// IDs. This is needed to go from e.g. a position in a file to the HIR
 /// expression containing it; but for type inference etc., we want to operate on
@@ -264,8 +261,6 @@ pub struct BodySourceMap {
     expr_map_back: ArenaMap<ExprId, Result<ExprSource, SyntheticSyntax>>,
     pat_map: FxHashMap<PatSource, PatId>,
     pat_map_back: ArenaMap<PatId, Result<PatSource, SyntheticSyntax>>,
-    label_map: FxHashMap<LabelSource, LabelId>,
-    label_map_back: ArenaMap<LabelId, LabelSource>,
     field_map: FxHashMap<(ExprId, usize), InFile<AstPtr<ast::RecordExprField>>>,
     expansions: FxHashMap<InFile<AstPtr<ast::MacroCall>>, HirFileId>,
 
@@ -339,14 +334,6 @@ impl Index<PatId> for Body {
     }
 }
 
-impl Index<LabelId> for Body {
-    type Output = Label;
-
-    fn index(&self, label: LabelId) -> &Label {
-        &self.labels[label]
-    }
-}
-
 impl BodySourceMap {
     pub fn expr_syntax(&self, expr: ExprId) -> Result<ExprSource, SyntheticSyntax> {
         self.expr_map_back[expr].clone()
@@ -376,15 +363,6 @@ impl BodySourceMap {
         self.pat_map.get(&src).cloned()
     }
 
-    pub fn label_syntax(&self, label: LabelId) -> LabelSource {
-        self.label_map_back[label].clone()
-    }
-
-    pub fn node_label(&self, node: InFile<&ast::Label>) -> Option<LabelId> {
-        let src = node.map(|it| AstPtr::new(it));
-        self.label_map.get(&src).cloned()
-    }
-
     pub fn field_syntax(&self, expr: ExprId, field: usize) -> InFile<AstPtr<ast::RecordExprField>> {
         self.field_map[&(expr, field)].clone()
     }
diff --git a/crates/hir_def/src/body/lower.rs b/crates/hir_def/src/body/lower.rs
index 17c72779ba..978c3a3249 100644
--- a/crates/hir_def/src/body/lower.rs
+++ b/crates/hir_def/src/body/lower.rs
@@ -22,14 +22,13 @@ use test_utils::mark;
 
 use crate::{
     adt::StructKind,
-    body::{Body, BodySourceMap, Expander, LabelSource, PatPtr, SyntheticSyntax},
+    body::{Body, BodySourceMap, Expander, PatPtr, SyntheticSyntax},
     builtin_type::{BuiltinFloat, BuiltinInt},
     db::DefDatabase,
     diagnostics::{InactiveCode, MacroError, UnresolvedProcMacro},
     expr::{
-        dummy_expr_id, ArithOp, Array, BinaryOp, BindingAnnotation, CmpOp, Expr, ExprId, Label,
-        LabelId, Literal, LogicOp, MatchArm, Ordering, Pat, PatId, RecordFieldPat, RecordLitField,
-        Statement,
+        dummy_expr_id, ArithOp, Array, BinaryOp, BindingAnnotation, CmpOp, Expr, ExprId, Literal,
+        LogicOp, MatchArm, Ordering, Pat, PatId, RecordFieldPat, RecordLitField, Statement,
     },
     item_scope::BuiltinShadowMode,
     item_tree::{ItemTree, ItemTreeId, ItemTreeNode},
@@ -73,7 +72,6 @@ pub(super) fn lower(
         body: Body {
             exprs: Arena::default(),
             pats: Arena::default(),
-            labels: Arena::default(),
             params: Vec::new(),
             body_expr: dummy_expr_id(),
             item_scope: Default::default(),
@@ -177,18 +175,6 @@ impl ExprCollector<'_> {
         id
     }
 
-    fn alloc_label(&mut self, label: Label, ptr: AstPtr<ast::Label>) -> LabelId {
-        let src = self.expander.to_source(ptr);
-        let id = self.make_label(label, src.clone());
-        self.source_map.label_map.insert(src, id);
-        id
-    }
-    fn make_label(&mut self, label: Label, src: LabelSource) -> LabelId {
-        let id = self.body.labels.alloc(label);
-        self.source_map.label_map_back.insert(id, src);
-        id
-    }
-
     fn collect_expr(&mut self, expr: ast::Expr) -> ExprId {
         let syntax_ptr = AstPtr::new(&expr);
         if self.check_cfg(&expr).is_none() {
@@ -242,40 +228,37 @@ impl ExprCollector<'_> {
                     self.alloc_expr(Expr::Unsafe { body }, syntax_ptr)
                 }
                 // FIXME: we need to record these effects somewhere...
-                ast::Effect::Label(label) => {
-                    let label = self.collect_label(label);
-                    match e.block_expr() {
-                        Some(block) => {
-                            let res = self.collect_block(block);
-                            match &mut self.body.exprs[res] {
-                                Expr::Block { label: block_label, .. } => {
-                                    *block_label = Some(label);
-                                }
-                                _ => unreachable!(),
+                ast::Effect::Label(label) => match e.block_expr() {
+                    Some(block) => {
+                        let res = self.collect_block(block);
+                        match &mut self.body.exprs[res] {
+                            Expr::Block { label: block_label, .. } => {
+                                *block_label = label.lifetime().map(|t| Name::new_lifetime(&t))
                             }
-                            res
+                            _ => unreachable!(),
                         }
-                        None => self.missing_expr(),
+                        res
                     }
-                }
+                    None => self.missing_expr(),
+                },
                 // FIXME: we need to record these effects somewhere...
                 ast::Effect::Async(_) => {
                     let body = self.collect_block_opt(e.block_expr());
                     self.alloc_expr(Expr::Async { body }, syntax_ptr)
                 }
-                ast::Effect::Const(_) => {
-                    let body = self.collect_block_opt(e.block_expr());
-                    self.alloc_expr(Expr::Const { body }, syntax_ptr)
-                }
             },
             ast::Expr::BlockExpr(e) => self.collect_block(e),
             ast::Expr::LoopExpr(e) => {
-                let label = e.label().map(|label| self.collect_label(label));
                 let body = self.collect_block_opt(e.loop_body());
-                self.alloc_expr(Expr::Loop { body, label }, syntax_ptr)
+                self.alloc_expr(
+                    Expr::Loop {
+                        body,
+                        label: e.label().and_then(|l| l.lifetime()).map(|l| Name::new_lifetime(&l)),
+                    },
+                    syntax_ptr,
+                )
             }
             ast::Expr::WhileExpr(e) => {
-                let label = e.label().map(|label| self.collect_label(label));
                 let body = self.collect_block_opt(e.loop_body());
 
                 let condition = match e.condition() {
@@ -296,20 +279,42 @@ impl ExprCollector<'_> {
                             ];
                             let match_expr =
                                 self.alloc_expr_desugared(Expr::Match { expr: match_expr, arms });
-                            return self
-                                .alloc_expr(Expr::Loop { body: match_expr, label }, syntax_ptr);
+                            return self.alloc_expr(
+                                Expr::Loop {
+                                    body: match_expr,
+                                    label: e
+                                        .label()
+                                        .and_then(|l| l.lifetime())
+                                        .map(|l| Name::new_lifetime(&l)),
+                                },
+                                syntax_ptr,
+                            );
                         }
                     },
                 };
 
-                self.alloc_expr(Expr::While { condition, body, label }, syntax_ptr)
+                self.alloc_expr(
+                    Expr::While {
+                        condition,
+                        body,
+                        label: e.label().and_then(|l| l.lifetime()).map(|l| Name::new_lifetime(&l)),
+                    },
+                    syntax_ptr,
+                )
             }
             ast::Expr::ForExpr(e) => {
-                let label = e.label().map(|label| self.collect_label(label));
                 let iterable = self.collect_expr_opt(e.iterable());
                 let pat = self.collect_pat_opt(e.pat());
                 let body = self.collect_block_opt(e.loop_body());
-                self.alloc_expr(Expr::For { iterable, pat, body, label }, syntax_ptr)
+                self.alloc_expr(
+                    Expr::For {
+                        iterable,
+                        pat,
+                        body,
+                        label: e.label().and_then(|l| l.lifetime()).map(|l| Name::new_lifetime(&l)),
+                    },
+                    syntax_ptr,
+                )
             }
             ast::Expr::CallExpr(e) => {
                 let callee = self.collect_expr_opt(e.expr());
@@ -809,13 +814,6 @@ impl ExprCollector<'_> {
         }
     }
 
-    fn collect_label(&mut self, ast_label: ast::Label) -> LabelId {
-        let label = Label {
-            name: ast_label.lifetime().as_ref().map_or_else(Name::missing, Name::new_lifetime),
-        };
-        self.alloc_label(label, AstPtr::new(&ast_label))
-    }
-
     fn collect_pat(&mut self, pat: ast::Pat) -> PatId {
         let pattern = match &pat {
             ast::Pat::IdentPat(bp) => {
@@ -934,16 +932,10 @@ impl ExprCollector<'_> {
                 let inner = self.collect_pat_opt(boxpat.pat());
                 Pat::Box { inner }
             }
-            ast::Pat::ConstBlockPat(const_block_pat) => {
-                if let Some(expr) = const_block_pat.block_expr() {
-                    let expr_id = self.collect_block(expr);
-                    Pat::ConstBlock(expr_id)
-                } else {
-                    Pat::Missing
-                }
-            }
             // FIXME: implement
-            ast::Pat::RangePat(_) | ast::Pat::MacroPat(_) => Pat::Missing,
+            ast::Pat::RangePat(_) | ast::Pat::MacroPat(_) | ast::Pat::ConstBlockPat(_) => {
+                Pat::Missing
+            }
         };
         let ptr = AstPtr::new(&pat);
         self.alloc_pat(pattern, Either::Left(ptr))
diff --git a/crates/hir_def/src/expr.rs b/crates/hir_def/src/expr.rs
index 6a481769db..e5d740a365 100644
--- a/crates/hir_def/src/expr.rs
+++ b/crates/hir_def/src/expr.rs
@@ -29,12 +29,6 @@ pub(crate) fn dummy_expr_id() -> ExprId {
 
 pub type PatId = Idx<Pat>;
 
-#[derive(Debug, Clone, Eq, PartialEq)]
-pub struct Label {
-    pub name: Name,
-}
-pub type LabelId = Idx<Label>;
-
 #[derive(Debug, Clone, Eq, PartialEq)]
 pub enum Literal {
     String(String),
@@ -58,22 +52,22 @@ pub enum Expr {
     Block {
         statements: Vec<Statement>,
         tail: Option<ExprId>,
-        label: Option<LabelId>,
+        label: Option<Name>,
     },
     Loop {
         body: ExprId,
-        label: Option<LabelId>,
+        label: Option<Name>,
     },
     While {
         condition: ExprId,
         body: ExprId,
-        label: Option<LabelId>,
+        label: Option<Name>,
     },
     For {
         iterable: ExprId,
         pat: PatId,
         body: ExprId,
-        label: Option<LabelId>,
+        label: Option<Name>,
     },
     Call {
         callee: ExprId,
@@ -120,9 +114,6 @@ pub enum Expr {
     Async {
         body: ExprId,
     },
-    Const {
-        body: ExprId,
-    },
     Cast {
         expr: ExprId,
         type_ref: TypeRef,
@@ -262,10 +253,7 @@ impl Expr {
                     f(*expr);
                 }
             }
-            Expr::TryBlock { body }
-            | Expr::Unsafe { body }
-            | Expr::Async { body }
-            | Expr::Const { body } => f(*body),
+            Expr::TryBlock { body } | Expr::Unsafe { body } | Expr::Async { body } => f(*body),
             Expr::Loop { body, .. } => f(*body),
             Expr::While { condition, body, .. } => {
                 f(*condition);
@@ -411,18 +399,12 @@ pub enum Pat {
     TupleStruct { path: Option<Path>, args: Vec<PatId>, ellipsis: Option<usize> },
     Ref { pat: PatId, mutability: Mutability },
     Box { inner: PatId },
-    ConstBlock(ExprId),
 }
 
 impl Pat {
     pub fn walk_child_pats(&self, mut f: impl FnMut(PatId)) {
         match self {
-            Pat::Range { .. }
-            | Pat::Lit(..)
-            | Pat::Path(..)
-            | Pat::ConstBlock(..)
-            | Pat::Wild
-            | Pat::Missing => {}
+            Pat::Range { .. } | Pat::Lit(..) | Pat::Path(..) | Pat::Wild | Pat::Missing => {}
             Pat::Bind { subpat, .. } => {
                 subpat.iter().copied().for_each(f);
             }
diff --git a/crates/hir_ty/src/infer/expr.rs b/crates/hir_ty/src/infer/expr.rs
index 70a3f3075c..2cdce2cefc 100644
--- a/crates/hir_ty/src/infer/expr.rs
+++ b/crates/hir_ty/src/infer/expr.rs
@@ -143,7 +143,7 @@ impl<'a> InferenceContext<'a> {
                     self.breakables.push(BreakableContext {
                         may_break: false,
                         break_ty: break_ty.clone(),
-                        label: label.map(|label| self.body[label].name.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");
@@ -155,7 +155,7 @@ impl<'a> InferenceContext<'a> {
                 }
                 None => self.infer_block(statements, *tail, expected),
             },
-            Expr::Unsafe { body } | Expr::Const { body } => self.infer_expr(*body, expected),
+            Expr::Unsafe { body } => self.infer_expr(*body, expected),
             Expr::TryBlock { body } => {
                 let _inner = self.infer_expr(*body, expected);
                 // FIXME should be std::result::Result<{inner}, _>
@@ -172,7 +172,7 @@ impl<'a> InferenceContext<'a> {
                 self.breakables.push(BreakableContext {
                     may_break: false,
                     break_ty: self.table.new_type_var(),
-                    label: label.map(|label| self.body[label].name.clone()),
+                    label: label.clone(),
                 });
                 self.infer_expr(*body, &Expectation::has_type(Ty::unit()));
 
@@ -191,7 +191,7 @@ impl<'a> InferenceContext<'a> {
                 self.breakables.push(BreakableContext {
                     may_break: false,
                     break_ty: Ty::Unknown,
-                    label: label.map(|label| self.body[label].name.clone()),
+                    label: label.clone(),
                 });
                 // while let is desugared to a match loop, so this is always simple while
                 self.infer_expr(*condition, &Expectation::has_type(Ty::simple(TypeCtor::Bool)));
@@ -207,7 +207,7 @@ impl<'a> InferenceContext<'a> {
                 self.breakables.push(BreakableContext {
                     may_break: false,
                     break_ty: Ty::Unknown,
-                    label: label.map(|label| self.body[label].name.clone()),
+                    label: label.clone(),
                 });
                 let pat_ty =
                     self.resolve_associated_type(iterable_ty, self.resolve_into_iter_item());
diff --git a/crates/hir_ty/src/infer/pat.rs b/crates/hir_ty/src/infer/pat.rs
index d974f805b5..b70ec55eb5 100644
--- a/crates/hir_ty/src/infer/pat.rs
+++ b/crates/hir_ty/src/infer/pat.rs
@@ -243,9 +243,6 @@ impl<'a> InferenceContext<'a> {
                 }
                 None => Ty::Unknown,
             },
-            Pat::ConstBlock(expr) => {
-                self.infer_expr(*expr, &Expectation::has_type(expected.clone()))
-            }
             Pat::Missing => Ty::Unknown,
         };
         // use a new type variable if we got Ty::Unknown here
@@ -267,9 +264,8 @@ fn is_non_ref_pat(body: &hir_def::body::Body, pat: PatId) -> bool {
         | Pat::Range { .. }
         | Pat::Slice { .. } => true,
         Pat::Or(pats) => pats.iter().all(|p| is_non_ref_pat(body, *p)),
-        // FIXME: ConstBlock/Path/Lit might actually evaluate to ref, but inference is unimplemented.
+        // FIXME: Path/Lit might actually evaluate to ref, but inference is unimplemented.
         Pat::Path(..) => true,
-        Pat::ConstBlock(..) => true,
         Pat::Lit(expr) => match body[*expr] {
             Expr::Literal(Literal::String(..)) => false,
             _ => true,
diff --git a/crates/ide/src/diagnostics.rs b/crates/ide/src/diagnostics.rs
index b2714cb691..3ad30f0c9e 100644
--- a/crates/ide/src/diagnostics.rs
+++ b/crates/ide/src/diagnostics.rs
@@ -895,17 +895,4 @@ impl TestStruct {
 "#,
         );
     }
-
-    #[test]
-    fn test_single_incorrect_case_diagnostic_in_function_name_issue_6970() {
-        let input = r#"fn FOO<|>() {}"#;
-        let expected = r#"fn foo() {}"#;
-
-        let (analysis, file_position) = fixture::position(input);
-        let diagnostics =
-            analysis.diagnostics(&DiagnosticsConfig::default(), file_position.file_id).unwrap();
-        assert_eq!(diagnostics.len(), 1);
-
-        check_fixes(input, expected);
-    }
 }
diff --git a/crates/ide/src/lib.rs b/crates/ide/src/lib.rs
index a75cc85b6e..52c7f97759 100644
--- a/crates/ide/src/lib.rs
+++ b/crates/ide/src/lib.rs
@@ -490,18 +490,8 @@ impl Analysis {
             .unwrap_or_default())
     }
 
-    /// Computes assists (aka code actions aka intentions) for the given
-    /// position. Computes enough info to show the lightbulb list in the editor,
-    /// but doesn't compute actual edits, to improve performance.
-    ///
-    /// When the user clicks on the assist, call `resolve_assists` to get the
-    /// edit.
-    pub fn assists(&self, config: &AssistConfig, frange: FileRange) -> Cancelable<Vec<Assist>> {
-        self.with_db(|db| Assist::unresolved(db, config, frange))
-    }
-
     /// Computes resolved assists with source changes for the given position.
-    pub fn resolve_assists(
+    pub fn resolved_assists(
         &self,
         config: &AssistConfig,
         frange: FileRange,
@@ -509,6 +499,16 @@ impl Analysis {
         self.with_db(|db| assists::Assist::resolved(db, config, frange))
     }
 
+    /// Computes unresolved assists (aka code actions aka intentions) for the given
+    /// position.
+    pub fn unresolved_assists(
+        &self,
+        config: &AssistConfig,
+        frange: FileRange,
+    ) -> Cancelable<Vec<Assist>> {
+        self.with_db(|db| Assist::unresolved(db, config, frange))
+    }
+
     /// Computes the set of diagnostics for the given file.
     pub fn diagnostics(
         &self,
diff --git a/crates/parser/src/grammar/items.rs b/crates/parser/src/grammar/items.rs
index cf4168d321..72b73f8917 100644
--- a/crates/parser/src/grammar/items.rs
+++ b/crates/parser/src/grammar/items.rs
@@ -389,15 +389,10 @@ fn macro_rules(p: &mut Parser, m: Marker) {
     }
 
     match p.current() {
-        // test macro_rules_non_brace
-        // macro_rules! m ( ($i:ident) => {} );
-        // macro_rules! m [ ($i:ident) => {} ];
-        T!['['] | T!['('] => {
+        T!['{'] => {
             token_tree(p);
-            p.expect(T![;]);
         }
-        T!['{'] => token_tree(p),
-        _ => p.error("expected `{`, `[`, `(`"),
+        _ => p.error("expected `{`"),
     }
     m.complete(p, MACRO_RULES);
 }
diff --git a/crates/rust-analyzer/src/cli/progress_report.rs b/crates/rust-analyzer/src/cli/progress_report.rs
index bdbe565e60..5a2dc39d52 100644
--- a/crates/rust-analyzer/src/cli/progress_report.rs
+++ b/crates/rust-analyzer/src/cli/progress_report.rs
@@ -1,7 +1,7 @@
 //! A simple progress bar
 //!
 //! A single thread non-optimized progress bar
-use std::io::Write;
+use std::io::{self, Write};
 
 /// A Simple ASCII Progress Bar
 pub(crate) struct ProgressReport {
@@ -97,8 +97,8 @@ impl ProgressReport {
             }
         }
 
-        let _ = std::io::stdout().write(output.as_bytes());
-        let _ = std::io::stdout().flush();
+        let _ = io::stdout().write(output.as_bytes());
+        let _ = io::stdout().flush();
         self.text = text.to_string();
     }
 
@@ -115,6 +115,8 @@ impl ProgressReport {
         let spaces = " ".repeat(self.text.len());
         let backspaces = "\x08".repeat(self.text.len());
         print!("{}{}{}", backspaces, spaces, backspaces);
+        let _ = io::stdout().flush();
+
         self.text = String::new();
     }
 }
diff --git a/crates/rust-analyzer/src/handlers.rs b/crates/rust-analyzer/src/handlers.rs
index 1207b31c48..25692793b9 100644
--- a/crates/rust-analyzer/src/handlers.rs
+++ b/crates/rust-analyzer/src/handlers.rs
@@ -946,12 +946,12 @@ pub(crate) fn handle_code_action(
 
     if snap.config.client_caps.code_action_resolve {
         for (index, assist) in
-            snap.analysis.assists(&assists_config, frange)?.into_iter().enumerate()
+            snap.analysis.unresolved_assists(&assists_config, frange)?.into_iter().enumerate()
         {
             res.push(to_proto::unresolved_code_action(&snap, params.clone(), assist, index)?);
         }
     } else {
-        for assist in snap.analysis.resolve_assists(&assists_config, frange)?.into_iter() {
+        for assist in snap.analysis.resolved_assists(&assists_config, frange)?.into_iter() {
             res.push(to_proto::resolved_code_action(&snap, assist)?);
         }
     }
@@ -1014,7 +1014,7 @@ pub(crate) fn handle_code_action_resolve(
         .only
         .map(|it| it.into_iter().filter_map(from_proto::assist_kind).collect());
 
-    let assists = snap.analysis.resolve_assists(&snap.config.assist, frange)?;
+    let assists = snap.analysis.resolved_assists(&snap.config.assist, frange)?;
     let (id, index) = split_once(&params.id, ':').unwrap();
     let index = index.parse::<usize>().unwrap();
     let assist = &assists[index];
diff --git a/crates/syntax/src/ast/expr_ext.rs b/crates/syntax/src/ast/expr_ext.rs
index 636ce166d7..e4a9b945c9 100644
--- a/crates/syntax/src/ast/expr_ext.rs
+++ b/crates/syntax/src/ast/expr_ext.rs
@@ -358,7 +358,6 @@ pub enum Effect {
     Async(SyntaxToken),
     Unsafe(SyntaxToken),
     Try(SyntaxToken),
-    Const(SyntaxToken),
     // Very much not an effect, but we stuff it into this node anyway
     Label(ast::Label),
 }
@@ -374,9 +373,6 @@ impl ast::EffectExpr {
         if let Some(token) = self.try_token() {
             return Effect::Try(token);
         }
-        if let Some(token) = self.const_token() {
-            return Effect::Const(token);
-        }
         if let Some(label) = self.label() {
             return Effect::Label(label);
         }
diff --git a/docs/user/manual.adoc b/docs/user/manual.adoc
index d4121b4011..e3082d5842 100644
--- a/docs/user/manual.adoc
+++ b/docs/user/manual.adoc
@@ -218,7 +218,7 @@ The are several LSP client implementations for vim or neovim:
    * automatically install and upgrade stable/nightly releases
    * same configurations as VSCode extension, `rust-analyzer.serverPath`, `rust-analyzer.cargo.features` etc.
    * same commands too, `rust-analyzer.analyzerStatus`, `rust-analyzer.ssr` etc.
-   * inlay hints for variables and method chaining, _Neovim Only_
+   * inlay hints for method chaining support, _Neovim Only_
    * semantic highlighting is not implemented yet
 
 ==== LanguageClient-neovim


Test patch:
diff --git a/crates/hir_ty/src/tests/patterns.rs b/crates/hir_ty/src/tests/patterns.rs
index 2053d8f56e..5a5f48fd05 100644
--- a/crates/hir_ty/src/tests/patterns.rs
+++ b/crates/hir_ty/src/tests/patterns.rs
@@ -774,33 +774,3 @@ fn foo(tuple: Tuple) {
         "#]],
     );
 }
-
-#[test]
-fn const_block_pattern() {
-    check_infer(
-        r#"
-struct Foo(usize);
-fn foo(foo: Foo) {
-    match foo {
-        const { Foo(15 + 32) } => {},
-        _ => {}
-    }
-}"#,
-        expect![[r#"
-            26..29 'foo': Foo
-            36..115 '{     ...   } }': ()
-            42..113 'match ...     }': ()
-            48..51 'foo': Foo
-            62..84 'const ... 32) }': Foo
-            68..84 '{ Foo(... 32) }': Foo
-            70..73 'Foo': Foo(usize) -> Foo
-            70..82 'Foo(15 + 32)': Foo
-            74..76 '15': usize
-            74..81 '15 + 32': usize
-            79..81 '32': usize
-            88..90 '{}': ()
-            100..101 '_': Foo
-            105..107 '{}': ()
-        "#]],
-    );
-}
diff --git a/crates/hir_ty/src/tests/simple.rs b/crates/hir_ty/src/tests/simple.rs
index a61282d5a7..a569223b4b 100644
--- a/crates/hir_ty/src/tests/simple.rs
+++ b/crates/hir_ty/src/tests/simple.rs
@@ -1894,7 +1894,6 @@ fn effects_smoke_test() {
             let x = unsafe { 92 };
             let y = async { async { () }.await };
             let z = try { () };
-            let w = const { 92 };
             let t = 'a: { 92 };
         }
 
@@ -1906,7 +1905,7 @@ fn effects_smoke_test() {
         }
         "#,
         expect![[r#"
-            16..162 '{     ...2 }; }': ()
+            16..136 '{     ...2 }; }': ()
             26..27 'x': i32
             30..43 'unsafe { 92 }': i32
             37..43 '{ 92 }': i32
@@ -1922,13 +1921,9 @@ fn effects_smoke_test() {
             99..109 'try { () }': {unknown}
             103..109 '{ () }': ()
             105..107 '()': ()
-            119..120 'w': i32
-            123..135 'const { 92 }': i32
-            129..135 '{ 92 }': i32
-            131..133 '92': i32
-            145..146 't': i32
-            153..159 '{ 92 }': i32
-            155..157 '92': i32
+            119..120 't': i32
+            127..133 '{ 92 }': i32
+            129..131 '92': i32
         "#]],
     )
 }
diff --git a/crates/syntax/test_data/parser/inline/ok/0158_macro_rules_non_brace.rast b/crates/syntax/test_data/parser/inline/ok/0158_macro_rules_non_brace.rast
deleted file mode 100644
index 4a1f712aa7..0000000000
--- a/crates/syntax/test_data/parser/inline/ok/0158_macro_rules_non_brace.rast
+++ /dev/null
@@ -1,57 +0,0 @@
-SOURCE_FILE@0..74
-  MACRO_RULES@0..36
-    MACRO_RULES_KW@0..11 "macro_rules"
-    BANG@11..12 "!"
-    WHITESPACE@12..13 " "
-    NAME@13..14
-      IDENT@13..14 "m"
-    WHITESPACE@14..15 " "
-    TOKEN_TREE@15..35
-      L_PAREN@15..16 "("
-      WHITESPACE@16..17 " "
-      TOKEN_TREE@17..27
-        L_PAREN@17..18 "("
-        DOLLAR@18..19 "$"
-        IDENT@19..20 "i"
-        COLON@20..21 ":"
-        IDENT@21..26 "ident"
-        R_PAREN@26..27 ")"
-      WHITESPACE@27..28 " "
-      EQ@28..29 "="
-      R_ANGLE@29..30 ">"
-      WHITESPACE@30..31 " "
-      TOKEN_TREE@31..33
-        L_CURLY@31..32 "{"
-        R_CURLY@32..33 "}"
-      WHITESPACE@33..34 " "
-      R_PAREN@34..35 ")"
-    SEMICOLON@35..36 ";"
-  WHITESPACE@36..37 "\n"
-  MACRO_RULES@37..73
-    MACRO_RULES_KW@37..48 "macro_rules"
-    BANG@48..49 "!"
-    WHITESPACE@49..50 " "
-    NAME@50..51
-      IDENT@50..51 "m"
-    WHITESPACE@51..52 " "
-    TOKEN_TREE@52..72
-      L_BRACK@52..53 "["
-      WHITESPACE@53..54 " "
-      TOKEN_TREE@54..64
-        L_PAREN@54..55 "("
-        DOLLAR@55..56 "$"
-        IDENT@56..57 "i"
-        COLON@57..58 ":"
-        IDENT@58..63 "ident"
-        R_PAREN@63..64 ")"
-      WHITESPACE@64..65 " "
-      EQ@65..66 "="
-      R_ANGLE@66..67 ">"
-      WHITESPACE@67..68 " "
-      TOKEN_TREE@68..70
-        L_CURLY@68..69 "{"
-        R_CURLY@69..70 "}"
-      WHITESPACE@70..71 " "
-      R_BRACK@71..72 "]"
-    SEMICOLON@72..73 ";"
-  WHITESPACE@73..74 "\n"
diff --git a/crates/syntax/test_data/parser/inline/ok/0158_macro_rules_non_brace.rs b/crates/syntax/test_data/parser/inline/ok/0158_macro_rules_non_brace.rs
deleted file mode 100644
index 6033a28cd6..0000000000
--- a/crates/syntax/test_data/parser/inline/ok/0158_macro_rules_non_brace.rs
+++ /dev/null
@@ -1,2 +0,0 @@
-macro_rules! m ( ($i:ident) => {} );
-macro_rules! m [ ($i:ident) => {} ];