Repository: rust-analyzer/rust-analyzer
Pull request #11872 (2022-04-01 17:12:30)

internal: Remove `PathResolution::AssocItem`
bors r+


Patch:
diff --git a/README.md b/README.md
index 9732b05801..e2f3ad232a 100644
--- a/README.md
+++ b/README.md
@@ -7,6 +7,12 @@
 rust-analyzer is a modular compiler frontend for the Rust language.
 It is a part of a larger rls-2.0 effort to create excellent IDE support for Rust.
 
+Work on rust-analyzer is sponsored by
+
+[<img src="https://user-images.githubusercontent.com/1711539/58105231-cf306900-7bee-11e9-83d8-9f1102e59d29.png" alt="Ferrous Systems" width="300">](https://ferrous-systems.com/)
+- [Mozilla](https://www.mozilla.org/en-US/)
+- [Embark Studios](https://embark-studios.com/)
+
 ## Quick Start
 
 https://rust-analyzer.github.io/manual.html#installation
diff --git a/crates/hir/src/semantics.rs b/crates/hir/src/semantics.rs
index 8a700027a3..246b93723b 100644
--- a/crates/hir/src/semantics.rs
+++ b/crates/hir/src/semantics.rs
@@ -30,9 +30,9 @@ use crate::{
     db::HirDatabase,
     semantics::source_to_def::{ChildContainer, SourceToDefCache, SourceToDefCtx},
     source_analyzer::{resolve_hir_path, SourceAnalyzer},
-    Access, AssocItem, BuiltinAttr, Callable, ConstParam, Crate, Field, Function, HasSource,
-    HirFileId, Impl, InFile, Label, LifetimeParam, Local, Macro, Module, ModuleDef, Name, Path,
-    ScopeDef, ToolModule, Trait, Type, TypeAlias, TypeParam, VariantDef,
+    Access, BuiltinAttr, Callable, ConstParam, Crate, Field, Function, HasSource, HirFileId, Impl,
+    InFile, Label, LifetimeParam, Local, Macro, Module, ModuleDef, Name, Path, ScopeDef,
+    ToolModule, Trait, Type, TypeAlias, TypeParam, VariantDef,
 };
 
 #[derive(Debug, Clone, PartialEq, Eq)]
@@ -46,7 +46,6 @@ pub enum PathResolution {
     /// A const parameter
     ConstParam(ConstParam),
     SelfType(Impl),
-    AssocItem(AssocItem),
     BuiltinAttr(BuiltinAttr),
     ToolModule(ToolModule),
 }
@@ -76,10 +75,6 @@ impl PathResolution {
             | PathResolution::ConstParam(_) => None,
             PathResolution::TypeParam(param) => Some(TypeNs::GenericParam((*param).into())),
             PathResolution::SelfType(impl_def) => Some(TypeNs::SelfType((*impl_def).into())),
-            PathResolution::AssocItem(AssocItem::Const(_) | AssocItem::Function(_)) => None,
-            PathResolution::AssocItem(AssocItem::TypeAlias(alias)) => {
-                Some(TypeNs::TypeAliasId((*alias).into()))
-            }
         }
     }
 }
diff --git a/crates/hir/src/source_analyzer.rs b/crates/hir/src/source_analyzer.rs
index f918443427..6f5908ceb7 100644
--- a/crates/hir/src/source_analyzer.rs
+++ b/crates/hir/src/source_analyzer.rs
@@ -40,8 +40,9 @@ use syntax::{
 };
 
 use crate::{
-    db::HirDatabase, semantics::PathResolution, Adt, BuiltinAttr, BuiltinType, Const, Field,
-    Function, Local, Macro, ModuleDef, Static, Struct, ToolModule, Trait, Type, TypeAlias, Variant,
+    db::HirDatabase, semantics::PathResolution, Adt, AssocItem, BuiltinAttr, BuiltinType, Const,
+    Field, Function, Local, Macro, ModuleDef, Static, Struct, ToolModule, Trait, Type, TypeAlias,
+    Variant,
 };
 use base_db::CrateId;
 
@@ -302,7 +303,7 @@ impl SourceAnalyzer {
             let expr_id = self.expr_id(db, &path_expr.into())?;
             let infer = self.infer.as_ref()?;
             if let Some(assoc) = infer.assoc_resolutions_for_expr(expr_id) {
-                return Some(PathResolution::AssocItem(assoc.into()));
+                return Some(PathResolution::Def(AssocItem::from(assoc).into()));
             }
             if let Some(VariantId::EnumVariantId(variant)) =
                 infer.variant_resolution_for_expr(expr_id)
@@ -313,7 +314,7 @@ impl SourceAnalyzer {
         } else if let Some(path_pat) = parent().and_then(ast::PathPat::cast) {
             let pat_id = self.pat_id(&path_pat.into())?;
             if let Some(assoc) = self.infer.as_ref()?.assoc_resolutions_for_pat(pat_id) {
-                return Some(PathResolution::AssocItem(assoc.into()));
+                return Some(PathResolution::Def(AssocItem::from(assoc).into()));
             }
             if let Some(VariantId::EnumVariantId(variant)) =
                 self.infer.as_ref()?.variant_resolution_for_pat(pat_id)
diff --git a/crates/ide/src/runnables.rs b/crates/ide/src/runnables.rs
index 1c455c5f30..bcb2c8797d 100644
--- a/crates/ide/src/runnables.rs
+++ b/crates/ide/src/runnables.rs
@@ -474,7 +474,7 @@ impl TestAttr {
     }
 }
 
-const RUSTDOC_FENCES: [&str; 2] = ["```", "~~~"];
+const RUSTDOC_FENCE: &str = "```";
 const RUSTDOC_CODE_BLOCK_ATTRIBUTES_RUNNABLE: &[&str] =
     &["", "rust", "should_panic", "edition2015", "edition2018", "edition2021"];
 
@@ -483,9 +483,7 @@ fn has_runnable_doc_test(attrs: &hir::Attrs) -> bool {
         let mut in_code_block = false;
 
         for line in String::from(doc).lines() {
-            if let Some(header) =
-                RUSTDOC_FENCES.into_iter().find_map(|fence| line.strip_prefix(fence))
-            {
+            if let Some(header) = line.strip_prefix(RUSTDOC_FENCE) {
                 in_code_block = !in_code_block;
 
                 if in_code_block
diff --git a/crates/ide/src/signature_help.rs b/crates/ide/src/signature_help.rs
index f33b09ed57..6dc8b3046c 100644
--- a/crates/ide/src/signature_help.rs
+++ b/crates/ide/src/signature_help.rs
@@ -198,9 +198,6 @@ fn signature_help_for_generics(
             | hir::PathResolution::Def(hir::ModuleDef::Macro(_))
             | hir::PathResolution::Def(hir::ModuleDef::Module(_))
             | hir::PathResolution::Def(hir::ModuleDef::Static(_)) => return None,
-            hir::PathResolution::AssocItem(hir::AssocItem::Function(it)) => it.into(),
-            hir::PathResolution::AssocItem(hir::AssocItem::TypeAlias(it)) => it.into(),
-            hir::PathResolution::AssocItem(hir::AssocItem::Const(_)) => return None,
             hir::PathResolution::BuiltinAttr(_)
             | hir::PathResolution::ToolModule(_)
             | hir::PathResolution::Local(_)
diff --git a/crates/ide/src/syntax_highlighting/inject.rs b/crates/ide/src/syntax_highlighting/inject.rs
index 8ac3c2da50..8af0d8007d 100644
--- a/crates/ide/src/syntax_highlighting/inject.rs
+++ b/crates/ide/src/syntax_highlighting/inject.rs
@@ -78,8 +78,7 @@ pub(super) fn ra_fixture(
     Some(())
 }
 
-const RUSTDOC_FENCE_LENGTH: usize = 3;
-const RUSTDOC_FENCES: [&str; 2] = ["```", "~~~"];
+const RUSTDOC_FENCE: &str = "```";
 
 /// Injection of syntax highlighting of doctests.
 pub(super) fn doc_comment(
@@ -167,11 +166,11 @@ pub(super) fn doc_comment(
             };
             let mut pos = TextSize::from(0);
 
-            match RUSTDOC_FENCES.into_iter().find_map(|fence| line.find(fence)) {
+            match line.find(RUSTDOC_FENCE) {
                 Some(idx) => {
                     is_codeblock = !is_codeblock;
                     // Check whether code is rust by inspecting fence guards
-                    let guards = &line[idx + RUSTDOC_FENCE_LENGTH..];
+                    let guards = &line[idx + RUSTDOC_FENCE.len()..];
                     let is_rust = is_rust_fence(guards);
                     is_doctest = is_codeblock && is_rust;
                     continue;
diff --git a/crates/ide_assists/src/handlers/generate_enum_is_method.rs b/crates/ide_assists/src/handlers/generate_enum_is_method.rs
index 7dc1e4df28..863ada79ba 100644
--- a/crates/ide_assists/src/handlers/generate_enum_is_method.rs
+++ b/crates/ide_assists/src/handlers/generate_enum_is_method.rs
@@ -1,4 +1,3 @@
-use ide_db::assists::GroupLabel;
 use stdx::to_lower_snake_case;
 use syntax::ast::HasVisibility;
 use syntax::ast::{self, AstNode, HasName};
@@ -55,8 +54,7 @@ pub(crate) fn generate_enum_is_method(acc: &mut Assists, ctx: &AssistContext) ->
     let impl_def = find_struct_impl(ctx, &parent_enum, &fn_name)?;
 
     let target = variant.syntax().text_range();
-    acc.add_group(
-        &GroupLabel("Generate `is_`,`as_`,`try_into_`".to_owned()),
+    acc.add(
         AssistId("generate_enum_is_method", AssistKind::Generate),
         "Generate an `is_` method for an enum variant",
         target,
diff --git a/crates/ide_assists/src/handlers/generate_enum_projection_method.rs b/crates/ide_assists/src/handlers/generate_enum_projection_method.rs
index fdaa791340..a9116be67c 100644
--- a/crates/ide_assists/src/handlers/generate_enum_projection_method.rs
+++ b/crates/ide_assists/src/handlers/generate_enum_projection_method.rs
@@ -1,4 +1,3 @@
-use ide_db::assists::GroupLabel;
 use itertools::Itertools;
 use stdx::to_lower_snake_case;
 use syntax::ast::HasVisibility;
@@ -140,37 +139,31 @@ fn generate_enum_projection_method(
     let impl_def = find_struct_impl(ctx, &parent_enum, &fn_name)?;
 
     let target = variant.syntax().text_range();
-    acc.add_group(
-        &GroupLabel("Generate `is_`,`as_`,`try_into_`".to_owned()),
-        AssistId(assist_id, AssistKind::Generate),
-        assist_description,
-        target,
-        |builder| {
-            let vis = parent_enum.visibility().map_or(String::new(), |v| format!("{} ", v));
-            let method = format!(
-                "    {0}fn {1}({2}) -> {3}{4}{5} {{
+    acc.add(AssistId(assist_id, AssistKind::Generate), assist_description, target, |builder| {
+        let vis = parent_enum.visibility().map_or(String::new(), |v| format!("{} ", v));
+        let method = format!(
+            "    {0}fn {1}({2}) -> {3}{4}{5} {{
         if let Self::{6}{7} = self {{
             {8}({9})
         }} else {{
             {10}
         }}
     }}",
-                vis,
-                fn_name,
-                props.self_param,
-                props.return_prefix,
-                field_type.syntax(),
-                props.return_suffix,
-                variant_name,
-                pattern_suffix,
-                props.happy_case,
-                bound_name,
-                props.sad_case,
-            );
+            vis,
+            fn_name,
+            props.self_param,
+            props.return_prefix,
+            field_type.syntax(),
+            props.return_suffix,
+            variant_name,
+            pattern_suffix,
+            props.happy_case,
+            bound_name,
+            props.sad_case,
+        );
 
-            add_method_to_adt(builder, &parent_enum, impl_def, &method);
-        },
-    )
+        add_method_to_adt(builder, &parent_enum, impl_def, &method);
+    })
 }
 
 #[cfg(test)]
diff --git a/crates/ide_assists/src/handlers/inline_call.rs b/crates/ide_assists/src/handlers/inline_call.rs
index 5a28cbcc23..af2cb332e5 100644
--- a/crates/ide_assists/src/handlers/inline_call.rs
+++ b/crates/ide_assists/src/handlers/inline_call.rs
@@ -185,7 +185,6 @@ pub(crate) fn inline_call(acc: &mut Assists, ctx: &AssistContext) -> Option<()>
             }?;
             let function = match ctx.sema.resolve_path(&path)? {
                 PathResolution::Def(hir::ModuleDef::Function(f)) => f,
-                PathResolution::AssocItem(hir::AssocItem::Function(f)) => f,
                 _ => return None,
             };
             (function, format!("Inline `{}`", path))
diff --git a/crates/ide_db/src/defs.rs b/crates/ide_db/src/defs.rs
index 36457a5364..34b557e21e 100644
--- a/crates/ide_db/src/defs.rs
+++ b/crates/ide_db/src/defs.rs
@@ -482,14 +482,6 @@ impl From<PathResolution> for Definition {
     fn from(path_resolution: PathResolution) -> Self {
         match path_resolution {
             PathResolution::Def(def) => def.into(),
-            PathResolution::AssocItem(item) => {
-                let def: ModuleDef = match item {
-                    hir::AssocItem::Function(it) => it.into(),
-                    hir::AssocItem::Const(it) => it.into(),
-                    hir::AssocItem::TypeAlias(it) => it.into(),
-                };
-                def.into()
-            }
             PathResolution::Local(local) => Definition::Local(local),
             PathResolution::TypeParam(par) => Definition::GenericParam(par.into()),
             PathResolution::ConstParam(par) => Definition::GenericParam(par.into()),
diff --git a/crates/ide_db/src/path_transform.rs b/crates/ide_db/src/path_transform.rs
index 15bd9a8c9c..61b2c3f3b8 100644
--- a/crates/ide_db/src/path_transform.rs
+++ b/crates/ide_db/src/path_transform.rs
@@ -2,7 +2,7 @@
 
 use crate::helpers::mod_path_to_ast;
 use either::Either;
-use hir::{HirDisplay, SemanticsScope};
+use hir::{AsAssocItem, HirDisplay, SemanticsScope};
 use rustc_hash::FxHashMap;
 use syntax::{
     ast::{self, AstNode},
@@ -197,7 +197,7 @@ impl<'a> Ctx<'a> {
                     }
                 }
             }
-            hir::PathResolution::Def(def) => {
+            hir::PathResolution::Def(def) if def.as_assoc_item(self.source_scope.db).is_none() => {
                 if let hir::ModuleDef::Trait(_) = def {
                     if matches!(path.segment()?.kind()?, ast::PathSegmentKind::Type { .. }) {
                         // `speculative_resolve` resolves segments like `<T as
@@ -222,7 +222,7 @@ impl<'a> Ctx<'a> {
             hir::PathResolution::Local(_)
             | hir::PathResolution::ConstParam(_)
             | hir::PathResolution::SelfType(_)
-            | hir::PathResolution::AssocItem(_)
+            | hir::PathResolution::Def(_)
             | hir::PathResolution::BuiltinAttr(_)
             | hir::PathResolution::ToolModule(_) => (),
         }
diff --git a/crates/ide_ssr/src/resolving.rs b/crates/ide_ssr/src/resolving.rs
index d9b40608b8..84bf792fe0 100644
--- a/crates/ide_ssr/src/resolving.rs
+++ b/crates/ide_ssr/src/resolving.rs
@@ -2,6 +2,7 @@
 
 use crate::errors::error;
 use crate::{parsing, SsrError};
+use hir::AsAssocItem;
 use ide_db::base_db::FilePosition;
 use parsing::Placeholder;
 use rustc_hash::FxHashMap;
@@ -82,14 +83,17 @@ impl Resolver<'_, '_> {
             .filter_map(|(path_node, resolved)| {
                 if let Some(grandparent) = path_node.parent().and_then(|parent| parent.parent()) {
                     if let Some(call_expr) = ast::CallExpr::cast(grandparent.clone()) {
-                        if let hir::PathResolution::AssocItem(hir::AssocItem::Function(function)) =
+                        if let hir::PathResolution::Def(hir::ModuleDef::Function(function)) =
                             resolved.resolution
                         {
-                            let qualifier_type = self.resolution_scope.qualifier_type(path_node);
-                            return Some((
-                                grandparent,
-                                UfcsCallInfo { call_expr, function, qualifier_type },
-                            ));
+                            if function.as_assoc_item(self.resolution_scope.scope.db).is_some() {
+                                let qualifier_type =
+                                    self.resolution_scope.qualifier_type(path_node);
+                                return Some((
+                                    grandparent,
+                                    UfcsCallInfo { call_expr, function, qualifier_type },
+                                ));
+                            }
                         }
                     }
                 }
@@ -162,7 +166,9 @@ impl Resolver<'_, '_> {
 
     fn ok_to_use_path_resolution(&self, resolution: &hir::PathResolution) -> bool {
         match resolution {
-            hir::PathResolution::AssocItem(hir::AssocItem::Function(function)) => {
+            hir::PathResolution::Def(hir::ModuleDef::Function(function))
+                if function.as_assoc_item(self.resolution_scope.scope.db).is_some() =>
+            {
                 if function.self_param(self.resolution_scope.scope.db).is_some() {
                     // If we don't use this path resolution, then we won't be able to match method
                     // calls. e.g. `Foo::bar($s)` should match `x.bar()`.
@@ -172,7 +178,9 @@ impl Resolver<'_, '_> {
                     false
                 }
             }
-            hir::PathResolution::AssocItem(_) => {
+            hir::PathResolution::Def(
+                def @ (hir::ModuleDef::Const(_) | hir::ModuleDef::TypeAlias(_)),
+            ) if def.as_assoc_item(self.resolution_scope.scope.db).is_some() => {
                 // Not a function. Could be a constant or an associated type.
                 cov_mark::hit!(replace_associated_trait_constant);
                 false
@@ -229,7 +237,7 @@ impl<'db> ResolutionScope<'db> {
                 |assoc_item| {
                     let item_name = assoc_item.name(self.scope.db)?;
                     if item_name.to_smol_str().as_str() == name.text() {
-                        Some(hir::PathResolution::AssocItem(assoc_item))
+                        Some(hir::PathResolution::Def(assoc_item.into()))
                     } else {
                         None
                     }
diff --git a/crates/parser/src/grammar/types.rs b/crates/parser/src/grammar/types.rs
index 46db487d02..ff067f5293 100644
--- a/crates/parser/src/grammar/types.rs
+++ b/crates/parser/src/grammar/types.rs
@@ -57,12 +57,6 @@ fn type_with_bounds_cond(p: &mut Parser, allow_bounds: bool) {
 pub(super) fn ascription(p: &mut Parser) {
     assert!(p.at(T![:]));
     p.bump(T![:]);
-    if p.at(T![=]) {
-        // recover from `let x: = expr;`, `const X: = expr;` and similars
-        // hopefully no type starts with `=`
-        p.error("missing type");
-        return;
-    }
     type_(p);
 }
 
diff --git a/crates/rust-analyzer/src/markdown.rs b/crates/rust-analyzer/src/markdown.rs
index 912ed1e764..e1ff0f0178 100644
--- a/crates/rust-analyzer/src/markdown.rs
+++ b/crates/rust-analyzer/src/markdown.rs
@@ -1,7 +1,7 @@
 //! Transforms markdown
 use ide_db::rust_doc::is_rust_fence;
 
-const RUSTDOC_FENCES: [&str; 2] = ["```", "~~~"];
+const RUSTDOC_FENCE: &str = "```";
 
 pub(crate) fn format_docs(src: &str) -> String {
     let mut processed_lines = Vec::new();
@@ -13,8 +13,7 @@ pub(crate) fn format_docs(src: &str) -> String {
             continue;
         }
 
-        if let Some(header) = RUSTDOC_FENCES.into_iter().find_map(|fence| line.strip_prefix(fence))
-        {
+        if let Some(header) = line.strip_prefix(RUSTDOC_FENCE) {
             in_code_block ^= true;
 
             if in_code_block {
diff --git a/crates/syntax/Cargo.toml b/crates/syntax/Cargo.toml
index bb4d10207d..4a454cb8b7 100644
--- a/crates/syntax/Cargo.toml
+++ b/crates/syntax/Cargo.toml
@@ -30,7 +30,7 @@ rayon = "1.5.1"
 expect-test = "1.2.2"
 proc-macro2 = "1.0.36"
 quote = "1.0.16"
-ungrammar = "1.16.1"
+ungrammar = "=1.16.1"
 
 test_utils = { path = "../test_utils" }
 sourcegen = { path = "../sourcegen" }
diff --git a/crates/syntax/rust.ungram b/crates/syntax/rust.ungram
deleted file mode 100644
index cb58486eff..0000000000
--- a/crates/syntax/rust.ungram
+++ /dev/null
@@ -1,664 +0,0 @@
-// Rust Un-Grammar.
-//
-// This grammar specifies the structure of Rust's concrete syntax tree.
-// It does not specify parsing rules (ambiguities, precedence, etc are out of scope).
-// Tokens are processed -- contextual keywords are recognised, compound operators glued.
-//
-// Legend:
-//
-//   //          -- comment
-//   Name =      -- non-terminal definition
-//   'ident'     -- token (terminal)
-//   A B         -- sequence
-//   A | B       -- alternation
-//   A*          -- zero or more repetition
-//   A?          -- zero or one repetition
-//   (A)         -- same as A
-//   label:A     -- suggested name for field of AST node
-
-//*************************//
-// Names, Paths and Macros //
-//*************************//
-
-Name =
-  'ident' | 'self'
-
-NameRef =
-  'ident' | 'int_number' | 'self' | 'super' | 'crate' | 'Self'
-
-Lifetime =
-  'lifetime_ident'
-
-Path =
-  (qualifier:Path '::')? segment:PathSegment
-
-PathSegment =
-  '::'? NameRef
-| NameRef GenericArgList?
-| NameRef ParamList RetType?
-| '<' PathType ('as' PathType)? '>'
-
-GenericArgList =
-  '::'? '<' (GenericArg (',' GenericArg)* ','?)? '>'
-
-GenericArg =
-  TypeArg
-| AssocTypeArg
-| LifetimeArg
-| ConstArg
-
-TypeArg =
-  Type
-
-AssocTypeArg =
-  NameRef GenericParamList? (':' TypeBoundList | '=' Type)
-
-LifetimeArg =
-  Lifetime
-
-ConstArg =
-  Expr
-
-MacroCall =
-  Attr* Path '!' TokenTree ';'?
-
-TokenTree =
-  '(' ')'
-| '{' '}'
-| '[' ']'
-
-MacroItems =
-  Item*
-
-MacroStmts =
-  statements:Stmt*
-  Expr?
-
-//*************************//
-//          Items          //
-//*************************//
-
-SourceFile =
-  'shebang'?
-  Attr*
-  Item*
-
-Item =
-  Const
-| Enum
-| ExternBlock
-| ExternCrate
-| Fn
-| Impl
-| MacroCall
-| MacroRules
-| MacroDef
-| Module
-| Static
-| Struct
-| Trait
-| TypeAlias
-| Union
-| Use
-
-MacroRules =
-  Attr* Visibility?
-  'macro_rules' '!' Name
-  TokenTree
-
-MacroDef =
-  Attr* Visibility?
-  'macro' Name args:TokenTree?
-  body:TokenTree
-
-Module =
-  Attr* Visibility?
-  'mod' Name
-  (ItemList | ';')
-
-ItemList =
-  '{' Attr* Item* '}'
-
-ExternCrate =
-  Attr* Visibility?
-  'extern' 'crate' NameRef Rename? ';'
-
-Rename =
-  'as' (Name | '_')
-
-Use =
-  Attr* Visibility?
-  'use' UseTree ';'
-
-UseTree =
-  (Path? '::')? ('*' | UseTreeList)
-| Path Rename?
-
-UseTreeList =
-  '{' (UseTree (',' UseTree)* ','?)? '}'
-
-Fn =
- Attr* Visibility?
- 'default'? 'const'? 'async'? 'unsafe'? Abi?
- 'fn' Name GenericParamList? ParamList RetType? WhereClause?
- (body:BlockExpr | ';')
-
-Abi =
-  'extern' 'string'?
-
-ParamList =
-  '('(
-    SelfParam
-  | (SelfParam ',')? (Param (',' Param)* ','?)?
-  )')'
-| '|' (Param (',' Param)* ','?)? '|'
-
-SelfParam =
-  Attr* (
-    ('&' Lifetime?)? 'mut'? Name
-  | 'mut'? Name ':' Type
-  )
-
-Param =
-  Attr* (
-    Pat (':' Type)?
-  | Type
-  | '...'
-  )
-
-RetType =
-  '->' Type
-
-TypeAlias =
-  Attr* Visibility?
-  'default'?
-  'type' Name GenericParamList? (':' TypeBoundList?)? WhereClause?
-  ('=' Type)? ';'
-
-Struct =
-  Attr* Visibility?
-  'struct' Name GenericParamList? (
-    WhereClause? (RecordFieldList | ';')
-  | TupleFieldList WhereClause? ';'
-  )
-
-RecordFieldList =
- '{' fields:(RecordField (',' RecordField)* ','?)? '}'
-
-RecordField =
-  Attr* Visibility?
-  Name ':' Type
-
-TupleFieldList =
-  '(' fields:(TupleField (',' TupleField)* ','?)? ')'
-
-TupleField =
-  Attr* Visibility?
-  Type
-
-FieldList =
-  RecordFieldList
-| TupleFieldList
-
-Enum =
-  Attr* Visibility?
-  'enum' Name GenericParamList? WhereClause?
-  VariantList
-
-VariantList =
- '{' (Variant (',' Variant)* ','?)? '}'
-
-Variant =
-  Attr* Visibility?
-  Name FieldList? ('=' Expr)?
-
-Union =
-  Attr* Visibility?
-  'union' Name GenericParamList? WhereClause?
-  RecordFieldList
-
-// A Data Type.
-//
-// Not used directly in the grammar, but handy to have anyway.
-Adt =
-  Enum
-| Struct
-| Union
-
-Const =
-  Attr* Visibility?
-  'default'?
-  'const' (Name | '_') ':' Type
-  ('=' body:Expr)? ';'
-
-Static =
-  Attr* Visibility?
-  'static' 'mut'? Name ':' Type
-  ('=' body:Expr)? ';'
-
-Trait =
-  Attr* Visibility?
-  'unsafe'? 'auto'?
-  'trait' Name GenericParamList? (':' TypeBoundList?)? WhereClause?
-  AssocItemList
-
-AssocItemList =
-  '{' Attr* AssocItem* '}'
-
-AssocItem =
-  Const
-| Fn
-| MacroCall
-| TypeAlias
-
-Impl =
-  Attr* Visibility?
-  'default'? 'unsafe'?
-  'impl' GenericParamList? ('const'? '!'? trait:Type 'for')? self_ty:Type WhereClause?
-  AssocItemList
-
-ExternBlock =
-  Attr* 'unsafe'? Abi ExternItemList
-
-ExternItemList =
-  '{' Attr* ExternItem* '}'
-
-ExternItem =
-  Fn
-| MacroCall
-| Static
-| TypeAlias
-
-GenericParamList =
-  '<' (GenericParam (',' GenericParam)* ','?)? '>'
-
-GenericParam =
-  ConstParam
-| LifetimeParam
-| TypeParam
-
-TypeParam =
-  Attr* Name (':' TypeBoundList?)?
-  ('=' default_type:Type)?
-
-ConstParam =
-  Attr* 'const' Name ':' Type
-  ('=' default_val:Expr)?
-
-LifetimeParam =
-  Attr* Lifetime (':' TypeBoundList?)?
-
-WhereClause =
-  'where' predicates:(WherePred (',' WherePred)* ','?)
-
-WherePred =
-  ('for' GenericParamList)?  (Lifetime | Type) ':' TypeBoundList?
-
-Visibility =
-  'pub' ('(' 'in'? Path ')')?
-
-Attr =
-  '#' '!'? '[' Meta ']'
-
-Meta =
-  Path ('=' Expr | TokenTree)?
-
-//****************************//
-// Statements and Expressions //
-//****************************//
-
-Stmt =
-  ';'
-| ExprStmt
-| Item
-| LetStmt
-
-LetStmt =
-  Attr* 'let' Pat (':' Type)?
-  '=' initializer:Expr
-  LetElse?
-  ';'
-
-LetElse =
-  'else' BlockExpr
-
-ExprStmt =
-  Expr ';'?
-
-Expr =
-  ArrayExpr
-| AwaitExpr
-| BinExpr
-| BlockExpr
-| BoxExpr
-| BreakExpr
-| CallExpr
-| CastExpr
-| ClosureExpr
-| ContinueExpr
-| FieldExpr
-| ForExpr
-| IfExpr
-| IndexExpr
-| Literal
-| LoopExpr
-| MacroCall
-| MacroStmts
-| MatchExpr
-| MethodCallExpr
-| ParenExpr
-| PathExpr
-| PrefixExpr
-| RangeExpr
-| RecordExpr
-| RefExpr
-| ReturnExpr
-| TryExpr
-| TupleExpr
-| WhileExpr
-| YieldExpr
-| LetExpr
-| UnderscoreExpr
-
-Literal =
-  Attr* value:(
-    'int_number' | 'float_number'
-  | 'string' | 'raw_string'
-  | 'byte_string' | 'raw_byte_string'
-  | 'true' | 'false'
-  | 'char' | 'byte'
-  )
-
-PathExpr =
-  Attr* Path
-
-StmtList =
-  '{'
-    Attr*
-    statements:Stmt*
-    tail_expr:Expr?
-  '}'
-
-RefExpr =
-  Attr* '&' ('raw' | 'mut' | 'const') Expr
-
-TryExpr =
-  Attr* Expr '?'
-
-BlockExpr =
-  Attr* Label? ('try' | 'unsafe' | 'async' | 'const') StmtList
-
-PrefixExpr =
-  Attr* op:('-' | '!' | '*') Expr
-
-BinExpr =
-  Attr*
-  lhs:Expr
-  op:(
-    '||' | '&&'
-  | '==' | '!=' | '<=' | '>=' | '<' | '>'
-  | '+' | '*' | '-' | '/' | '%' | '<<' | '>>' | '^' | '|' | '&'
-  | '=' | '+=' | '/=' | '*=' | '%=' | '>>=' | '<<=' | '-=' | '|=' | '&=' | '^='
-  )
-  rhs:Expr
-
-CastExpr =
-  Attr* Expr 'as' Type
-
-ParenExpr =
-  Attr* '(' Attr* Expr ')'
-
-ArrayExpr =
-  Attr* '[' Attr* (
-    (Expr (',' Expr)* ','?)?
-  | Expr ';' Expr
-  ) ']'
-
-IndexExpr =
-  Attr* base:Expr '[' index:Expr ']'
-
-TupleExpr =
-  Attr* '(' Attr* fields:(Expr (',' Expr)* ','?)? ')'
-
-RecordExpr =
-  Path RecordExprFieldList
-
-RecordExprFieldList =
-  '{'
-    Attr*
-    fields:(RecordExprField (',' RecordExprField)* ','?)?
-    ('..' spread:Expr?)?
-  '}'
-
-RecordExprField =
-  Attr* (NameRef ':')? Expr
-
-CallExpr =
-  Attr* Expr ArgList
-
-ArgList =
-  '(' args:(Expr (',' Expr)* ','?)? ')'
-
-MethodCallExpr =
-  Attr* receiver:Expr '.' NameRef GenericArgList? ArgList
-
-FieldExpr =
-  Attr* Expr '.' NameRef
-
-ClosureExpr =
-  Attr* 'static'? 'async'? 'move'?  ParamList RetType?
-  body:Expr
-
-IfExpr =
-  Attr* 'if' condition:Expr then_branch:BlockExpr
-  ('else' else_branch:(IfExpr | BlockExpr))?
-
-LoopExpr =
-  Attr* Label? 'loop'
-  loop_body:BlockExpr
-
-ForExpr =
-  Attr* Label? 'for' Pat 'in' iterable:Expr
-  loop_body:BlockExpr
-
-WhileExpr =
-  Attr* Label? 'while' condition:Expr
-  loop_body:BlockExpr
-
-Label =
-  Lifetime ':'
-
-BreakExpr =
-  Attr* 'break' Lifetime? Expr?
-
-ContinueExpr =
-  Attr* 'continue' Lifetime?
-
-RangeExpr =
-  Attr* start:Expr? op:('..' | '..=') end:Expr?
-
-MatchExpr =
-  Attr* 'match' Expr MatchArmList
-
-MatchArmList =
-  '{'
-    Attr*
-    arms:MatchArm*
-  '}'
-
-MatchArm =
-  Attr* Pat guard:MatchGuard? '=>' Expr ','?
-
-MatchGuard =
-  'if' condition:Expr
-
-ReturnExpr =
-  Attr* 'return' Expr?
-
-YieldExpr =
-  Attr* 'yield' Expr?
-
-LetExpr =
-  Attr* 'let' Pat '=' Expr
-
-UnderscoreExpr =
-  Attr* '_'
-
-AwaitExpr =
-  Attr* Expr '.' 'await'
-
-BoxExpr =
-  Attr* 'box' Expr
-
-//*************************//
-//          Types          //
-//*************************//
-
-Type =
-  ArrayType
-| DynTraitType
-| FnPtrType
-| ForType
-| ImplTraitType
-| InferType
-| MacroType
-| NeverType
-| ParenType
-| PathType
-| PtrType
-| RefType
-| SliceType
-| TupleType
-
-ParenType =
-  '(' Type ')'
-
-NeverType =
-  '!'
-
-MacroType =
-  MacroCall
-
-PathType =
-  Path
-
-TupleType =
-  '(' fields:(Type (',' Type)* ','?)? ')'
-
-PtrType =
-  '*' ('const' | 'mut') Type
-
-RefType =
-  '&' Lifetime? 'mut'? Type
-
-ArrayType =
-  '[' Type ';' Expr ']'
-
-SliceType =
-  '[' Type ']'
-
-InferType =
-  '_'
-
-FnPtrType =
-  'const'? 'async'? 'unsafe'? Abi? 'fn' ParamList RetType?
-
-ForType =
-  'for' GenericParamList Type
-
-ImplTraitType =
-  'impl' TypeBoundList
-
-DynTraitType =
-  'dyn' TypeBoundList
-
-TypeBoundList =
-  bounds:(TypeBound ('+' TypeBound)* '+'?)
-
-TypeBound =
-  Lifetime
-| ('?' | '~' 'const')? Type
-
-//************************//
-//        Patterns        //
-//************************//
-
-Pat =
-  IdentPat
-| BoxPat
-| RestPat
-| LiteralPat
-| MacroPat
-| OrPat
-| ParenPat
-| PathPat
-| WildcardPat
-| RangePat
-| RecordPat
-| RefPat
-| SlicePat
-| TuplePat
-| TupleStructPat
-| ConstBlockPat
-
-LiteralPat =
-  Literal
-
-IdentPat =
-  Attr* 'ref'? 'mut'? Name ('@' Pat)?
-
-WildcardPat =
-  '_'
-
-RangePat =
-  // 1..
-  start:Pat op:('..' | '..=')
-  // 1..2
-  | start:Pat op:('..' | '..=') end:Pat
-  // ..2
-  | op:('..' | '..=') end:Pat
-
-RefPat =
-  '&' 'mut'? Pat
-
-RecordPat =
-  Path RecordPatFieldList
-
-RecordPatFieldList =
-  '{'
-    fields:(RecordPatField (',' RecordPatField)* ','?)?
-    RestPat?
-  '}'
-
-RecordPatField =
-  Attr* (NameRef ':')? Pat
-
-TupleStructPat =
-   Path '(' fields:(Pat (',' Pat)* ','?)? ')'
-
-TuplePat =
-   '(' fields:(Pat (',' Pat)* ','?)? ')'
-
-ParenPat =
-  '(' Pat ')'
-
-SlicePat =
-  '[' (Pat (',' Pat)* ','?)? ']'
-
-PathPat =
-  Path
-
-OrPat =
-  (Pat ('|' Pat)* '|'?)
-
-BoxPat =
-  'box' Pat
-
-RestPat =
-  Attr* '..'
-
-MacroPat =
-  MacroCall
-
-ConstBlockPat =
-  'const' BlockExpr
diff --git a/editors/code/README.md b/editors/code/README.md
index 46c6f6f2aa..b9d2891795 100644
--- a/editors/code/README.md
+++ b/editors/code/README.md
@@ -4,6 +4,20 @@ Provides support for rust-analyzer: novel LSP server for the Rust programming la
 
 **Note** the extension may cause conflicts with the official Rust extension. It is recommended to disable the Rust extension when using the rust-analyzer extension.
 
+## Sponsor
+
+Work on rust-analyzer is sponsored by
+
+[<img src="https://user-images.githubusercontent.com/1711539/58105231-cf306900-7bee-11e9-83d8-9f1102e59d29.png" alt="Ferrous Systems" width="300">](https://ferrous-systems.com/)
+
+- [Mozilla](https://www.mozilla.org/en-US/)
+- [Embark Studios](https://embark-studios.com/)
+
+If you want to sponsor:
+
+- [OpenCollective](https://opencollective.com/rust-analyzer/)
+- [Github Sponsors](https://github.com/sponsors/rust-analyzer)
+
 ## Features
 
 - [code completion], [imports insertion]


Test patch:
diff --git a/crates/hir_ty/src/tests/simple.rs b/crates/hir_ty/src/tests/simple.rs
index baed34ce23..df7b3df3d5 100644
--- a/crates/hir_ty/src/tests/simple.rs
+++ b/crates/hir_ty/src/tests/simple.rs
@@ -2556,20 +2556,6 @@ fn f() {
     )
 }
 
-#[test]
-fn infer_missing_type() {
-    check_types(
-        r#"
-struct S;
-
-fn f() {
-    let s: = S;
-      //^ S
-}
-    "#,
-    );
-}
-
 #[test]
 fn infer_type_alias_variant() {
     check_infer(
diff --git a/crates/ide/src/syntax_highlighting/test_data/highlight_doctest.html b/crates/ide/src/syntax_highlighting/test_data/highlight_doctest.html
index 36e9ec6333..d9126421cd 100644
--- a/crates/ide/src/syntax_highlighting/test_data/highlight_doctest.html
+++ b/crates/ide/src/syntax_highlighting/test_data/highlight_doctest.html
@@ -110,11 +110,6 @@ pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
     <span class="comment documentation">///</span><span class="comment documentation"> </span><span class="keyword injected">let</span><span class="none injected"> </span><span class="variable declaration injected">foobar</span><span class="none injected"> </span><span class="operator injected">=</span><span class="none injected"> </span><span class="struct injected">Foo</span><span class="operator injected">::</span><span class="function injected">new</span><span class="parenthesis injected">(</span><span class="parenthesis injected">)</span><span class="operator injected">.</span><span class="function injected">bar</span><span class="parenthesis injected">(</span><span class="parenthesis injected">)</span><span class="semicolon injected">;</span>
     <span class="comment documentation">/// ```</span>
     <span class="comment documentation">///</span>
-    <span class="comment documentation">/// ~~~rust,no_run</span>
-    <span class="comment documentation">///</span><span class="comment documentation"> </span><span class="comment injected">// code block with tilde.</span>
-    <span class="comment documentation">///</span><span class="comment documentation"> </span><span class="keyword injected">let</span><span class="none injected"> </span><span class="variable declaration injected">foobar</span><span class="none injected"> </span><span class="operator injected">=</span><span class="none injected"> </span><span class="struct injected">Foo</span><span class="operator injected">::</span><span class="function injected">new</span><span class="parenthesis injected">(</span><span class="parenthesis injected">)</span><span class="operator injected">.</span><span class="function injected">bar</span><span class="parenthesis injected">(</span><span class="parenthesis injected">)</span><span class="semicolon injected">;</span>
-    <span class="comment documentation">/// ~~~</span>
-    <span class="comment documentation">///</span>
     <span class="comment documentation">/// ```</span>
     <span class="comment documentation">///</span><span class="comment documentation"> </span><span class="comment injected">// functions</span>
     <span class="comment documentation">///</span><span class="comment documentation"> </span><span class="keyword injected">fn</span><span class="none injected"> </span><span class="function declaration injected">foo</span><span class="angle injected">&lt;</span><span class="type_param declaration injected">T</span><span class="comma injected">,</span><span class="none injected"> </span><span class="keyword injected">const</span><span class="none injected"> </span><span class="const_param declaration injected">X</span><span class="colon injected">:</span><span class="none injected"> </span><span class="builtin_type injected">usize</span><span class="angle injected">&gt;</span><span class="parenthesis injected">(</span><span class="value_param declaration injected">arg</span><span class="colon injected">:</span><span class="none injected"> </span><span class="builtin_type injected">i32</span><span class="parenthesis injected">)</span><span class="none injected"> </span><span class="brace injected">{</span>
diff --git a/crates/ide/src/syntax_highlighting/tests.rs b/crates/ide/src/syntax_highlighting/tests.rs
index fdfe347a32..2cd4fa809a 100644
--- a/crates/ide/src/syntax_highlighting/tests.rs
+++ b/crates/ide/src/syntax_highlighting/tests.rs
@@ -644,11 +644,6 @@ impl Foo {
     /// let foobar = Foo::new().bar();
     /// ```
     ///
-    /// ~~~rust,no_run
-    /// // code block with tilde.
-    /// let foobar = Foo::new().bar();
-    /// ~~~
-    ///
     /// ```
     /// // functions
     /// fn foo<T, const X: usize>(arg: i32) {
diff --git a/crates/syntax/src/tests/sourcegen_ast.rs b/crates/syntax/src/tests/sourcegen_ast.rs
index c2ed3eab0a..cb38abfe89 100644
--- a/crates/syntax/src/tests/sourcegen_ast.rs
+++ b/crates/syntax/src/tests/sourcegen_ast.rs
@@ -11,7 +11,7 @@ use std::{
 use itertools::Itertools;
 use proc_macro2::{Punct, Spacing};
 use quote::{format_ident, quote};
-use ungrammar::{Grammar, Rule};
+use ungrammar::{rust_grammar, Grammar, Rule};
 
 use crate::tests::ast_src::{
     AstEnumSrc, AstNodeSrc, AstSrc, Cardinality, Field, KindsSrc, KINDS_SRC,
@@ -24,8 +24,7 @@ fn sourcegen_ast() {
         sourcegen::project_root().join("crates/parser/src/syntax_kind/generated.rs");
     sourcegen::ensure_file_contents(syntax_kinds_file.as_path(), &syntax_kinds);
 
-    let grammar =
-        include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/rust.ungram")).parse().unwrap();
+    let grammar = rust_grammar();
     let ast = lower(&grammar);
 
     let ast_tokens = generate_tokens(&ast);