Repository: rust-analyzer/rust-analyzer
Pull request #4061 (2020-04-20 18:28:06)

ra_proc_macro: cleanups here and there
r? @edwin0cheng 


Patch:
diff --git a/Cargo.lock b/Cargo.lock
index 37455bc57b..3826ae1c6f 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -114,7 +114,7 @@ checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
 [[package]]
 name = "chalk-derive"
 version = "0.1.0"
-source = "git+https://github.com/rust-lang/chalk.git?rev=2c072cc830d04af5f10b390e6643327f85108282#2c072cc830d04af5f10b390e6643327f85108282"
+source = "git+https://github.com/rust-lang/chalk.git?rev=28cef6ff403d403e6ad2f3d27d944e9ffac1bce8#28cef6ff403d403e6ad2f3d27d944e9ffac1bce8"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -125,7 +125,7 @@ dependencies = [
 [[package]]
 name = "chalk-engine"
 version = "0.9.0"
-source = "git+https://github.com/rust-lang/chalk.git?rev=2c072cc830d04af5f10b390e6643327f85108282#2c072cc830d04af5f10b390e6643327f85108282"
+source = "git+https://github.com/rust-lang/chalk.git?rev=28cef6ff403d403e6ad2f3d27d944e9ffac1bce8#28cef6ff403d403e6ad2f3d27d944e9ffac1bce8"
 dependencies = [
  "chalk-macros",
  "rustc-hash",
@@ -134,7 +134,7 @@ dependencies = [
 [[package]]
 name = "chalk-ir"
 version = "0.1.0"
-source = "git+https://github.com/rust-lang/chalk.git?rev=2c072cc830d04af5f10b390e6643327f85108282#2c072cc830d04af5f10b390e6643327f85108282"
+source = "git+https://github.com/rust-lang/chalk.git?rev=28cef6ff403d403e6ad2f3d27d944e9ffac1bce8#28cef6ff403d403e6ad2f3d27d944e9ffac1bce8"
 dependencies = [
  "chalk-derive",
  "chalk-engine",
@@ -144,7 +144,7 @@ dependencies = [
 [[package]]
 name = "chalk-macros"
 version = "0.1.1"
-source = "git+https://github.com/rust-lang/chalk.git?rev=2c072cc830d04af5f10b390e6643327f85108282#2c072cc830d04af5f10b390e6643327f85108282"
+source = "git+https://github.com/rust-lang/chalk.git?rev=28cef6ff403d403e6ad2f3d27d944e9ffac1bce8#28cef6ff403d403e6ad2f3d27d944e9ffac1bce8"
 dependencies = [
  "lazy_static",
 ]
@@ -152,7 +152,7 @@ dependencies = [
 [[package]]
 name = "chalk-rust-ir"
 version = "0.1.0"
-source = "git+https://github.com/rust-lang/chalk.git?rev=2c072cc830d04af5f10b390e6643327f85108282#2c072cc830d04af5f10b390e6643327f85108282"
+source = "git+https://github.com/rust-lang/chalk.git?rev=28cef6ff403d403e6ad2f3d27d944e9ffac1bce8#28cef6ff403d403e6ad2f3d27d944e9ffac1bce8"
 dependencies = [
  "chalk-derive",
  "chalk-engine",
@@ -163,7 +163,7 @@ dependencies = [
 [[package]]
 name = "chalk-solve"
 version = "0.1.0"
-source = "git+https://github.com/rust-lang/chalk.git?rev=2c072cc830d04af5f10b390e6643327f85108282#2c072cc830d04af5f10b390e6643327f85108282"
+source = "git+https://github.com/rust-lang/chalk.git?rev=28cef6ff403d403e6ad2f3d27d944e9ffac1bce8#28cef6ff403d403e6ad2f3d27d944e9ffac1bce8"
 dependencies = [
  "chalk-derive",
  "chalk-engine",
@@ -1288,9 +1288,9 @@ checksum = "2439c63f3f6139d1b57529d16bc3b8bb855230c8efcc5d3a896c8bea7c3b1e84"
 
 [[package]]
 name = "regex"
-version = "1.3.7"
+version = "1.3.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a6020f034922e3194c711b82a627453881bc4682166cabb07134a10c26ba7692"
+checksum = "7f6946991529684867e47d86474e3a6d0c0ab9b82d5821e314b1ede31fa3a4b3"
 dependencies = [
  "aho-corasick",
  "memchr",
diff --git a/crates/ra_assists/src/handlers/add_from_impl_for_enum.rs b/crates/ra_assists/src/handlers/add_from_impl_for_enum.rs
index 0621487e8f..864373aa5d 100644
--- a/crates/ra_assists/src/handlers/add_from_impl_for_enum.rs
+++ b/crates/ra_assists/src/handlers/add_from_impl_for_enum.rs
@@ -98,7 +98,7 @@ fn already_has_from_impl(
     };
     let var_ty = hir_enum_var.fields(sema.db)[0].signature_ty(sema.db);
 
-    e_ty.impls_trait(sema.db, from_trait, &[var_ty])
+    e_ty.impls_trait(sema.db, from_trait, &[var_ty.clone()])
 }
 
 #[cfg(test)]
diff --git a/crates/ra_assists/src/handlers/introduce_variable.rs b/crates/ra_assists/src/handlers/introduce_variable.rs
index 8c09e6bcd0..8d0f7e922a 100644
--- a/crates/ra_assists/src/handlers/introduce_variable.rs
+++ b/crates/ra_assists/src/handlers/introduce_variable.rs
@@ -124,7 +124,7 @@ fn anchor_stmt(expr: ast::Expr) -> Option<(SyntaxNode, bool)> {
             }
         }
 
-        if ast::Stmt::cast(node.clone()).is_some() {
+        if ast::Stmt::cast(node.clone().into()).is_some() {
             return Some((node, false));
         }
 
diff --git a/crates/ra_assists/src/handlers/merge_imports.rs b/crates/ra_assists/src/handlers/merge_imports.rs
index 4be1238f14..ef0ce05861 100644
--- a/crates/ra_assists/src/handlers/merge_imports.rs
+++ b/crates/ra_assists/src/handlers/merge_imports.rs
@@ -30,7 +30,7 @@ pub(crate) fn merge_imports(ctx: AssistCtx) -> Option<Assist> {
             .filter_map(|dir| neighbor(&use_item, dir))
             .filter_map(|it| Some((it.clone(), it.use_tree()?)))
             .find_map(|(use_item, use_tree)| {
-                Some((try_merge_trees(&tree, &use_tree)?, use_item))
+                Some((try_merge_trees(&tree, &use_tree)?, use_item.clone()))
             })?;
 
         rewriter.replace_ast(&tree, &merged);
diff --git a/crates/ra_assists/src/handlers/split_import.rs b/crates/ra_assists/src/handlers/split_import.rs
index f258267963..d9244f22d6 100644
--- a/crates/ra_assists/src/handlers/split_import.rs
+++ b/crates/ra_assists/src/handlers/split_import.rs
@@ -37,7 +37,7 @@ pub(crate) fn split_import(ctx: AssistCtx) -> Option<Assist> {
 
 #[cfg(test)]
 mod tests {
-    use crate::helpers::{check_assist, check_assist_not_applicable, check_assist_target};
+    use crate::helpers::{check_assist, check_assist_target};
 
     use super::*;
 
@@ -63,9 +63,4 @@ mod tests {
     fn split_import_target() {
         check_assist_target(split_import, "use crate::<|>db::{RootDatabase, FileSymbol}", "::");
     }
-
-    #[test]
-    fn issue4044() {
-        check_assist_not_applicable(split_import, "use crate::<|>:::self;")
-    }
 }
diff --git a/crates/ra_db/src/fixture.rs b/crates/ra_db/src/fixture.rs
index 8248684eea..7777ce81e7 100644
--- a/crates/ra_db/src/fixture.rs
+++ b/crates/ra_db/src/fixture.rs
@@ -235,7 +235,7 @@ fn parse_meta(meta: &str) -> ParsedMeta {
             "env" => {
                 for key in value.split(',') {
                     if let Some((k, v)) = split1(key, '=') {
-                        env.set(k, v.into());
+                        env.set(k.into(), v.into());
                     }
                 }
             }
diff --git a/crates/ra_db/src/input.rs b/crates/ra_db/src/input.rs
index ab14e2d5e6..5ddce98c65 100644
--- a/crates/ra_db/src/input.rs
+++ b/crates/ra_db/src/input.rs
@@ -327,7 +327,7 @@ impl ExternSource {
         self.extern_paths.iter().find_map(|(root_path, id)| {
             if let Ok(rel_path) = path.strip_prefix(root_path) {
                 let rel_path = RelativePathBuf::from_path(rel_path).ok()?;
-                Some((*id, rel_path))
+                Some((id.clone(), rel_path))
             } else {
                 None
             }
diff --git a/crates/ra_hir_def/src/body/lower.rs b/crates/ra_hir_def/src/body/lower.rs
index 0caedd8d85..82a52804d5 100644
--- a/crates/ra_hir_def/src/body/lower.rs
+++ b/crates/ra_hir_def/src/body/lower.rs
@@ -473,14 +473,16 @@ impl ExprCollector<'_> {
         self.collect_block_items(&block);
         let statements = block
             .statements()
-            .map(|s| match s {
+            .filter_map(|s| match s {
                 ast::Stmt::LetStmt(stmt) => {
                     let pat = self.collect_pat_opt(stmt.pat());
                     let type_ref = stmt.ascribed_type().map(TypeRef::from_ast);
                     let initializer = stmt.initializer().map(|e| self.collect_expr(e));
-                    Statement::Let { pat, type_ref, initializer }
+                    Some(Statement::Let { pat, type_ref, initializer })
+                }
+                ast::Stmt::ExprStmt(stmt) => {
+                    Some(Statement::Expr(self.collect_expr_opt(stmt.expr())))
                 }
-                ast::Stmt::ExprStmt(stmt) => Statement::Expr(self.collect_expr_opt(stmt.expr())),
             })
             .collect();
         let tail = block.expr().map(|e| self.collect_expr(e));
diff --git a/crates/ra_hir_expand/src/ast_id_map.rs b/crates/ra_hir_expand/src/ast_id_map.rs
index d19569245e..a3ca302c2e 100644
--- a/crates/ra_hir_expand/src/ast_id_map.rs
+++ b/crates/ra_hir_expand/src/ast_id_map.rs
@@ -66,7 +66,7 @@ impl AstIdMap {
         // change parent's id. This means that, say, adding a new function to a
         // trait does not change ids of top-level items, which helps caching.
         bfs(node, |it| {
-            if let Some(module_item) = ast::ModuleItem::cast(it) {
+            if let Some(module_item) = ast::ModuleItem::cast(it.clone()) {
                 res.alloc(module_item.syntax());
             }
         });
diff --git a/crates/ra_hir_expand/src/builtin_macro.rs b/crates/ra_hir_expand/src/builtin_macro.rs
index 3da137f2e6..f9d3787f63 100644
--- a/crates/ra_hir_expand/src/builtin_macro.rs
+++ b/crates/ra_hir_expand/src/builtin_macro.rs
@@ -301,7 +301,7 @@ fn relative_file(db: &dyn AstDatabase, call_id: MacroCallId, path: &str) -> Opti
     }
 
     // Extern paths ?
-    let krate = *db.relevant_crates(call_site).get(0)?;
+    let krate = db.relevant_crates(call_site).get(0)?.clone();
     let (extern_source_id, relative_file) =
         db.crate_graph()[krate].extern_source.extern_path(path)?;
 
@@ -329,7 +329,7 @@ fn include_expand(
 
     // FIXME:
     // Handle include as expression
-    let res = parse_to_token_tree(&db.file_text(file_id))
+    let res = parse_to_token_tree(&db.file_text(file_id.into()))
         .ok_or_else(|| mbe::ExpandError::ConversionError)?
         .0;
 
@@ -340,7 +340,7 @@ fn get_env_inner(db: &dyn AstDatabase, arg_id: EagerMacroId, key: &str) -> Optio
     let call_id: MacroCallId = arg_id.into();
     let original_file = call_id.as_file().original_file(db);
 
-    let krate = *db.relevant_crates(original_file).get(0)?;
+    let krate = db.relevant_crates(original_file).get(0)?.clone();
     db.crate_graph()[krate].env.get(key)
 }
 
@@ -447,7 +447,7 @@ mod tests {
                     file_id: file_id.into(),
                 };
 
-                let id: MacroCallId = db.intern_eager_expansion(eager).into();
+                let id: MacroCallId = db.intern_eager_expansion(eager.into()).into();
                 id.as_file()
             }
         };
diff --git a/crates/ra_hir_ty/Cargo.toml b/crates/ra_hir_ty/Cargo.toml
index 04d3cd6a27..177bdbcb0e 100644
--- a/crates/ra_hir_ty/Cargo.toml
+++ b/crates/ra_hir_ty/Cargo.toml
@@ -27,9 +27,9 @@ test_utils = { path = "../test_utils" }
 
 scoped-tls = "1"
 
-chalk-solve =   { git = "https://github.com/rust-lang/chalk.git", rev = "2c072cc830d04af5f10b390e6643327f85108282" }
-chalk-rust-ir = { git = "https://github.com/rust-lang/chalk.git", rev = "2c072cc830d04af5f10b390e6643327f85108282" }
-chalk-ir =      { git = "https://github.com/rust-lang/chalk.git", rev = "2c072cc830d04af5f10b390e6643327f85108282" }
+chalk-solve =   { git = "https://github.com/rust-lang/chalk.git", rev = "28cef6ff403d403e6ad2f3d27d944e9ffac1bce8" }
+chalk-rust-ir = { git = "https://github.com/rust-lang/chalk.git", rev = "28cef6ff403d403e6ad2f3d27d944e9ffac1bce8" }
+chalk-ir =      { git = "https://github.com/rust-lang/chalk.git", rev = "28cef6ff403d403e6ad2f3d27d944e9ffac1bce8" }
 
 [dev-dependencies]
 insta = "0.16.0"
diff --git a/crates/ra_hir_ty/src/db.rs b/crates/ra_hir_ty/src/db.rs
index 9e5dfeab3c..33da16b487 100644
--- a/crates/ra_hir_ty/src/db.rs
+++ b/crates/ra_hir_ty/src/db.rs
@@ -107,13 +107,6 @@ pub trait HirDatabase: DefDatabase + Upcast<dyn DefDatabase> {
         krate: CrateId,
         goal: crate::Canonical<crate::InEnvironment<crate::Obligation>>,
     ) -> Option<crate::traits::Solution>;
-
-    #[salsa::invoke(crate::traits::chalk::program_clauses_for_chalk_env_query)]
-    fn program_clauses_for_chalk_env(
-        &self,
-        krate: CrateId,
-        env: chalk_ir::Environment<chalk::Interner>,
-    ) -> chalk_ir::ProgramClauses<chalk::Interner>;
 }
 
 fn infer_wait(db: &impl HirDatabase, def: DefWithBodyId) -> Arc<InferenceResult> {
diff --git a/crates/ra_hir_ty/src/traits.rs b/crates/ra_hir_ty/src/traits.rs
index 6bc6d474c9..05791a8486 100644
--- a/crates/ra_hir_ty/src/traits.rs
+++ b/crates/ra_hir_ty/src/traits.rs
@@ -225,7 +225,7 @@ fn solution_from_chalk(
                 None => unimplemented!(),
             })
             .collect();
-        let result = Canonical { value, num_vars: subst.binders.len(&Interner) };
+        let result = Canonical { value, num_vars: subst.binders.len() };
         SolutionVariables(result)
     };
     match solution {
diff --git a/crates/ra_hir_ty/src/traits/chalk.rs b/crates/ra_hir_ty/src/traits/chalk.rs
index 1ccb7c3b4a..e00a82db2a 100644
--- a/crates/ra_hir_ty/src/traits/chalk.rs
+++ b/crates/ra_hir_ty/src/traits/chalk.rs
@@ -4,8 +4,8 @@ use std::{fmt, sync::Arc};
 use log::debug;
 
 use chalk_ir::{
-    cast::Cast, fold::shift::Shift, interner::HasInterner, Goal, GoalData, Parameter,
-    PlaceholderIndex, TypeName, UniverseIndex,
+    cast::Cast, fold::shift::Shift, Goal, GoalData, Parameter, PlaceholderIndex, TypeName,
+    UniverseIndex,
 };
 
 use hir_def::{AssocContainerId, AssocItemId, GenericDefId, HasModule, Lookup, TypeAliasId};
@@ -33,10 +33,8 @@ impl chalk_ir::interner::Interner for Interner {
     type InternedGoals = Vec<Goal<Self>>;
     type InternedSubstitution = Vec<Parameter<Self>>;
     type InternedProgramClause = chalk_ir::ProgramClauseData<Self>;
-    type InternedProgramClauses = Arc<[chalk_ir::ProgramClause<Self>]>;
+    type InternedProgramClauses = Vec<chalk_ir::ProgramClause<Self>>;
     type InternedQuantifiedWhereClauses = Vec<chalk_ir::QuantifiedWhereClause<Self>>;
-    type InternedParameterKinds = Vec<chalk_ir::ParameterKind<()>>;
-    type InternedCanonicalVarKinds = Vec<chalk_ir::ParameterKind<UniverseIndex>>;
     type Identifier = TypeAliasId;
     type DefId = InternId;
 
@@ -62,27 +60,6 @@ impl chalk_ir::interner::Interner for Interner {
         tls::with_current_program(|prog| Some(prog?.debug_alias(alias, fmt)))
     }
 
-    fn debug_projection_ty(
-        proj: &chalk_ir::ProjectionTy<Interner>,
-        fmt: &mut fmt::Formatter<'_>,
-    ) -> Option<fmt::Result> {
-        tls::with_current_program(|prog| Some(prog?.debug_projection_ty(proj, fmt)))
-    }
-
-    fn debug_opaque_ty(
-        opaque_ty: &chalk_ir::OpaqueTy<Interner>,
-        fmt: &mut fmt::Formatter<'_>,
-    ) -> Option<fmt::Result> {
-        tls::with_current_program(|prog| Some(prog?.debug_opaque_ty(opaque_ty, fmt)))
-    }
-
-    fn debug_opaque_ty_id(
-        opaque_ty_id: chalk_ir::OpaqueTyId<Self>,
-        fmt: &mut fmt::Formatter<'_>,
-    ) -> Option<fmt::Result> {
-        tls::with_current_program(|prog| Some(prog?.debug_opaque_ty_id(opaque_ty_id, fmt)))
-    }
-
     fn debug_ty(ty: &chalk_ir::Ty<Interner>, fmt: &mut fmt::Formatter<'_>) -> Option<fmt::Result> {
         tls::with_current_program(|prog| Some(prog?.debug_ty(ty, fmt)))
     }
@@ -225,15 +202,15 @@ impl chalk_ir::interner::Interner for Interner {
     fn intern_program_clauses(
         &self,
         data: impl IntoIterator<Item = chalk_ir::ProgramClause<Self>>,
-    ) -> Arc<[chalk_ir::ProgramClause<Self>]> {
+    ) -> Vec<chalk_ir::ProgramClause<Self>> {
         data.into_iter().collect()
     }
 
     fn program_clauses_data<'a>(
         &self,
-        clauses: &'a Arc<[chalk_ir::ProgramClause<Self>]>,
+        clauses: &'a Vec<chalk_ir::ProgramClause<Self>>,
     ) -> &'a [chalk_ir::ProgramClause<Self>] {
-        &clauses
+        clauses
     }
 
     fn intern_quantified_where_clauses(
@@ -249,34 +226,6 @@ impl chalk_ir::interner::Interner for Interner {
     ) -> &'a [chalk_ir::QuantifiedWhereClause<Self>] {
         clauses
     }
-
-    fn intern_parameter_kinds(
-        &self,
-        data: impl IntoIterator<Item = chalk_ir::ParameterKind<()>>,
-    ) -> Self::InternedParameterKinds {
-        data.into_iter().collect()
-    }
-
-    fn parameter_kinds_data<'a>(
-        &self,
-        parameter_kinds: &'a Self::InternedParameterKinds,
-    ) -> &'a [chalk_ir::ParameterKind<()>] {
-        &parameter_kinds
-    }
-
-    fn intern_canonical_var_kinds(
-        &self,
-        data: impl IntoIterator<Item = chalk_ir::ParameterKind<UniverseIndex>>,
-    ) -> Self::InternedCanonicalVarKinds {
-        data.into_iter().collect()
-    }
-
-    fn canonical_var_kinds_data<'a>(
-        &self,
-        canonical_var_kinds: &'a Self::InternedCanonicalVarKinds,
-    ) -> &'a [chalk_ir::ParameterKind<UniverseIndex>] {
-        &canonical_var_kinds
-    }
 }
 
 impl chalk_ir::interner::HasInterner for Interner {
@@ -319,12 +268,9 @@ impl ToChalk for Ty {
             Ty::Projection(proj_ty) => {
                 let associated_ty_id = proj_ty.associated_ty.to_chalk(db);
                 let substitution = proj_ty.parameters.to_chalk(db);
-                chalk_ir::AliasTy::Projection(chalk_ir::ProjectionTy {
-                    associated_ty_id,
-                    substitution,
-                })
-                .cast(&Interner)
-                .intern(&Interner)
+                chalk_ir::AliasTy { associated_ty_id, substitution }
+                    .cast(&Interner)
+                    .intern(&Interner)
             }
             Ty::Placeholder(id) => {
                 let interned_id = db.intern_type_param_id(id);
@@ -368,17 +314,16 @@ impl ToChalk for Ty {
                 );
                 Ty::Placeholder(db.lookup_intern_type_param_id(interned_id))
             }
-            chalk_ir::TyData::Alias(chalk_ir::AliasTy::Projection(proj)) => {
+            chalk_ir::TyData::Alias(proj) => {
                 let associated_ty = from_chalk(db, proj.associated_ty_id);
                 let parameters = from_chalk(db, proj.substitution);
                 Ty::Projection(ProjectionTy { associated_ty, parameters })
             }
-            chalk_ir::TyData::Alias(chalk_ir::AliasTy::Opaque(_)) => unimplemented!(),
             chalk_ir::TyData::Function(_) => unimplemented!(),
             chalk_ir::TyData::BoundVar(idx) => Ty::Bound(idx),
             chalk_ir::TyData::InferenceVar(_iv) => Ty::Unknown,
             chalk_ir::TyData::Dyn(where_clauses) => {
-                assert_eq!(where_clauses.bounds.binders.len(&Interner), 1);
+                assert_eq!(where_clauses.bounds.binders.len(), 1);
                 let predicates = where_clauses
                     .bounds
                     .skip_binders()
@@ -459,7 +404,6 @@ impl ToChalk for TypeCtor {
         match type_name {
             TypeName::Struct(struct_id) => db.lookup_intern_type_ctor(struct_id.into()),
             TypeName::AssociatedType(type_id) => TypeCtor::AssociatedType(from_chalk(db, type_id)),
-            TypeName::OpaqueType(_) => unreachable!(),
             TypeName::Error => {
                 // this should not be reached, since we don't represent TypeName::Error with TypeCtor
                 unreachable!()
@@ -516,8 +460,7 @@ impl ToChalk for GenericPredicate {
             }
             GenericPredicate::Projection(projection_pred) => {
                 let ty = projection_pred.ty.to_chalk(db).shifted_in(&Interner);
-                let projection = projection_pred.projection_ty.to_chalk(db).shifted_in(&Interner);
-                let alias = chalk_ir::AliasTy::Projection(projection);
+                let alias = projection_pred.projection_ty.to_chalk(db).shifted_in(&Interner);
                 make_binders(chalk_ir::WhereClause::AliasEq(chalk_ir::AliasEq { alias, ty }), 0)
             }
             GenericPredicate::Error => panic!("tried passing GenericPredicate::Error to Chalk"),
@@ -538,13 +481,7 @@ impl ToChalk for GenericPredicate {
                 GenericPredicate::Implemented(from_chalk(db, tr))
             }
             chalk_ir::WhereClause::AliasEq(projection_eq) => {
-                let projection_ty = from_chalk(
-                    db,
-                    match projection_eq.alias {
-                        chalk_ir::AliasTy::Projection(p) => p,
-                        _ => unimplemented!(),
-                    },
-                );
+                let projection_ty = from_chalk(db, projection_eq.alias);
                 let ty = from_chalk(db, projection_eq.ty);
                 GenericPredicate::Projection(super::ProjectionPredicate { projection_ty, ty })
             }
@@ -553,10 +490,10 @@ impl ToChalk for GenericPredicate {
 }
 
 impl ToChalk for ProjectionTy {
-    type Chalk = chalk_ir::ProjectionTy<Interner>;
+    type Chalk = chalk_ir::AliasTy<Interner>;
 
-    fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::ProjectionTy<Interner> {
-        chalk_ir::ProjectionTy {
+    fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::AliasTy<Interner> {
+        chalk_ir::AliasTy {
             associated_ty_id: self.associated_ty.to_chalk(db),
             substitution: self.parameters.to_chalk(db),
         }
@@ -564,7 +501,7 @@ impl ToChalk for ProjectionTy {
 
     fn from_chalk(
         db: &dyn HirDatabase,
-        projection_ty: chalk_ir::ProjectionTy<Interner>,
+        projection_ty: chalk_ir::AliasTy<Interner>,
     ) -> ProjectionTy {
         ProjectionTy {
             associated_ty: from_chalk(db, projection_ty.associated_ty_id),
@@ -577,10 +514,7 @@ impl ToChalk for super::ProjectionPredicate {
     type Chalk = chalk_ir::AliasEq<Interner>;
 
     fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::AliasEq<Interner> {
-        chalk_ir::AliasEq {
-            alias: chalk_ir::AliasTy::Projection(self.projection_ty.to_chalk(db)),
-            ty: self.ty.to_chalk(db),
-        }
+        chalk_ir::AliasEq { alias: self.projection_ty.to_chalk(db), ty: self.ty.to_chalk(db) }
     }
 
     fn from_chalk(_db: &dyn HirDatabase, _normalize: chalk_ir::AliasEq<Interner>) -> Self {
@@ -606,24 +540,17 @@ impl ToChalk for Obligation {
 impl<T> ToChalk for Canonical<T>
 where
     T: ToChalk,
-    T::Chalk: HasInterner<Interner = Interner>,
 {
     type Chalk = chalk_ir::Canonical<T::Chalk>;
 
     fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::Canonical<T::Chalk> {
         let parameter = chalk_ir::ParameterKind::Ty(chalk_ir::UniverseIndex::ROOT);
         let value = self.value.to_chalk(db);
-        chalk_ir::Canonical {
-            value,
-            binders: chalk_ir::CanonicalVarKinds::from(&Interner, vec![parameter; self.num_vars]),
-        }
+        chalk_ir::Canonical { value, binders: vec![parameter; self.num_vars] }
     }
 
     fn from_chalk(db: &dyn HirDatabase, canonical: chalk_ir::Canonical<T::Chalk>) -> Canonical<T> {
-        Canonical {
-            num_vars: canonical.binders.len(&Interner),
-            value: from_chalk(db, canonical.value),
-        }
+        Canonical { num_vars: canonical.binders.len(), value: from_chalk(db, canonical.value) }
     }
 }
 
@@ -722,15 +649,9 @@ impl ToChalk for builtin::BuiltinImplAssocTyValueData {
     }
 }
 
-fn make_binders<T>(value: T, num_vars: usize) -> chalk_ir::Binders<T>
-where
-    T: HasInterner<Interner = Interner>,
-{
+fn make_binders<T>(value: T, num_vars: usize) -> chalk_ir::Binders<T> {
     chalk_ir::Binders::new(
-        chalk_ir::ParameterKinds::from(
-            &Interner,
-            std::iter::repeat(chalk_ir::ParameterKind::Ty(())).take(num_vars),
-        ),
+        std::iter::repeat(chalk_ir::ParameterKind::Ty(())).take(num_vars).collect(),
         value,
     )
 }
@@ -878,28 +799,6 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
         // FIXME tell Chalk about well-known traits (here and in trait_datum)
         None
     }
-
-    fn program_clauses_for_env(
-        &self,
-        environment: &chalk_ir::Environment<Interner>,
-    ) -> chalk_ir::ProgramClauses<Interner> {
-        self.db.program_clauses_for_chalk_env(self.krate, environment.clone())
-    }
-
-    fn opaque_ty_data(
-        &self,
-        _id: chalk_ir::OpaqueTyId<Interner>,
-    ) -> Arc<chalk_rust_ir::OpaqueTyDatum<Interner>> {
-        unimplemented!()
-    }
-}
-
-pub(crate) fn program_clauses_for_chalk_env_query(
-    db: &dyn HirDatabase,
-    krate: CrateId,
-    environment: chalk_ir::Environment<Interner>,
-) -> chalk_ir::ProgramClauses<Interner> {
-    chalk_solve::program_clauses_for_env(&ChalkContext { db, krate }, &environment)
 }
 
 pub(crate) fn associated_ty_data_query(
diff --git a/crates/ra_hir_ty/src/traits/chalk/tls.rs b/crates/ra_hir_ty/src/traits/chalk/tls.rs
index 4867cb17ed..fa8e4d1ad1 100644
--- a/crates/ra_hir_ty/src/traits/chalk/tls.rs
+++ b/crates/ra_hir_ty/src/traits/chalk/tls.rs
@@ -121,38 +121,19 @@ impl DebugContext<'_> {
         write!(fmt, "{}::{}", trait_data.name, type_alias_data.name)
     }
 
-    pub fn debug_opaque_ty_id(
-        &self,
-        opaque_ty_id: chalk_ir::OpaqueTyId<Interner>,
-        fmt: &mut fmt::Formatter<'_>,
-    ) -> Result<(), fmt::Error> {
-        fmt.debug_struct("OpaqueTyId").field("index", &opaque_ty_id.0).finish()
-    }
-
     pub fn debug_alias(
         &self,
-        alias_ty: &AliasTy<Interner>,
-        fmt: &mut fmt::Formatter<'_>,
-    ) -> Result<(), fmt::Error> {
-        match alias_ty {
-            AliasTy::Projection(projection_ty) => self.debug_projection_ty(projection_ty, fmt),
-            AliasTy::Opaque(opaque_ty) => self.debug_opaque_ty(opaque_ty, fmt),
-        }
-    }
-
-    pub fn debug_projection_ty(
-        &self,
-        projection_ty: &chalk_ir::ProjectionTy<Interner>,
+        alias: &AliasTy<Interner>,
         fmt: &mut fmt::Formatter<'_>,
     ) -> Result<(), fmt::Error> {
-        let type_alias: TypeAliasId = from_chalk(self.0, projection_ty.associated_ty_id);
+        let type_alias: TypeAliasId = from_chalk(self.0, alias.associated_ty_id);
         let type_alias_data = self.0.type_alias_data(type_alias);
         let trait_ = match type_alias.lookup(self.0.upcast()).container {
             AssocContainerId::TraitId(t) => t,
             _ => panic!("associated type not in trait"),
         };
         let trait_data = self.0.trait_data(trait_);
-        let params = projection_ty.substitution.parameters(&Interner);
+        let params = alias.substitution.parameters(&Interner);
         write!(fmt, "<{:?} as {}", &params[0], trait_data.name,)?;
         if params.len() > 1 {
             write!(
@@ -164,14 +145,6 @@ impl DebugContext<'_> {
         write!(fmt, ">::{}", type_alias_data.name)
     }
 
-    pub fn debug_opaque_ty(
-        &self,
-        opaque_ty: &chalk_ir::OpaqueTy<Interner>,
-        fmt: &mut fmt::Formatter<'_>,
-    ) -> Result<(), fmt::Error> {
-        write!(fmt, "{:?}", opaque_ty.opaque_ty_id)
-    }
-
     pub fn debug_ty(
         &self,
         ty: &chalk_ir::Ty<Interner>,
diff --git a/crates/ra_ide/src/extend_selection.rs b/crates/ra_ide/src/extend_selection.rs
index 753d2ef6a0..f5a0633512 100644
--- a/crates/ra_ide/src/extend_selection.rs
+++ b/crates/ra_ide/src/extend_selection.rs
@@ -96,7 +96,7 @@ fn try_extend_selection(
         return Some(node.text_range());
     }
 
-    let node = shallowest_node(&node);
+    let node = shallowest_node(&node.into());
 
     if node.parent().map(|n| list_kinds.contains(&n.kind())) == Some(true) {
         if let Some(range) = extend_list_item(&node) {
diff --git a/crates/ra_proc_macro/src/lib.rs b/crates/ra_proc_macro/src/lib.rs
index b200fd1263..004943b9e0 100644
--- a/crates/ra_proc_macro/src/lib.rs
+++ b/crates/ra_proc_macro/src/lib.rs
@@ -2,7 +2,7 @@
 //!
 //! We separate proc-macro expanding logic to an extern program to allow
 //! different implementations (e.g. wasm or dylib loading). And this crate
-//! is used to provide basic infrastructure  for communication between two
+//! is used to provide basic infrastructure for communication between two
 //! processes: Client (RA itself), Server (the external program)
 
 mod rpc;
@@ -13,6 +13,7 @@ use process::{ProcMacroProcessSrv, ProcMacroProcessThread};
 use ra_tt::{SmolStr, Subtree};
 use std::{
     ffi::OsStr,
+    io,
     path::{Path, PathBuf},
     sync::Arc,
 };
@@ -57,14 +58,10 @@ pub struct ProcMacroClient {
 }
 
 impl ProcMacroClient {
-    pub fn extern_process<I, S>(
-        process_path: &Path,
-        args: I,
-    ) -> Result<ProcMacroClient, std::io::Error>
-    where
-        I: IntoIterator<Item = S>,
-        S: AsRef<OsStr>,
-    {
+    pub fn extern_process(
+        process_path: PathBuf,
+        args: impl IntoIterator<Item = impl AsRef<OsStr>>,
+    ) -> io::Result<ProcMacroClient> {
         let (thread, process) = ProcMacroProcessSrv::run(process_path, args)?;
         Ok(ProcMacroClient {
             kind: ProcMacroClientKind::Process { process: Arc::new(process), thread },
@@ -84,7 +81,7 @@ impl ProcMacroClient {
             ProcMacroClientKind::Process { process, .. } => {
                 let macros = match process.find_proc_macros(dylib_path) {
                     Err(err) => {
-                        eprintln!("Fail to find proc macro. Error: {:#?}", err);
+                        eprintln!("Failed to find proc macros. Error: {:#?}", err);
                         return vec![];
                     }
                     Ok(macros) => macros,
diff --git a/crates/ra_proc_macro/src/msg.rs b/crates/ra_proc_macro/src/msg.rs
index aa95bcc8f7..95d9b8804e 100644
--- a/crates/ra_proc_macro/src/msg.rs
+++ b/crates/ra_proc_macro/src/msg.rs
@@ -1,4 +1,4 @@
-//! Defines messages for cross-process message based on `ndjson` wire protocol
+//! Defines messages for cross-process message passing based on `ndjson` wire protocol
 
 use std::{
     convert::TryFrom,
@@ -31,7 +31,7 @@ macro_rules! impl_try_from_response {
             fn try_from(value: Response) -> Result<Self, Self::Error> {
                 match value {
                     Response::$tag(res) => Ok(res),
-                    _ => Err("Fail to convert from response"),
+                    _ => Err(concat!("Failed to convert response to ", stringify!($tag))),
                 }
             }
         }
@@ -53,18 +53,16 @@ pub enum ErrorCode {
     ExpansionError,
 }
 
-pub trait Message: Sized + Serialize + DeserializeOwned {
-    fn read(r: &mut impl BufRead) -> io::Result<Option<Self>> {
-        let text = match read_json(r)? {
-            None => return Ok(None),
-            Some(text) => text,
-        };
-        let msg = serde_json::from_str(&text)?;
-        Ok(Some(msg))
+pub trait Message: Serialize + DeserializeOwned {
+    fn read(inp: &mut impl BufRead) -> io::Result<Option<Self>> {
+        Ok(match read_json(inp)? {
+            None => None,
+            Some(text) => Some(serde_json::from_str(&text)?),
+        })
     }
-    fn write(self, w: &mut impl Write) -> io::Result<()> {
+    fn write(self, out: &mut impl Write) -> io::Result<()> {
         let text = serde_json::to_string(&self)?;
-        write_json(w, &text)
+        write_json(out, &text)
     }
 }
 
@@ -73,15 +71,12 @@ impl Message for Response {}
 
 fn read_json(inp: &mut impl BufRead) -> io::Result<Option<String>> {
     let mut buf = String::new();
-    if inp.read_line(&mut buf)? == 0 {
-        return Ok(None);
-    }
-    // Remove ending '\n'
-    let buf = &buf[..buf.len() - 1];
-    if buf.is_empty() {
-        return Ok(None);
-    }
-    Ok(Some(buf.to_string()))
+    inp.read_line(&mut buf)?;
+    buf.pop(); // Remove traling '\n'
+    Ok(match buf.len() {
+        0 => None,
+        _ => Some(buf),
+    })
 }
 
 fn write_json(out: &mut impl Write, msg: &str) -> io::Result<()> {
diff --git a/crates/ra_proc_macro/src/process.rs b/crates/ra_proc_macro/src/process.rs
index f851570bca..e24944af4b 100644
--- a/crates/ra_proc_macro/src/process.rs
+++ b/crates/ra_proc_macro/src/process.rs
@@ -45,24 +45,23 @@ impl Drop for Process {
 }
 
 impl Process {
-    fn run<I, S>(process_path: &Path, args: I) -> Result<Process, io::Error>
-    where
-        I: IntoIterator<Item = S>,
-        S: AsRef<OsStr>,
-    {
-        let child = Command::new(process_path.clone())
+    fn run(
+        process_path: PathBuf,
+        args: impl IntoIterator<Item = impl AsRef<OsStr>>,
+    ) -> io::Result<Process> {
+        let child = Command::new(&process_path)
             .args(args)
             .stdin(Stdio::piped())
             .stdout(Stdio::piped())
             .stderr(Stdio::null())
             .spawn()?;
 
-        Ok(Process { path: process_path.into(), child })
+        Ok(Process { path: process_path, child })
     }
 
-    fn restart(&mut self) -> Result<(), io::Error> {
+    fn restart(&mut self) -> io::Result<()> {
         let _ = self.child.kill();
-        self.child = Command::new(self.path.clone())
+        self.child = Command::new(&self.path)
             .stdin(Stdio::piped())
             .stdout(Stdio::piped())
             .stderr(Stdio::null())
@@ -80,14 +79,10 @@ impl Process {
 }
 
 impl ProcMacroProcessSrv {
-    pub fn run<I, S>(
-        process_path: &Path,
-        args: I,
-    ) -> Result<(ProcMacroProcessThread, ProcMacroProcessSrv), io::Error>
-    where
-        I: IntoIterator<Item = S>,
-        S: AsRef<OsStr>,
-    {
+    pub fn run(
+        process_path: PathBuf,
+        args: impl IntoIterator<Item = impl AsRef<OsStr>>,
+    ) -> io::Result<(ProcMacroProcessThread, ProcMacroProcessSrv)> {
         let process = Process::run(process_path, args)?;
 
         let (task_tx, task_rx) = bounded(0);
@@ -201,7 +196,7 @@ fn send_request(
     mut writer: &mut impl Write,
     mut reader: &mut impl BufRead,
     req: Request,
-) -> Result<Option<Response>, io::Error> {
+) -> io::Result<Option<Response>> {
     req.write(&mut writer)?;
     Ok(Response::read(&mut reader)?)
 }
diff --git a/crates/ra_proc_macro/src/rpc.rs b/crates/ra_proc_macro/src/rpc.rs
index 66b3f55db3..4ce4859263 100644
--- a/crates/ra_proc_macro/src/rpc.rs
+++ b/crates/ra_proc_macro/src/rpc.rs
@@ -1,9 +1,9 @@
-//! Data struture serialization related stuffs for RPC
+//! Data struture serialization related stuff for RPC
 //!
-//! Define all necessary rpc serialization data structure,
-//! which include ra_tt related data and some task messages.
-//! Although adding Serialize and Deserialize trait to ra_tt directly seem to be much easier,
-//! we deliberately duplicate the ra_tt struct with #[serde(with = "XXDef")]
+//! Defines all necessary rpc serialization data structures,
+//! which includes `ra_tt` related data and some task messages.
+//! Although adding `Serialize` and `Deserialize` traits to `ra_tt` directly seems
+//! to be much easier, we deliberately duplicate `ra_tt` structs with `#[serde(with = "XXDef")]`
 //! for separation of code responsibility.
 
 use ra_tt::{
@@ -34,15 +34,15 @@ pub struct ListMacrosResult {
 pub struct ExpansionTask {
     /// Argument of macro call.
     ///
-    /// In custom derive that would be a struct or enum; in attribute-like macro - underlying
+    /// In custom derive this will be a struct or enum; in attribute-like macro - underlying
     /// item; in function-like macro - the macro body.
     #[serde(with = "SubtreeDef")]
     pub macro_body: Subtree,
 
-    /// Names of macros to expand.
+    /// Name of macro to expand.
     ///
-    /// In custom derive those are names of derived traits (`Serialize`, `Getters`, etc.). In
-    /// attribute-like and functiona-like macros - single name of macro itself (`show_streams`).
+    /// In custom derive this is the name of the derived trait (`Serialize`, `Getters`, etc.).
+    /// In attribute-like and function-like macros - single name of macro itself (`show_streams`).
     pub macro_name: String,
 
     /// Possible attributes for the attribute-like macros.
diff --git a/crates/ra_proc_macro_srv/src/cli.rs b/crates/ra_proc_macro_srv/src/cli.rs
index c771f2b389..5f1f3ba3c7 100644
--- a/crates/ra_proc_macro_srv/src/cli.rs
+++ b/crates/ra_proc_macro_srv/src/cli.rs
@@ -2,55 +2,43 @@
 
 use crate::{expand_task, list_macros};
 use ra_proc_macro::msg::{self, Message};
-
 use std::io;
 
-fn read_request() -> Result<Option<msg::Request>, io::Error> {
-    let stdin = io::stdin();
-    let mut stdin = stdin.lock();
-    msg::Request::read(&mut stdin)
-}
-
-fn write_response(res: Result<msg::Response, String>) -> Result<(), io::Error> {
-    let msg: msg::Response = match res {
-        Ok(res) => res,
-        Err(err) => msg::Response::Error(msg::ResponseError {
-            code: msg::ErrorCode::ExpansionError,
-            message: err,
-        }),
-    };
-
-    let stdout = io::stdout();
-    let mut stdout = stdout.lock();
-    msg.write(&mut stdout)
-}
-
 pub fn run() {
     loop {
         let req = match read_request() {
             Err(err) => {
-                eprintln!("Read message error on ra_proc_macro_srv: {}", err.to_string());
+                eprintln!("Read message error on ra_proc_macro_srv: {}", err);
                 continue;
             }
             Ok(None) => continue,
             Ok(Some(req)) => req,
         };
 
-        match req {
-            msg::Request::ListMacro(task) => {
-                if let Err(err) =
-                    write_response(list_macros(&task).map(|it| msg::Response::ListMacro(it)))
-                {
-                    eprintln!("Write message error on list macro: {}", err);
-                }
-            }
+        let res = match req {
+            msg::Request::ListMacro(task) => Ok(msg::Response::ListMacro(list_macros(&task))),
             msg::Request::ExpansionMacro(task) => {
-                if let Err(err) =
-                    write_response(expand_task(&task).map(|it| msg::Response::ExpansionMacro(it)))
-                {
-                    eprintln!("Write message error on expansion macro: {}", err);
-                }
+                expand_task(&task).map(msg::Response::ExpansionMacro)
             }
+        };
+
+        let msg = res.unwrap_or_else(|err| {
+            msg::Response::Error(msg::ResponseError {
+                code: msg::ErrorCode::ExpansionError,
+                message: err,
+            })
+        });
+
+        if let Err(err) = write_response(msg) {
+            eprintln!("Write message error: {}", err);
         }
     }
 }
+
+fn read_request() -> io::Result<Option<msg::Request>> {
+    msg::Request::read(&mut io::stdin().lock())
+}
+
+fn write_response(msg: msg::Response) -> io::Result<()> {
+    msg.write(&mut io::stdout().lock())
+}
diff --git a/crates/ra_proc_macro_srv/src/dylib.rs b/crates/ra_proc_macro_srv/src/dylib.rs
index 16bd7466e3..d202eb0fde 100644
--- a/crates/ra_proc_macro_srv/src/dylib.rs
+++ b/crates/ra_proc_macro_srv/src/dylib.rs
@@ -9,43 +9,37 @@ use libloading::Library;
 use memmap::Mmap;
 use ra_proc_macro::ProcMacroKind;
 
-use std::io::Error as IoError;
-use std::io::ErrorKind as IoErrorKind;
+use std::io;
 
 const NEW_REGISTRAR_SYMBOL: &str = "_rustc_proc_macro_decls_";
 
-fn invalid_data_err(e: impl Into<Box<dyn std::error::Error + Send + Sync>>) -> IoError {
-    IoError::new(IoErrorKind::InvalidData, e)
+fn invalid_data_err(e: impl Into<Box<dyn std::error::Error + Send + Sync>>) -> io::Error {
+    io::Error::new(io::ErrorKind::InvalidData, e)
 }
 
 fn is_derive_registrar_symbol(symbol: &str) -> bool {
     symbol.contains(NEW_REGISTRAR_SYMBOL)
 }
 
-fn find_registrar_symbol(file: &Path) -> Result<Option<String>, IoError> {
+fn find_registrar_symbol(file: &Path) -> io::Result<Option<String>> {
     let file = File::open(file)?;
     let buffer = unsafe { Mmap::map(&file)? };
     let object = Object::parse(&buffer).map_err(invalid_data_err)?;
 
-    match object {
+    let name = match object {
         Object::Elf(elf) => {
             let symbols = elf.dynstrtab.to_vec().map_err(invalid_data_err)?;
-            let name =
-                symbols.iter().find(|s| is_derive_registrar_symbol(s)).map(|s| s.to_string());
-            Ok(name)
-        }
-        Object::PE(pe) => {
-            let name = pe
-                .exports
-                .iter()
-                .flat_map(|s| s.name)
-                .find(|s| is_derive_registrar_symbol(s))
-                .map(|s| s.to_string());
-            Ok(name)
+            symbols.into_iter().find(|s| is_derive_registrar_symbol(s)).map(&str::to_owned)
         }
+        Object::PE(pe) => pe
+            .exports
+            .iter()
+            .flat_map(|s| s.name)
+            .find(|s| is_derive_registrar_symbol(s))
+            .map(&str::to_owned),
         Object::Mach(Mach::Binary(binary)) => {
             let exports = binary.exports().map_err(invalid_data_err)?;
-            let name = exports
+            exports
                 .iter()
                 .map(|s| {
                     // In macos doc:
@@ -59,11 +53,11 @@ fn find_registrar_symbol(file: &Path) -> Result<Option<String>, IoError> {
                     }
                 })
                 .find(|s| is_derive_registrar_symbol(s))
-                .map(|s| s.to_string());
-            Ok(name)
+                .map(&str::to_owned)
         }
-        _ => Ok(None),
-    }
+        _ => return Ok(None),
+    };
+    return Ok(name);
 }
 
 /// Loads dynamic library in platform dependent manner.
@@ -93,15 +87,16 @@ fn load_library(file: &Path) -> Result<Library, libloading::Error> {
 }
 
 struct ProcMacroLibraryLibloading {
-    // Hold the dylib to prevent it for unloadeding
+    // Hold the dylib to prevent it from unloading
     _lib: Library,
     exported_macros: Vec<bridge::client::ProcMacro>,
 }
 
 impl ProcMacroLibraryLibloading {
-    fn open(file: &Path) -> Result<Self, IoError> {
-        let symbol_name = find_registrar_symbol(file)?
-            .ok_or(invalid_data_err(format!("Cannot find registrar symbol in file {:?}", file)))?;
+    fn open(file: &Path) -> io::Result<Self> {
+        let symbol_name = find_registrar_symbol(file)?.ok_or_else(|| {
+            invalid_data_err(format!("Cannot find registrar symbol in file {}", file.display()))
+        })?;
 
         let lib = load_library(file).map_err(invalid_data_err)?;
         let exported_macros = {
@@ -121,18 +116,16 @@ pub struct Expander {
 }
 
 impl Expander {
-    pub fn new<P: AsRef<Path>>(lib: &P) -> Result<Expander, String> {
-        let mut libs = vec![];
-        /* Some libraries for dynamic loading require canonicalized path (even when it is
-        already absolute
-        */
-        let lib =
-            lib.as_ref().canonicalize().expect(&format!("Cannot canonicalize {:?}", lib.as_ref()));
+    pub fn new(lib: &Path) -> Result<Expander, String> {
+        // Some libraries for dynamic loading require canonicalized path even when it is
+        // already absolute
+        let lib = lib
+            .canonicalize()
+            .unwrap_or_else(|err| panic!("Cannot canonicalize {}: {:?}", lib.display(), err));
 
         let library = ProcMacroLibraryImpl::open(&lib).map_err(|e| e.to_string())?;
-        libs.push(library);
 
-        Ok(Expander { libs })
+        Ok(Expander { libs: vec![library] })
     }
 
     pub fn expand(
@@ -176,7 +169,6 @@ impl Expander {
                             parsed_attributes,
                             parsed_body,
                         );
-
                         return res.map(|it| it.subtree);
                     }
                     _ => continue,
@@ -187,26 +179,21 @@ impl Expander {
         Err(bridge::PanicMessage::String("Nothing to expand".to_string()))
     }
 
-    pub fn list_macros(&self) -> Result<Vec<(String, ProcMacroKind)>, bridge::PanicMessage> {
-        let mut result = vec![];
-
-        for lib in &self.libs {
-            for proc_macro in &lib.exported_macros {
-                let res = match proc_macro {
-                    bridge::client::ProcMacro::CustomDerive { trait_name, .. } => {
-                        (trait_name.to_string(), ProcMacroKind::CustomDerive)
-                    }
-                    bridge::client::ProcMacro::Bang { name, .. } => {
-                        (name.to_string(), ProcMacroKind::FuncLike)
-                    }
-                    bridge::client::ProcMacro::Attr { name, .. } => {
-                        (name.to_string(), ProcMacroKind::Attr)
-                    }
-                };
-                result.push(res);
-            }
-        }
-
-        Ok(result)
+    pub fn list_macros(&self) -> Vec<(String, ProcMacroKind)> {
+        self.libs
+            .iter()
+            .flat_map(|it| &it.exported_macros)
+            .map(|proc_macro| match proc_macro {
+                bridge::client::ProcMacro::CustomDerive { trait_name, .. } => {
+                    (trait_name.to_string(), ProcMacroKind::CustomDerive)
+                }
+                bridge::client::ProcMacro::Bang { name, .. } => {
+                    (name.to_string(), ProcMacroKind::FuncLike)
+                }
+                bridge::client::ProcMacro::Attr { name, .. } => {
+                    (name.to_string(), ProcMacroKind::Attr)
+                }
+            })
+            .collect()
     }
 }
diff --git a/crates/ra_proc_macro_srv/src/lib.rs b/crates/ra_proc_macro_srv/src/lib.rs
index c62b0ed893..3aca859db3 100644
--- a/crates/ra_proc_macro_srv/src/lib.rs
+++ b/crates/ra_proc_macro_srv/src/lib.rs
@@ -3,10 +3,10 @@
 //! This library is able to call compiled Rust custom derive dynamic libraries on arbitrary code.
 //! The general idea here is based on https://github.com/fedochet/rust-proc-macro-expander.
 //!
-//! But we change some several design for fitting RA needs:
+//! But we adapt it to better fit RA needs:
 //!
-//! * We use `ra_tt` for proc-macro `TokenStream` server, it is easy to manipute and interact with
-//!   RA then proc-macro2 token stream.
+//! * We use `ra_tt` for proc-macro `TokenStream` server, it is easier to manipulate and interact with
+//!   RA than `proc-macro2` token stream.
 //! * By **copying** the whole rustc `lib_proc_macro` code, we are able to build this with `stable`
 //!   rustc rather than `unstable`. (Although in gerenal ABI compatibility is still an issue)
 
@@ -21,36 +21,28 @@ mod dylib;
 
 use proc_macro::bridge::client::TokenStream;
 use ra_proc_macro::{ExpansionResult, ExpansionTask, ListMacrosResult, ListMacrosTask};
+use std::path::Path;
 
 pub(crate) fn expand_task(task: &ExpansionTask) -> Result<ExpansionResult, String> {
-    let expander = dylib::Expander::new(&task.lib)
-        .expect(&format!("Cannot expand with provided libraries: ${:?}", &task.lib));
+    let expander = create_expander(&task.lib);
 
     match expander.expand(&task.macro_name, &task.macro_body, task.attributes.as_ref()) {
         Ok(expansion) => Ok(ExpansionResult { expansion }),
         Err(msg) => {
-            let reason = format!(
-                "Cannot perform expansion for {}: error {:?}!",
-                &task.macro_name,
-                msg.as_str()
-            );
-            Err(reason)
+            Err(format!("Cannot perform expansion for {}: error {:?}", &task.macro_name, msg))
         }
     }
 }
 
-pub(crate) fn list_macros(task: &ListMacrosTask) -> Result<ListMacrosResult, String> {
-    let expander = dylib::Expander::new(&task.lib)
-        .expect(&format!("Cannot expand with provided libraries: ${:?}", &task.lib));
+pub(crate) fn list_macros(task: &ListMacrosTask) -> ListMacrosResult {
+    let expander = create_expander(&task.lib);
 
-    match expander.list_macros() {
-        Ok(macros) => Ok(ListMacrosResult { macros }),
-        Err(msg) => {
-            let reason =
-                format!("Cannot perform expansion for {:?}: error {:?}!", &task.lib, msg.as_str());
-            Err(reason)
-        }
-    }
+    ListMacrosResult { macros: expander.list_macros() }
+}
+
+fn create_expander(lib: &Path) -> dylib::Expander {
+    dylib::Expander::new(lib)
+        .unwrap_or_else(|err| panic!("Cannot create expander for {}: {:?}", lib.display(), err))
 }
 
 pub mod cli;
diff --git a/crates/ra_proc_macro_srv/src/rustc_server.rs b/crates/ra_proc_macro_srv/src/rustc_server.rs
index 9fcfdc4504..f481d70b22 100644
--- a/crates/ra_proc_macro_srv/src/rustc_server.rs
+++ b/crates/ra_proc_macro_srv/src/rustc_server.rs
@@ -6,7 +6,7 @@
 //! The original idea from fedochet is using proc-macro2 as backend,
 //! we use ra_tt instead for better intergation with RA.
 //!
-//! FIXME: No span and source file informatin is implemented yet
+//! FIXME: No span and source file information is implemented yet
 
 use crate::proc_macro::bridge::{self, server};
 use ra_tt as tt;
diff --git a/crates/ra_project_model/src/cargo_workspace.rs b/crates/ra_project_model/src/cargo_workspace.rs
index 84008b2e34..b50cda06fd 100644
--- a/crates/ra_project_model/src/cargo_workspace.rs
+++ b/crates/ra_project_model/src/cargo_workspace.rs
@@ -303,7 +303,8 @@ pub fn load_extern_resources(
                     if message.target.kind.contains(&"proc-macro".to_string()) {
                         let package_id = message.package_id;
                         // Skip rmeta file
-                        if let Some(filename) = message.filenames.iter().find(|name| is_dylib(name))
+                        if let Some(filename) =
+                            message.filenames.iter().filter(|name| is_dylib(name)).next()
                         {
                             res.proc_dylib_paths.insert(package_id, filename.clone());
                         }
diff --git a/crates/ra_syntax/src/algo.rs b/crates/ra_syntax/src/algo.rs
index 06df8495c9..ea41bf85d1 100644
--- a/crates/ra_syntax/src/algo.rs
+++ b/crates/ra_syntax/src/algo.rs
@@ -10,8 +10,8 @@ use ra_text_edit::TextEditBuilder;
 use rustc_hash::FxHashMap;
 
 use crate::{
-    AstNode, Direction, NodeOrToken, SyntaxElement, SyntaxKind, SyntaxNode, SyntaxNodePtr,
-    SyntaxToken, TextRange, TextUnit,
+    AstNode, Direction, NodeOrToken, SyntaxElement, SyntaxNode, SyntaxNodePtr, SyntaxToken,
+    TextRange, TextUnit,
 };
 
 /// Returns ancestors of the node at the offset, sorted by length. This should
@@ -90,10 +90,6 @@ pub fn neighbor<T: AstNode>(me: &T, direction: Direction) -> Option<T> {
     me.syntax().siblings(direction).skip(1).find_map(T::cast)
 }
 
-pub fn has_errors(node: &SyntaxNode) -> bool {
-    node.children().any(|it| it.kind() == SyntaxKind::ERROR)
-}
-
 #[derive(Debug, PartialEq, Eq, Clone, Copy)]
 pub enum InsertPosition<T> {
     First,
diff --git a/crates/ra_syntax/src/ast/edit.rs b/crates/ra_syntax/src/ast/edit.rs
index 26e4576ffe..9e5411ee58 100644
--- a/crates/ra_syntax/src/ast/edit.rs
+++ b/crates/ra_syntax/src/ast/edit.rs
@@ -307,11 +307,7 @@ impl ast::UseTree {
 
         fn split_path_prefix(prefix: &ast::Path) -> Option<ast::Path> {
             let parent = prefix.parent_path()?;
-            let segment = parent.segment()?;
-            if algo::has_errors(segment.syntax()) {
-                return None;
-            }
-            let mut res = make::path_unqualified(segment);
+            let mut res = make::path_unqualified(parent.segment()?);
             for p in iter::successors(parent.parent_path(), |it| it.parent_path()) {
                 res = make::path_qualified(res, p.segment()?);
             }
diff --git a/crates/rust-analyzer/src/bin/main.rs b/crates/rust-analyzer/src/bin/main.rs
index 28b67cfe2a..e8d5dad657 100644
--- a/crates/rust-analyzer/src/bin/main.rs
+++ b/crates/rust-analyzer/src/bin/main.rs
@@ -51,7 +51,7 @@ fn main() -> Result<()> {
             cli::diagnostics(path.as_ref(), load_output_dirs, with_proc_macro, all)?
         }
 
-        args::Command::ProcMacro => run_proc_macro_sv()?,
+        args::Command::ProcMacro => run_proc_macro_srv()?,
         args::Command::RunServer => run_server()?,
         args::Command::Version => println!("rust-analyzer {}", env!("REV")),
     }
@@ -65,7 +65,7 @@ fn setup_logging() -> Result<()> {
     Ok(())
 }
 
-fn run_proc_macro_sv() -> Result<()> {
+fn run_proc_macro_srv() -> Result<()> {
     ra_proc_macro_srv::cli::run();
     Ok(())
 }
diff --git a/crates/rust-analyzer/src/cli/load_cargo.rs b/crates/rust-analyzer/src/cli/load_cargo.rs
index 762f776fea..d0a71120aa 100644
--- a/crates/rust-analyzer/src/cli/load_cargo.rs
+++ b/crates/rust-analyzer/src/cli/load_cargo.rs
@@ -76,7 +76,7 @@ pub(crate) fn load_cargo(
         ProcMacroClient::dummy()
     } else {
         let path = std::env::current_exe()?;
-        ProcMacroClient::extern_process(&path, &["proc-macro"]).unwrap()
+        ProcMacroClient::extern_process(path, &["proc-macro"]).unwrap()
     };
     let host = load(&source_roots, ws, &mut vfs, receiver, extern_dirs, &proc_macro_client);
     Ok((host, source_roots))
diff --git a/crates/rust-analyzer/src/world.rs b/crates/rust-analyzer/src/world.rs
index 369578fb6c..d50f3f3d4b 100644
--- a/crates/rust-analyzer/src/world.rs
+++ b/crates/rust-analyzer/src/world.rs
@@ -148,20 +148,17 @@ impl WorldState {
 
         let proc_macro_client = match &config.proc_macro_srv {
             None => ProcMacroClient::dummy(),
-            Some((path, args)) => {
-                let path = std::path::Path::new(path);
-                match ProcMacroClient::extern_process(path, args) {
-                    Ok(it) => it,
-                    Err(err) => {
-                        log::error!(
-                            "Fail to run ra_proc_macro_srv from path {}, error : {}",
-                            path.to_string_lossy(),
-                            err
-                        );
-                        ProcMacroClient::dummy()
-                    }
+            Some((path, args)) => match ProcMacroClient::extern_process(path.into(), args) {
+                Ok(it) => it,
+                Err(err) => {
+                    log::error!(
+                        "Fail to run ra_proc_macro_srv from path {}, error: {:?}",
+                        path,
+                        err
+                    );
+                    ProcMacroClient::dummy()
                 }
-            }
+            },
         };
 
         workspaces
@@ -184,7 +181,7 @@ impl WorldState {
         let mut analysis_host = AnalysisHost::new(lru_capacity);
         analysis_host.apply_change(change);
         WorldState {
-            config,
+            config: config,
             roots: folder_roots,
             workspaces: Arc::new(workspaces),
             analysis_host,


Test patch:
diff --git a/crates/ra_proc_macro_srv/src/tests/utils.rs b/crates/ra_proc_macro_srv/src/tests/utils.rs
index 1ee4094492..2139ec7a4d 100644
--- a/crates/ra_proc_macro_srv/src/tests/utils.rs
+++ b/crates/ra_proc_macro_srv/src/tests/utils.rs
@@ -60,6 +60,6 @@ pub fn list(crate_name: &str, version: &str) -> Vec<String> {
     let path = fixtures::dylib_path(crate_name, version);
     let task = ListMacrosTask { lib: path };
 
-    let res = list_macros(&task).unwrap();
+    let res = list_macros(&task);
     res.macros.into_iter().map(|(name, kind)| format!("{} [{:?}]", name, kind)).collect()
 }