diff options
Diffstat (limited to 'crates')
64 files changed, 382 insertions, 237 deletions
diff --git a/crates/ra_assists/src/ast_editor.rs b/crates/ra_assists/src/ast_editor.rs index cabb3d862..de0529b32 100644 --- a/crates/ra_assists/src/ast_editor.rs +++ b/crates/ra_assists/src/ast_editor.rs | |||
@@ -212,21 +212,17 @@ impl AstEditor<ast::FnDef> { | |||
212 | } | 212 | } |
213 | 213 | ||
214 | pub fn strip_attrs_and_docs(&mut self) { | 214 | pub fn strip_attrs_and_docs(&mut self) { |
215 | loop { | 215 | while let Some(start) = self |
216 | if let Some(start) = self | 216 | .ast() |
217 | .ast() | 217 | .syntax() |
218 | .syntax() | 218 | .children_with_tokens() |
219 | .children_with_tokens() | 219 | .find(|it| it.kind() == ATTR || it.kind() == COMMENT) |
220 | .find(|it| it.kind() == ATTR || it.kind() == COMMENT) | 220 | { |
221 | { | 221 | let end = match start.next_sibling_or_token() { |
222 | let end = match start.next_sibling_or_token() { | 222 | Some(el) if el.kind() == WHITESPACE => el, |
223 | Some(el) if el.kind() == WHITESPACE => el, | 223 | Some(_) | None => start, |
224 | Some(_) | None => start, | 224 | }; |
225 | }; | 225 | self.ast = self.replace_children(RangeInclusive::new(start, end), iter::empty()); |
226 | self.ast = self.replace_children(RangeInclusive::new(start, end), iter::empty()); | ||
227 | } else { | ||
228 | break; | ||
229 | } | ||
230 | } | 226 | } |
231 | } | 227 | } |
232 | } | 228 | } |
diff --git a/crates/ra_assists/src/auto_import.rs b/crates/ra_assists/src/auto_import.rs index 1566cf179..9617beb5c 100644 --- a/crates/ra_assists/src/auto_import.rs +++ b/crates/ra_assists/src/auto_import.rs | |||
@@ -334,7 +334,7 @@ fn best_action_for_target<'b, 'a: 'b>( | |||
334 | .filter_map(ast::UseItem::use_tree) | 334 | .filter_map(ast::UseItem::use_tree) |
335 | .map(|u| walk_use_tree_for_best_action(&mut storage, None, u, target)) | 335 | .map(|u| walk_use_tree_for_best_action(&mut storage, None, u, target)) |
336 | .fold(None, |best, a| { | 336 | .fold(None, |best, a| { |
337 | best.and_then(|best| Some(*ImportAction::better(&best, &a))).or(Some(a)) | 337 | best.and_then(|best| Some(*ImportAction::better(&best, &a))).or_else(|| Some(a)) |
338 | }); | 338 | }); |
339 | 339 | ||
340 | match best_action { | 340 | match best_action { |
@@ -347,7 +347,7 @@ fn best_action_for_target<'b, 'a: 'b>( | |||
347 | let anchor = container | 347 | let anchor = container |
348 | .children() | 348 | .children() |
349 | .find(|n| n.range().start() < anchor.range().start()) | 349 | .find(|n| n.range().start() < anchor.range().start()) |
350 | .or(Some(anchor)); | 350 | .or_else(|| Some(anchor)); |
351 | 351 | ||
352 | return ImportAction::add_new_use(anchor, false); | 352 | return ImportAction::add_new_use(anchor, false); |
353 | } | 353 | } |
diff --git a/crates/ra_assists/src/change_visibility.rs b/crates/ra_assists/src/change_visibility.rs index 620f534b5..4eb24d27f 100644 --- a/crates/ra_assists/src/change_visibility.rs +++ b/crates/ra_assists/src/change_visibility.rs | |||
@@ -59,7 +59,7 @@ fn vis_offset(node: &SyntaxNode) -> TextUnit { | |||
59 | }) | 59 | }) |
60 | .next() | 60 | .next() |
61 | .map(|it| it.range().start()) | 61 | .map(|it| it.range().start()) |
62 | .unwrap_or(node.range().start()) | 62 | .unwrap_or_else(|| node.range().start()) |
63 | } | 63 | } |
64 | 64 | ||
65 | fn change_vis(mut ctx: AssistCtx<impl HirDatabase>, vis: &ast::Visibility) -> Option<Assist> { | 65 | fn change_vis(mut ctx: AssistCtx<impl HirDatabase>, vis: &ast::Visibility) -> Option<Assist> { |
diff --git a/crates/ra_assists/src/introduce_variable.rs b/crates/ra_assists/src/introduce_variable.rs index fb7333c8c..28467d341 100644 --- a/crates/ra_assists/src/introduce_variable.rs +++ b/crates/ra_assists/src/introduce_variable.rs | |||
@@ -57,9 +57,9 @@ pub(crate) fn introduce_variable(mut ctx: AssistCtx<impl HirDatabase>) -> Option | |||
57 | if text.starts_with("\r\n") { | 57 | if text.starts_with("\r\n") { |
58 | buf.push_str("\r\n"); | 58 | buf.push_str("\r\n"); |
59 | buf.push_str(text.trim_start_matches("\r\n")); | 59 | buf.push_str(text.trim_start_matches("\r\n")); |
60 | } else if text.starts_with("\n") { | 60 | } else if text.starts_with('\n') { |
61 | buf.push_str("\n"); | 61 | buf.push_str("\n"); |
62 | buf.push_str(text.trim_start_matches("\n")); | 62 | buf.push_str(text.trim_start_matches('\n')); |
63 | } else { | 63 | } else { |
64 | buf.push_str(text); | 64 | buf.push_str(text); |
65 | } | 65 | } |
diff --git a/crates/ra_batch/src/lib.rs b/crates/ra_batch/src/lib.rs index a4a8462de..a445dcb4d 100644 --- a/crates/ra_batch/src/lib.rs +++ b/crates/ra_batch/src/lib.rs | |||
@@ -34,10 +34,10 @@ impl salsa::Database for BatchDatabase { | |||
34 | } | 34 | } |
35 | 35 | ||
36 | fn vfs_file_to_id(f: ra_vfs::VfsFile) -> FileId { | 36 | fn vfs_file_to_id(f: ra_vfs::VfsFile) -> FileId { |
37 | FileId(f.0.into()) | 37 | FileId(f.0) |
38 | } | 38 | } |
39 | fn vfs_root_to_id(r: ra_vfs::VfsRoot) -> SourceRootId { | 39 | fn vfs_root_to_id(r: ra_vfs::VfsRoot) -> SourceRootId { |
40 | SourceRootId(r.0.into()) | 40 | SourceRootId(r.0) |
41 | } | 41 | } |
42 | 42 | ||
43 | impl BatchDatabase { | 43 | impl BatchDatabase { |
diff --git a/crates/ra_cli/src/analysis_stats.rs b/crates/ra_cli/src/analysis_stats.rs index b481ace9e..8bb524ce3 100644 --- a/crates/ra_cli/src/analysis_stats.rs +++ b/crates/ra_cli/src/analysis_stats.rs | |||
@@ -31,18 +31,16 @@ pub fn run(verbose: bool, path: &str, only: Option<&str>) -> Result<()> { | |||
31 | 31 | ||
32 | for decl in module.declarations(&db) { | 32 | for decl in module.declarations(&db) { |
33 | num_decls += 1; | 33 | num_decls += 1; |
34 | match decl { | 34 | if let ModuleDef::Function(f) = decl { |
35 | ModuleDef::Function(f) => funcs.push(f), | 35 | funcs.push(f); |
36 | _ => {} | ||
37 | } | 36 | } |
38 | } | 37 | } |
39 | 38 | ||
40 | for impl_block in module.impl_blocks(&db) { | 39 | for impl_block in module.impl_blocks(&db) { |
41 | for item in impl_block.items(&db) { | 40 | for item in impl_block.items(&db) { |
42 | num_decls += 1; | 41 | num_decls += 1; |
43 | match item { | 42 | if let ImplItem::Method(f) = item { |
44 | ImplItem::Method(f) => funcs.push(f), | 43 | funcs.push(f); |
45 | _ => {} | ||
46 | } | 44 | } |
47 | } | 45 | } |
48 | } | 46 | } |
diff --git a/crates/ra_hir/src/adt.rs b/crates/ra_hir/src/adt.rs index 45a12dd4d..38ff1d6f6 100644 --- a/crates/ra_hir/src/adt.rs +++ b/crates/ra_hir/src/adt.rs | |||
@@ -36,7 +36,7 @@ impl AdtDef { | |||
36 | 36 | ||
37 | impl Struct { | 37 | impl Struct { |
38 | pub(crate) fn variant_data(&self, db: &impl DefDatabase) -> Arc<VariantData> { | 38 | pub(crate) fn variant_data(&self, db: &impl DefDatabase) -> Arc<VariantData> { |
39 | db.struct_data((*self).into()).variant_data.clone() | 39 | db.struct_data(*self).variant_data.clone() |
40 | } | 40 | } |
41 | } | 41 | } |
42 | 42 | ||
diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs index 9c02b3995..6ee6bd627 100644 --- a/crates/ra_hir/src/code_model.rs +++ b/crates/ra_hir/src/code_model.rs | |||
@@ -281,9 +281,8 @@ impl Module { | |||
281 | 281 | ||
282 | for impl_block in self.impl_blocks(db) { | 282 | for impl_block in self.impl_blocks(db) { |
283 | for item in impl_block.items(db) { | 283 | for item in impl_block.items(db) { |
284 | match item { | 284 | if let crate::ImplItem::Method(f) = item { |
285 | crate::ImplItem::Method(f) => f.diagnostics(db, sink), | 285 | f.diagnostics(db, sink); |
286 | _ => (), | ||
287 | } | 286 | } |
288 | } | 287 | } |
289 | } | 288 | } |
diff --git a/crates/ra_hir/src/diagnostics.rs b/crates/ra_hir/src/diagnostics.rs index 4b7b2dbee..2557ef18e 100644 --- a/crates/ra_hir/src/diagnostics.rs +++ b/crates/ra_hir/src/diagnostics.rs | |||
@@ -87,7 +87,7 @@ impl Diagnostic for NoSuchField { | |||
87 | fn syntax_node_ptr(&self) -> SyntaxNodePtr { | 87 | fn syntax_node_ptr(&self) -> SyntaxNodePtr { |
88 | self.field.into() | 88 | self.field.into() |
89 | } | 89 | } |
90 | fn as_any(&self) -> &(Any + Send + 'static) { | 90 | fn as_any(&self) -> &(dyn Any + Send + 'static) { |
91 | self | 91 | self |
92 | } | 92 | } |
93 | } | 93 | } |
@@ -109,7 +109,7 @@ impl Diagnostic for UnresolvedModule { | |||
109 | fn syntax_node_ptr(&self) -> SyntaxNodePtr { | 109 | fn syntax_node_ptr(&self) -> SyntaxNodePtr { |
110 | self.decl.into() | 110 | self.decl.into() |
111 | } | 111 | } |
112 | fn as_any(&self) -> &(Any + Send + 'static) { | 112 | fn as_any(&self) -> &(dyn Any + Send + 'static) { |
113 | self | 113 | self |
114 | } | 114 | } |
115 | } | 115 | } |
diff --git a/crates/ra_hir/src/expr.rs b/crates/ra_hir/src/expr.rs index 51913d37b..9d9769859 100644 --- a/crates/ra_hir/src/expr.rs +++ b/crates/ra_hir/src/expr.rs | |||
@@ -6,7 +6,7 @@ use rustc_hash::FxHashMap; | |||
6 | use ra_arena::{Arena, RawId, impl_arena_id, map::ArenaMap}; | 6 | use ra_arena::{Arena, RawId, impl_arena_id, map::ArenaMap}; |
7 | use ra_syntax::{ | 7 | use ra_syntax::{ |
8 | SyntaxNodePtr, AstPtr, AstNode, | 8 | SyntaxNodePtr, AstPtr, AstNode, |
9 | ast::{self, LoopBodyOwner, ArgListOwner, NameOwner, LiteralKind,ArrayExprKind, TypeAscriptionOwner}, | 9 | ast::{self, TryBlockBodyOwner, LoopBodyOwner, ArgListOwner, NameOwner, LiteralKind,ArrayExprKind, TypeAscriptionOwner}, |
10 | }; | 10 | }; |
11 | 11 | ||
12 | use crate::{ | 12 | use crate::{ |
@@ -216,6 +216,9 @@ pub enum Expr { | |||
216 | Try { | 216 | Try { |
217 | expr: ExprId, | 217 | expr: ExprId, |
218 | }, | 218 | }, |
219 | TryBlock { | ||
220 | body: ExprId, | ||
221 | }, | ||
219 | Cast { | 222 | Cast { |
220 | expr: ExprId, | 223 | expr: ExprId, |
221 | type_ref: TypeRef, | 224 | type_ref: TypeRef, |
@@ -299,6 +302,7 @@ impl Expr { | |||
299 | f(*expr); | 302 | f(*expr); |
300 | } | 303 | } |
301 | } | 304 | } |
305 | Expr::TryBlock { body } => f(*body), | ||
302 | Expr::Loop { body } => f(*body), | 306 | Expr::Loop { body } => f(*body), |
303 | Expr::While { condition, body } => { | 307 | Expr::While { condition, body } => { |
304 | f(*condition); | 308 | f(*condition); |
@@ -578,6 +582,10 @@ where | |||
578 | self.alloc_expr(Expr::If { condition, then_branch, else_branch }, syntax_ptr) | 582 | self.alloc_expr(Expr::If { condition, then_branch, else_branch }, syntax_ptr) |
579 | } | 583 | } |
580 | } | 584 | } |
585 | ast::ExprKind::TryBlockExpr(e) => { | ||
586 | let body = self.collect_block_opt(e.try_body()); | ||
587 | self.alloc_expr(Expr::TryBlock { body }, syntax_ptr) | ||
588 | } | ||
581 | ast::ExprKind::BlockExpr(e) => self.collect_block_opt(e.block()), | 589 | ast::ExprKind::BlockExpr(e) => self.collect_block_opt(e.block()), |
582 | ast::ExprKind::LoopExpr(e) => { | 590 | ast::ExprKind::LoopExpr(e) => { |
583 | let body = self.collect_block_opt(e.loop_body()); | 591 | let body = self.collect_block_opt(e.loop_body()); |
diff --git a/crates/ra_hir/src/expr/validation.rs b/crates/ra_hir/src/expr/validation.rs index 2816144a7..a1b2641da 100644 --- a/crates/ra_hir/src/expr/validation.rs +++ b/crates/ra_hir/src/expr/validation.rs | |||
@@ -31,11 +31,8 @@ impl<'a, 'b> ExprValidator<'a, 'b> { | |||
31 | pub(crate) fn validate_body(&mut self, db: &impl HirDatabase) { | 31 | pub(crate) fn validate_body(&mut self, db: &impl HirDatabase) { |
32 | let body = self.func.body(db); | 32 | let body = self.func.body(db); |
33 | for e in body.exprs() { | 33 | for e in body.exprs() { |
34 | match e { | 34 | if let (id, Expr::StructLit { path, fields, spread }) = e { |
35 | (id, Expr::StructLit { path, fields, spread }) => { | 35 | self.validate_struct_literal(id, path, fields, spread, db); |
36 | self.validate_struct_literal(id, path, fields, spread, db) | ||
37 | } | ||
38 | _ => (), | ||
39 | } | 36 | } |
40 | } | 37 | } |
41 | } | 38 | } |
@@ -44,7 +41,7 @@ impl<'a, 'b> ExprValidator<'a, 'b> { | |||
44 | &mut self, | 41 | &mut self, |
45 | id: ExprId, | 42 | id: ExprId, |
46 | _path: &Option<Path>, | 43 | _path: &Option<Path>, |
47 | fields: &Vec<StructLitField>, | 44 | fields: &[StructLitField], |
48 | spread: &Option<ExprId>, | 45 | spread: &Option<ExprId>, |
49 | db: &impl HirDatabase, | 46 | db: &impl HirDatabase, |
50 | ) { | 47 | ) { |
@@ -57,7 +54,7 @@ impl<'a, 'b> ExprValidator<'a, 'b> { | |||
57 | _ => return, | 54 | _ => return, |
58 | }; | 55 | }; |
59 | 56 | ||
60 | let lit_fields: FxHashSet<_> = fields.into_iter().map(|f| &f.name).collect(); | 57 | let lit_fields: FxHashSet<_> = fields.iter().map(|f| &f.name).collect(); |
61 | let missed_fields: Vec<Name> = struct_def | 58 | let missed_fields: Vec<Name> = struct_def |
62 | .fields(db) | 59 | .fields(db) |
63 | .iter() | 60 | .iter() |
diff --git a/crates/ra_hir/src/impl_block.rs b/crates/ra_hir/src/impl_block.rs index ba90e67e9..a0d3b33fe 100644 --- a/crates/ra_hir/src/impl_block.rs +++ b/crates/ra_hir/src/impl_block.rs | |||
@@ -202,7 +202,6 @@ impl ModuleImplBlocks { | |||
202 | }; | 202 | }; |
203 | 203 | ||
204 | let (file_id, module_source) = m.module.definition_source(db); | 204 | let (file_id, module_source) = m.module.definition_source(db); |
205 | let file_id: HirFileId = file_id.into(); | ||
206 | let node = match &module_source { | 205 | let node = match &module_source { |
207 | ModuleSource::SourceFile(node) => node.syntax(), | 206 | ModuleSource::SourceFile(node) => node.syntax(), |
208 | ModuleSource::Module(node) => { | 207 | ModuleSource::Module(node) => { |
diff --git a/crates/ra_hir/src/lang_item.rs b/crates/ra_hir/src/lang_item.rs index 4cacaeba4..684fbc068 100644 --- a/crates/ra_hir/src/lang_item.rs +++ b/crates/ra_hir/src/lang_item.rs | |||
@@ -95,7 +95,7 @@ impl LangItems { | |||
95 | .nth(0); | 95 | .nth(0); |
96 | if let Some(lang_item_name) = lang_item_name { | 96 | if let Some(lang_item_name) = lang_item_name { |
97 | let imp = ImplBlock::from_id(*module, impl_id); | 97 | let imp = ImplBlock::from_id(*module, impl_id); |
98 | self.items.entry(lang_item_name).or_insert(LangItemTarget::ImplBlock(imp)); | 98 | self.items.entry(lang_item_name).or_insert_with(|| LangItemTarget::ImplBlock(imp)); |
99 | } | 99 | } |
100 | } | 100 | } |
101 | 101 | ||
diff --git a/crates/ra_hir/src/nameres.rs b/crates/ra_hir/src/nameres.rs index d649aa820..8b798d6c9 100644 --- a/crates/ra_hir/src/nameres.rs +++ b/crates/ra_hir/src/nameres.rs | |||
@@ -332,7 +332,8 @@ impl CrateDefMap { | |||
332 | let name = path.expand_macro_expr()?; | 332 | let name = path.expand_macro_expr()?; |
333 | // search local first | 333 | // search local first |
334 | // FIXME: Remove public_macros check when we have a correct local_macors implementation | 334 | // FIXME: Remove public_macros check when we have a correct local_macors implementation |
335 | let local = self.public_macros.get(&name).or(self.local_macros.get(&name)).map(|it| *it); | 335 | let local = |
336 | self.public_macros.get(&name).or_else(|| self.local_macros.get(&name)).map(|it| *it); | ||
336 | if local.is_some() { | 337 | if local.is_some() { |
337 | return local; | 338 | return local; |
338 | } | 339 | } |
@@ -405,7 +406,7 @@ impl CrateDefMap { | |||
405 | }; | 406 | }; |
406 | 407 | ||
407 | for (i, segment) in segments { | 408 | for (i, segment) in segments { |
408 | let curr = match curr_per_ns.as_ref().left().map_or(None, |m| m.as_ref().take_types()) { | 409 | let curr = match curr_per_ns.as_ref().left().and_then(|m| m.as_ref().take_types()) { |
409 | Some(r) => r, | 410 | Some(r) => r, |
410 | None => { | 411 | None => { |
411 | // we still have path segments left, but the path so far | 412 | // we still have path segments left, but the path so far |
@@ -421,10 +422,8 @@ impl CrateDefMap { | |||
421 | curr_per_ns = match curr { | 422 | curr_per_ns = match curr { |
422 | ModuleDef::Module(module) => { | 423 | ModuleDef::Module(module) => { |
423 | if module.krate != self.krate { | 424 | if module.krate != self.krate { |
424 | let path = Path { | 425 | let path = |
425 | segments: path.segments[i..].iter().cloned().collect(), | 426 | Path { segments: path.segments[i..].to_vec(), kind: PathKind::Self_ }; |
426 | kind: PathKind::Self_, | ||
427 | }; | ||
428 | log::debug!("resolving {:?} in other crate", path); | 427 | log::debug!("resolving {:?} in other crate", path); |
429 | let defp_map = db.crate_def_map(module.krate); | 428 | let defp_map = db.crate_def_map(module.krate); |
430 | let (def, s) = | 429 | let (def, s) = |
@@ -468,7 +467,7 @@ impl CrateDefMap { | |||
468 | ); | 467 | ); |
469 | 468 | ||
470 | return ResolvePathResult::with( | 469 | return ResolvePathResult::with( |
471 | Either::Left(PerNs::types((*s).into())), | 470 | Either::Left(PerNs::types(*s)), |
472 | ReachedFixedPoint::Yes, | 471 | ReachedFixedPoint::Yes, |
473 | Some(i), | 472 | Some(i), |
474 | ); | 473 | ); |
@@ -479,8 +478,10 @@ impl CrateDefMap { | |||
479 | } | 478 | } |
480 | 479 | ||
481 | fn resolve_name_in_crate_root_or_extern_prelude(&self, name: &Name) -> ItemOrMacro { | 480 | fn resolve_name_in_crate_root_or_extern_prelude(&self, name: &Name) -> ItemOrMacro { |
482 | let from_crate_root = | 481 | let from_crate_root = self[self.root] |
483 | self[self.root].scope.get_item_or_macro(name).unwrap_or(Either::Left(PerNs::none())); | 482 | .scope |
483 | .get_item_or_macro(name) | ||
484 | .unwrap_or_else(|| Either::Left(PerNs::none())); | ||
484 | let from_extern_prelude = self.resolve_name_in_extern_prelude(name); | 485 | let from_extern_prelude = self.resolve_name_in_extern_prelude(name); |
485 | 486 | ||
486 | or(from_crate_root, Either::Left(from_extern_prelude)) | 487 | or(from_crate_root, Either::Left(from_extern_prelude)) |
@@ -505,8 +506,10 @@ impl CrateDefMap { | |||
505 | // - current module / scope | 506 | // - current module / scope |
506 | // - extern prelude | 507 | // - extern prelude |
507 | // - std prelude | 508 | // - std prelude |
508 | let from_scope = | 509 | let from_scope = self[module] |
509 | self[module].scope.get_item_or_macro(name).unwrap_or(Either::Left(PerNs::none()));; | 510 | .scope |
511 | .get_item_or_macro(name) | ||
512 | .unwrap_or_else(|| Either::Left(PerNs::none()));; | ||
510 | let from_extern_prelude = | 513 | let from_extern_prelude = |
511 | self.extern_prelude.get(name).map_or(PerNs::none(), |&it| PerNs::types(it)); | 514 | self.extern_prelude.get(name).map_or(PerNs::none(), |&it| PerNs::types(it)); |
512 | let from_prelude = self.resolve_in_prelude(db, name); | 515 | let from_prelude = self.resolve_in_prelude(db, name); |
@@ -525,7 +528,7 @@ impl CrateDefMap { | |||
525 | } else { | 528 | } else { |
526 | db.crate_def_map(prelude.krate)[prelude.module_id].scope.get_item_or_macro(name) | 529 | db.crate_def_map(prelude.krate)[prelude.module_id].scope.get_item_or_macro(name) |
527 | }; | 530 | }; |
528 | resolution.unwrap_or(Either::Left(PerNs::none())) | 531 | resolution.unwrap_or_else(|| Either::Left(PerNs::none())) |
529 | } else { | 532 | } else { |
530 | Either::Left(PerNs::none()) | 533 | Either::Left(PerNs::none()) |
531 | } | 534 | } |
diff --git a/crates/ra_hir/src/nameres/collector.rs b/crates/ra_hir/src/nameres/collector.rs index 693c3fe8e..3bfef799d 100644 --- a/crates/ra_hir/src/nameres/collector.rs +++ b/crates/ra_hir/src/nameres/collector.rs | |||
@@ -556,7 +556,7 @@ where | |||
556 | 556 | ||
557 | fn define_def(&mut self, def: &raw::DefData) { | 557 | fn define_def(&mut self, def: &raw::DefData) { |
558 | let module = Module { krate: self.def_collector.def_map.krate, module_id: self.module_id }; | 558 | let module = Module { krate: self.def_collector.def_map.krate, module_id: self.module_id }; |
559 | let ctx = LocationCtx::new(self.def_collector.db, module, self.file_id.into()); | 559 | let ctx = LocationCtx::new(self.def_collector.db, module, self.file_id); |
560 | 560 | ||
561 | macro_rules! def { | 561 | macro_rules! def { |
562 | ($kind:ident, $ast_id:ident) => { | 562 | ($kind:ident, $ast_id:ident) => { |
diff --git a/crates/ra_hir/src/nameres/raw.rs b/crates/ra_hir/src/nameres/raw.rs index 21935dbb9..a0afe282c 100644 --- a/crates/ra_hir/src/nameres/raw.rs +++ b/crates/ra_hir/src/nameres/raw.rs | |||
@@ -69,7 +69,7 @@ impl RawItems { | |||
69 | ) -> (Arc<RawItems>, Arc<ImportSourceMap>) { | 69 | ) -> (Arc<RawItems>, Arc<ImportSourceMap>) { |
70 | let mut collector = RawItemsCollector { | 70 | let mut collector = RawItemsCollector { |
71 | raw_items: RawItems::default(), | 71 | raw_items: RawItems::default(), |
72 | source_ast_id_map: db.ast_id_map(file_id.into()), | 72 | source_ast_id_map: db.ast_id_map(file_id), |
73 | source_map: ImportSourceMap::default(), | 73 | source_map: ImportSourceMap::default(), |
74 | }; | 74 | }; |
75 | if let Some(node) = db.parse_or_expand(file_id) { | 75 | if let Some(node) = db.parse_or_expand(file_id) { |
diff --git a/crates/ra_hir/src/path.rs b/crates/ra_hir/src/path.rs index 1b129c752..67afd5027 100644 --- a/crates/ra_hir/src/path.rs +++ b/crates/ra_hir/src/path.rs | |||
@@ -116,7 +116,7 @@ impl Path { | |||
116 | 116 | ||
117 | /// `true` if this path is just a standalone `self` | 117 | /// `true` if this path is just a standalone `self` |
118 | pub fn is_self(&self) -> bool { | 118 | pub fn is_self(&self) -> bool { |
119 | self.kind == PathKind::Self_ && self.segments.len() == 0 | 119 | self.kind == PathKind::Self_ && self.segments.is_empty() |
120 | } | 120 | } |
121 | 121 | ||
122 | /// If this path is a single identifier, like `foo`, return its name. | 122 | /// If this path is a single identifier, like `foo`, return its name. |
@@ -140,7 +140,7 @@ impl GenericArgs { | |||
140 | args.push(GenericArg::Type(type_ref)); | 140 | args.push(GenericArg::Type(type_ref)); |
141 | } | 141 | } |
142 | // lifetimes and assoc type args ignored for now | 142 | // lifetimes and assoc type args ignored for now |
143 | if args.len() > 0 { | 143 | if !args.is_empty() { |
144 | Some(GenericArgs { args }) | 144 | Some(GenericArgs { args }) |
145 | } else { | 145 | } else { |
146 | None | 146 | None |
diff --git a/crates/ra_hir/src/source_binder.rs b/crates/ra_hir/src/source_binder.rs index 75ed2de6c..6a5799622 100644 --- a/crates/ra_hir/src/source_binder.rs +++ b/crates/ra_hir/src/source_binder.rs | |||
@@ -48,8 +48,8 @@ pub fn module_from_declaration( | |||
48 | pub fn module_from_position(db: &impl HirDatabase, position: FilePosition) -> Option<Module> { | 48 | pub fn module_from_position(db: &impl HirDatabase, position: FilePosition) -> Option<Module> { |
49 | let file = db.parse(position.file_id).tree; | 49 | let file = db.parse(position.file_id).tree; |
50 | match find_node_at_offset::<ast::Module>(file.syntax(), position.offset) { | 50 | match find_node_at_offset::<ast::Module>(file.syntax(), position.offset) { |
51 | Some(m) if !m.has_semi() => module_from_inline(db, position.file_id.into(), m), | 51 | Some(m) if !m.has_semi() => module_from_inline(db, position.file_id, m), |
52 | _ => module_from_file_id(db, position.file_id.into()), | 52 | _ => module_from_file_id(db, position.file_id), |
53 | } | 53 | } |
54 | } | 54 | } |
55 | 55 | ||
@@ -72,9 +72,9 @@ pub fn module_from_child_node( | |||
72 | child: &SyntaxNode, | 72 | child: &SyntaxNode, |
73 | ) -> Option<Module> { | 73 | ) -> Option<Module> { |
74 | if let Some(m) = child.ancestors().filter_map(ast::Module::cast).find(|it| !it.has_semi()) { | 74 | if let Some(m) = child.ancestors().filter_map(ast::Module::cast).find(|it| !it.has_semi()) { |
75 | module_from_inline(db, file_id.into(), m) | 75 | module_from_inline(db, file_id, m) |
76 | } else { | 76 | } else { |
77 | module_from_file_id(db, file_id.into()) | 77 | module_from_file_id(db, file_id) |
78 | } | 78 | } |
79 | } | 79 | } |
80 | 80 | ||
@@ -99,14 +99,12 @@ pub fn struct_from_module( | |||
99 | struct_def: &ast::StructDef, | 99 | struct_def: &ast::StructDef, |
100 | ) -> Struct { | 100 | ) -> Struct { |
101 | let (file_id, _) = module.definition_source(db); | 101 | let (file_id, _) = module.definition_source(db); |
102 | let file_id = file_id.into(); | ||
103 | let ctx = LocationCtx::new(db, module, file_id); | 102 | let ctx = LocationCtx::new(db, module, file_id); |
104 | Struct { id: ctx.to_def(struct_def) } | 103 | Struct { id: ctx.to_def(struct_def) } |
105 | } | 104 | } |
106 | 105 | ||
107 | pub fn enum_from_module(db: &impl HirDatabase, module: Module, enum_def: &ast::EnumDef) -> Enum { | 106 | pub fn enum_from_module(db: &impl HirDatabase, module: Module, enum_def: &ast::EnumDef) -> Enum { |
108 | let (file_id, _) = module.definition_source(db); | 107 | let (file_id, _) = module.definition_source(db); |
109 | let file_id = file_id.into(); | ||
110 | let ctx = LocationCtx::new(db, module, file_id); | 108 | let ctx = LocationCtx::new(db, module, file_id); |
111 | Enum { id: ctx.to_def(enum_def) } | 109 | Enum { id: ctx.to_def(enum_def) } |
112 | } | 110 | } |
@@ -117,7 +115,6 @@ pub fn trait_from_module( | |||
117 | trait_def: &ast::TraitDef, | 115 | trait_def: &ast::TraitDef, |
118 | ) -> Trait { | 116 | ) -> Trait { |
119 | let (file_id, _) = module.definition_source(db); | 117 | let (file_id, _) = module.definition_source(db); |
120 | let file_id = file_id.into(); | ||
121 | let ctx = LocationCtx::new(db, module, file_id); | 118 | let ctx = LocationCtx::new(db, module, file_id); |
122 | Trait { id: ctx.to_def(trait_def) } | 119 | Trait { id: ctx.to_def(trait_def) } |
123 | } | 120 | } |
diff --git a/crates/ra_hir/src/traits.rs b/crates/ra_hir/src/traits.rs index 2a7c2b791..967654e97 100644 --- a/crates/ra_hir/src/traits.rs +++ b/crates/ra_hir/src/traits.rs | |||
@@ -77,13 +77,10 @@ impl TraitItemsIndex { | |||
77 | pub(crate) fn trait_items_index(db: &impl DefDatabase, module: Module) -> TraitItemsIndex { | 77 | pub(crate) fn trait_items_index(db: &impl DefDatabase, module: Module) -> TraitItemsIndex { |
78 | let mut index = TraitItemsIndex { traits_by_def: FxHashMap::default() }; | 78 | let mut index = TraitItemsIndex { traits_by_def: FxHashMap::default() }; |
79 | for decl in module.declarations(db) { | 79 | for decl in module.declarations(db) { |
80 | match decl { | 80 | if let crate::ModuleDef::Trait(tr) = decl { |
81 | crate::ModuleDef::Trait(tr) => { | 81 | for item in tr.trait_data(db).items() { |
82 | for item in tr.trait_data(db).items() { | 82 | index.traits_by_def.insert(*item, tr); |
83 | index.traits_by_def.insert(*item, tr); | ||
84 | } | ||
85 | } | 83 | } |
86 | _ => {} | ||
87 | } | 84 | } |
88 | } | 85 | } |
89 | index | 86 | index |
diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs index 76d34c12b..4a37e0268 100644 --- a/crates/ra_hir/src/ty.rs +++ b/crates/ra_hir/src/ty.rs | |||
@@ -451,7 +451,7 @@ impl Ty { | |||
451 | /// Substitutes `Ty::Bound` vars (as opposed to type parameters). | 451 | /// Substitutes `Ty::Bound` vars (as opposed to type parameters). |
452 | pub fn subst_bound_vars(self, substs: &Substs) -> Ty { | 452 | pub fn subst_bound_vars(self, substs: &Substs) -> Ty { |
453 | self.fold(&mut |ty| match ty { | 453 | self.fold(&mut |ty| match ty { |
454 | Ty::Bound(idx) => substs.get(idx as usize).cloned().unwrap_or(Ty::Bound(idx)), | 454 | Ty::Bound(idx) => substs.get(idx as usize).cloned().unwrap_or_else(|| Ty::Bound(idx)), |
455 | ty => ty, | 455 | ty => ty, |
456 | }) | 456 | }) |
457 | } | 457 | } |
diff --git a/crates/ra_hir/src/ty/infer.rs b/crates/ra_hir/src/ty/infer.rs index e8ae33ead..6cc5dbc6f 100644 --- a/crates/ra_hir/src/ty/infer.rs +++ b/crates/ra_hir/src/ty/infer.rs | |||
@@ -462,7 +462,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
462 | let mut resolved = | 462 | let mut resolved = |
463 | if remaining_index.is_none() { def.take_values()? } else { def.take_types()? }; | 463 | if remaining_index.is_none() { def.take_values()? } else { def.take_types()? }; |
464 | 464 | ||
465 | let remaining_index = remaining_index.unwrap_or(path.segments.len()); | 465 | let remaining_index = remaining_index.unwrap_or_else(|| path.segments.len()); |
466 | let mut actual_def_ty: Option<Ty> = None; | 466 | let mut actual_def_ty: Option<Ty> = None; |
467 | 467 | ||
468 | let krate = resolver.krate()?; | 468 | let krate = resolver.krate()?; |
@@ -539,7 +539,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
539 | } | 539 | } |
540 | })?; | 540 | })?; |
541 | 541 | ||
542 | resolved = Resolution::Def(item.into()); | 542 | resolved = Resolution::Def(item); |
543 | } | 543 | } |
544 | 544 | ||
545 | match resolved { | 545 | match resolved { |
@@ -762,7 +762,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
762 | _ => &Ty::Unknown, | 762 | _ => &Ty::Unknown, |
763 | }; | 763 | }; |
764 | let subty = self.infer_pat(*pat, expectation, default_bm); | 764 | let subty = self.infer_pat(*pat, expectation, default_bm); |
765 | Ty::apply_one(TypeCtor::Ref(*mutability), subty.into()) | 765 | Ty::apply_one(TypeCtor::Ref(*mutability), subty) |
766 | } | 766 | } |
767 | Pat::TupleStruct { path: ref p, args: ref subpats } => { | 767 | Pat::TupleStruct { path: ref p, args: ref subpats } => { |
768 | self.infer_tuple_struct_pat(p.as_ref(), subpats, expected, default_bm) | 768 | self.infer_tuple_struct_pat(p.as_ref(), subpats, expected, default_bm) |
@@ -790,7 +790,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
790 | 790 | ||
791 | let bound_ty = match mode { | 791 | let bound_ty = match mode { |
792 | BindingMode::Ref(mutability) => { | 792 | BindingMode::Ref(mutability) => { |
793 | Ty::apply_one(TypeCtor::Ref(mutability), inner_ty.clone().into()) | 793 | Ty::apply_one(TypeCtor::Ref(mutability), inner_ty.clone()) |
794 | } | 794 | } |
795 | BindingMode::Move => inner_ty.clone(), | 795 | BindingMode::Move => inner_ty.clone(), |
796 | }; | 796 | }; |
@@ -848,28 +848,23 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
848 | } | 848 | } |
849 | 849 | ||
850 | fn register_obligations_for_call(&mut self, callable_ty: &Ty) { | 850 | fn register_obligations_for_call(&mut self, callable_ty: &Ty) { |
851 | match callable_ty { | 851 | if let Ty::Apply(a_ty) = callable_ty { |
852 | Ty::Apply(a_ty) => match a_ty.ctor { | 852 | if let TypeCtor::FnDef(def) = a_ty.ctor { |
853 | TypeCtor::FnDef(def) => { | 853 | // add obligation for trait implementation, if this is a trait method |
854 | // add obligation for trait implementation, if this is a trait method | 854 | // FIXME also register obligations from where clauses from the trait or impl and method |
855 | // FIXME also register obligations from where clauses from the trait or impl and method | 855 | match def { |
856 | match def { | 856 | CallableDef::Function(f) => { |
857 | CallableDef::Function(f) => { | 857 | if let Some(trait_) = f.parent_trait(self.db) { |
858 | if let Some(trait_) = f.parent_trait(self.db) { | 858 | // construct a TraitDef |
859 | // construct a TraitDef | 859 | let substs = a_ty.parameters.prefix( |
860 | let substs = a_ty.parameters.prefix( | 860 | trait_.generic_params(self.db).count_params_including_parent(), |
861 | trait_.generic_params(self.db).count_params_including_parent(), | 861 | ); |
862 | ); | 862 | self.obligations.push(Obligation::Trait(TraitRef { trait_, substs })); |
863 | self.obligations | ||
864 | .push(Obligation::Trait(TraitRef { trait_, substs })); | ||
865 | } | ||
866 | } | 863 | } |
867 | CallableDef::Struct(_) | CallableDef::EnumVariant(_) => {} | ||
868 | } | 864 | } |
865 | CallableDef::Struct(_) | CallableDef::EnumVariant(_) => {} | ||
869 | } | 866 | } |
870 | _ => {} | 867 | } |
871 | }, | ||
872 | _ => {} | ||
873 | } | 868 | } |
874 | } | 869 | } |
875 | 870 | ||
@@ -951,6 +946,11 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
951 | then_ty | 946 | then_ty |
952 | } | 947 | } |
953 | Expr::Block { statements, tail } => self.infer_block(statements, *tail, expected), | 948 | Expr::Block { statements, tail } => self.infer_block(statements, *tail, expected), |
949 | Expr::TryBlock { body } => { | ||
950 | let _inner = self.infer_expr(*body, expected); | ||
951 | // FIXME should be std::result::Result<{inner}, _> | ||
952 | Ty::Unknown | ||
953 | } | ||
954 | Expr::Loop { body } => { | 954 | Expr::Loop { body } => { |
955 | self.infer_expr(*body, &Expectation::has_type(Ty::unit())); | 955 | self.infer_expr(*body, &Expectation::has_type(Ty::unit())); |
956 | // FIXME handle break with value | 956 | // FIXME handle break with value |
@@ -1049,7 +1049,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { | |||
1049 | Expr::StructLit { path, fields, spread } => { | 1049 | Expr::StructLit { path, fields, spread } => { |
1050 | let (ty, def_id) = self.resolve_variant(path.as_ref()); | 1050 | let (ty, def_id) = self.resolve_variant(path.as_ref()); |
1051 | let substs = ty.substs().unwrap_or_else(Substs::empty); | 1051 | let substs = ty.substs().unwrap_or_else(Substs::empty); |
1052 | for (field_idx, field) in fields.into_iter().enumerate() { | 1052 | for (field_idx, field) in fields.iter().enumerate() { |
1053 | let field_ty = def_id | 1053 | let field_ty = def_id |
1054 | .and_then(|it| match it.field(self.db, &field.name) { | 1054 | .and_then(|it| match it.field(self.db, &field.name) { |
1055 | Some(field) => Some(field), | 1055 | Some(field) => Some(field), |
diff --git a/crates/ra_hir/src/ty/method_resolution.rs b/crates/ra_hir/src/ty/method_resolution.rs index 34817a5ec..646e58aa9 100644 --- a/crates/ra_hir/src/ty/method_resolution.rs +++ b/crates/ra_hir/src/ty/method_resolution.rs | |||
@@ -192,23 +192,20 @@ fn iterate_trait_method_candidates<T>( | |||
192 | // iteration | 192 | // iteration |
193 | let mut known_implemented = false; | 193 | let mut known_implemented = false; |
194 | for item in data.items() { | 194 | for item in data.items() { |
195 | match item { | 195 | if let TraitItem::Function(m) = *item { |
196 | &TraitItem::Function(m) => { | 196 | let sig = m.signature(db); |
197 | let sig = m.signature(db); | 197 | if name.map_or(true, |name| sig.name() == name) && sig.has_self_param() { |
198 | if name.map_or(true, |name| sig.name() == name) && sig.has_self_param() { | 198 | if !known_implemented { |
199 | if !known_implemented { | 199 | let trait_ref = canonical_trait_ref(db, t, ty.clone()); |
200 | let trait_ref = canonical_trait_ref(db, t, ty.clone()); | 200 | if db.implements(krate, trait_ref).is_none() { |
201 | if db.implements(krate, trait_ref).is_none() { | 201 | continue 'traits; |
202 | continue 'traits; | ||
203 | } | ||
204 | } | ||
205 | known_implemented = true; | ||
206 | if let Some(result) = callback(&ty.value, m) { | ||
207 | return Some(result); | ||
208 | } | 202 | } |
209 | } | 203 | } |
204 | known_implemented = true; | ||
205 | if let Some(result) = callback(&ty.value, m) { | ||
206 | return Some(result); | ||
207 | } | ||
210 | } | 208 | } |
211 | _ => {} | ||
212 | } | 209 | } |
213 | } | 210 | } |
214 | } | 211 | } |
@@ -230,16 +227,13 @@ fn iterate_inherent_methods<T>( | |||
230 | 227 | ||
231 | for impl_block in impls.lookup_impl_blocks(&ty.value) { | 228 | for impl_block in impls.lookup_impl_blocks(&ty.value) { |
232 | for item in impl_block.items(db) { | 229 | for item in impl_block.items(db) { |
233 | match item { | 230 | if let ImplItem::Method(f) = item { |
234 | ImplItem::Method(f) => { | 231 | let sig = f.signature(db); |
235 | let sig = f.signature(db); | 232 | if name.map_or(true, |name| sig.name() == name) && sig.has_self_param() { |
236 | if name.map_or(true, |name| sig.name() == name) && sig.has_self_param() { | 233 | if let Some(result) = callback(&ty.value, f) { |
237 | if let Some(result) = callback(&ty.value, f) { | 234 | return Some(result); |
238 | return Some(result); | ||
239 | } | ||
240 | } | 235 | } |
241 | } | 236 | } |
242 | _ => {} | ||
243 | } | 237 | } |
244 | } | 238 | } |
245 | } | 239 | } |
diff --git a/crates/ra_hir/src/ty/traits/chalk.rs b/crates/ra_hir/src/ty/traits/chalk.rs index 78440b258..1e4806db0 100644 --- a/crates/ra_hir/src/ty/traits/chalk.rs +++ b/crates/ra_hir/src/ty/traits/chalk.rs | |||
@@ -211,13 +211,10 @@ fn convert_where_clauses( | |||
211 | // anyway), otherwise Chalk can easily get into slow situations | 211 | // anyway), otherwise Chalk can easily get into slow situations |
212 | return vec![pred.clone().subst(substs).to_chalk(db)]; | 212 | return vec![pred.clone().subst(substs).to_chalk(db)]; |
213 | } | 213 | } |
214 | match pred { | 214 | if let GenericPredicate::Implemented(trait_ref) = pred { |
215 | GenericPredicate::Implemented(trait_ref) => { | 215 | if blacklisted_trait(db, trait_ref.trait_) { |
216 | if blacklisted_trait(db, trait_ref.trait_) { | 216 | continue; |
217 | continue; | ||
218 | } | ||
219 | } | 217 | } |
220 | _ => {} | ||
221 | } | 218 | } |
222 | result.push(pred.clone().subst(substs).to_chalk(db)); | 219 | result.push(pred.clone().subst(substs).to_chalk(db)); |
223 | } | 220 | } |
diff --git a/crates/ra_ide_api/src/call_info.rs b/crates/ra_ide_api/src/call_info.rs index 5d43282fd..bd08e183d 100644 --- a/crates/ra_ide_api/src/call_info.rs +++ b/crates/ra_ide_api/src/call_info.rs | |||
@@ -21,8 +21,7 @@ pub(crate) fn call_info(db: &RootDatabase, position: FilePosition) -> Option<Cal | |||
21 | let function = match calling_node { | 21 | let function = match calling_node { |
22 | FnCallNode::CallExpr(expr) => { | 22 | FnCallNode::CallExpr(expr) => { |
23 | //FIXME: apply subst | 23 | //FIXME: apply subst |
24 | let (callable_def, _subst) = | 24 | let (callable_def, _subst) = analyzer.type_of(db, expr.expr()?)?.as_callable()?; |
25 | analyzer.type_of(db, expr.expr()?.into())?.as_callable()?; | ||
26 | match callable_def { | 25 | match callable_def { |
27 | hir::CallableDef::Function(it) => it, | 26 | hir::CallableDef::Function(it) => it, |
28 | //FIXME: handle other callables | 27 | //FIXME: handle other callables |
@@ -64,7 +63,7 @@ pub(crate) fn call_info(db: &RootDatabase, position: FilePosition) -> Option<Cal | |||
64 | 63 | ||
65 | // If we are in a method account for `self` | 64 | // If we are in a method account for `self` |
66 | if has_self { | 65 | if has_self { |
67 | param = param + 1; | 66 | param += 1; |
68 | } | 67 | } |
69 | 68 | ||
70 | call_info.active_parameter = Some(param); | 69 | call_info.active_parameter = Some(param); |
diff --git a/crates/ra_ide_api/src/completion/complete_dot.rs b/crates/ra_ide_api/src/completion/complete_dot.rs index 5bf289c63..0822a0e7e 100644 --- a/crates/ra_ide_api/src/completion/complete_dot.rs +++ b/crates/ra_ide_api/src/completion/complete_dot.rs | |||
@@ -16,8 +16,8 @@ pub(super) fn complete_dot(acc: &mut Completions, ctx: &CompletionContext) { | |||
16 | 16 | ||
17 | fn complete_fields(acc: &mut Completions, ctx: &CompletionContext, receiver: Ty) { | 17 | fn complete_fields(acc: &mut Completions, ctx: &CompletionContext, receiver: Ty) { |
18 | for receiver in receiver.autoderef(ctx.db) { | 18 | for receiver in receiver.autoderef(ctx.db) { |
19 | match receiver { | 19 | if let Ty::Apply(a_ty) = receiver { |
20 | Ty::Apply(a_ty) => match a_ty.ctor { | 20 | match a_ty.ctor { |
21 | TypeCtor::Adt(AdtDef::Struct(s)) => { | 21 | TypeCtor::Adt(AdtDef::Struct(s)) => { |
22 | for field in s.fields(ctx.db) { | 22 | for field in s.fields(ctx.db) { |
23 | acc.add_field(ctx, field, &a_ty.parameters); | 23 | acc.add_field(ctx, field, &a_ty.parameters); |
@@ -30,8 +30,7 @@ fn complete_fields(acc: &mut Completions, ctx: &CompletionContext, receiver: Ty) | |||
30 | } | 30 | } |
31 | } | 31 | } |
32 | _ => {} | 32 | _ => {} |
33 | }, | 33 | } |
34 | _ => {} | ||
35 | }; | 34 | }; |
36 | } | 35 | } |
37 | } | 36 | } |
diff --git a/crates/ra_ide_api/src/completion/complete_pattern.rs b/crates/ra_ide_api/src/completion/complete_pattern.rs index 74833a756..6655a05a7 100644 --- a/crates/ra_ide_api/src/completion/complete_pattern.rs +++ b/crates/ra_ide_api/src/completion/complete_pattern.rs | |||
@@ -10,7 +10,7 @@ pub(super) fn complete_pattern(acc: &mut Completions, ctx: &CompletionContext) { | |||
10 | let names = ctx.analyzer.all_names(ctx.db); | 10 | let names = ctx.analyzer.all_names(ctx.db); |
11 | for (name, res) in names.into_iter() { | 11 | for (name, res) in names.into_iter() { |
12 | let r = res.as_ref(); | 12 | let r = res.as_ref(); |
13 | let def = match r.take_types().or(r.take_values()) { | 13 | let def = match r.take_types().or_else(|| r.take_values()) { |
14 | Some(hir::Resolution::Def(def)) => def, | 14 | Some(hir::Resolution::Def(def)) => def, |
15 | _ => continue, | 15 | _ => continue, |
16 | }; | 16 | }; |
diff --git a/crates/ra_ide_api/src/completion/complete_scope.rs b/crates/ra_ide_api/src/completion/complete_scope.rs index 2473e58b4..0f8cfaae8 100644 --- a/crates/ra_ide_api/src/completion/complete_scope.rs +++ b/crates/ra_ide_api/src/completion/complete_scope.rs | |||
@@ -49,7 +49,7 @@ pub(super) fn complete_scope(acc: &mut Completions, ctx: &CompletionContext) { | |||
49 | } | 49 | } |
50 | } | 50 | } |
51 | 51 | ||
52 | fn build_import_label(name: &str, path: &Vec<SmolStr>) -> String { | 52 | fn build_import_label(name: &str, path: &[SmolStr]) -> String { |
53 | let mut buf = String::with_capacity(64); | 53 | let mut buf = String::with_capacity(64); |
54 | buf.push_str(name); | 54 | buf.push_str(name); |
55 | buf.push_str(" ("); | 55 | buf.push_str(" ("); |
@@ -58,7 +58,7 @@ fn build_import_label(name: &str, path: &Vec<SmolStr>) -> String { | |||
58 | buf | 58 | buf |
59 | } | 59 | } |
60 | 60 | ||
61 | fn fmt_import_path(path: &Vec<SmolStr>, buf: &mut String) { | 61 | fn fmt_import_path(path: &[SmolStr], buf: &mut String) { |
62 | let mut segments = path.iter(); | 62 | let mut segments = path.iter(); |
63 | if let Some(s) = segments.next() { | 63 | if let Some(s) = segments.next() { |
64 | buf.push_str(&s); | 64 | buf.push_str(&s); |
diff --git a/crates/ra_ide_api/src/diagnostics.rs b/crates/ra_ide_api/src/diagnostics.rs index a2a8c1e4f..35b3d77df 100644 --- a/crates/ra_ide_api/src/diagnostics.rs +++ b/crates/ra_ide_api/src/diagnostics.rs | |||
@@ -109,7 +109,7 @@ fn check_unnecessary_braces_in_use_statement( | |||
109 | 109 | ||
110 | acc.push(Diagnostic { | 110 | acc.push(Diagnostic { |
111 | range, | 111 | range, |
112 | message: format!("Unnecessary braces in use statement"), | 112 | message: "Unnecessary braces in use statement".to_string(), |
113 | severity: Severity::WeakWarning, | 113 | severity: Severity::WeakWarning, |
114 | fix: Some(SourceChange::source_file_edit( | 114 | fix: Some(SourceChange::source_file_edit( |
115 | "Remove unnecessary braces", | 115 | "Remove unnecessary braces", |
@@ -155,7 +155,7 @@ fn check_struct_shorthand_initialization( | |||
155 | 155 | ||
156 | acc.push(Diagnostic { | 156 | acc.push(Diagnostic { |
157 | range: named_field.syntax().range(), | 157 | range: named_field.syntax().range(), |
158 | message: format!("Shorthand struct initialization"), | 158 | message: "Shorthand struct initialization".to_string(), |
159 | severity: Severity::WeakWarning, | 159 | severity: Severity::WeakWarning, |
160 | fix: Some(SourceChange::source_file_edit( | 160 | fix: Some(SourceChange::source_file_edit( |
161 | "use struct shorthand initialization", | 161 | "use struct shorthand initialization", |
diff --git a/crates/ra_ide_api/src/extend_selection.rs b/crates/ra_ide_api/src/extend_selection.rs index 00c445310..a713b762c 100644 --- a/crates/ra_ide_api/src/extend_selection.rs +++ b/crates/ra_ide_api/src/extend_selection.rs | |||
@@ -95,7 +95,7 @@ fn extend_single_word_in_comment_or_string( | |||
95 | } | 95 | } |
96 | 96 | ||
97 | let start_idx = before.rfind(non_word_char)? as u32; | 97 | let start_idx = before.rfind(non_word_char)? as u32; |
98 | let end_idx = after.find(non_word_char).unwrap_or(after.len()) as u32; | 98 | let end_idx = after.find(non_word_char).unwrap_or_else(|| after.len()) as u32; |
99 | 99 | ||
100 | let from: TextUnit = (start_idx + 1).into(); | 100 | let from: TextUnit = (start_idx + 1).into(); |
101 | let to: TextUnit = (cursor_position + end_idx).into(); | 101 | let to: TextUnit = (cursor_position + end_idx).into(); |
diff --git a/crates/ra_ide_api/src/folding_ranges.rs b/crates/ra_ide_api/src/folding_ranges.rs index b50bbee38..4400ff232 100644 --- a/crates/ra_ide_api/src/folding_ranges.rs +++ b/crates/ra_ide_api/src/folding_ranges.rs | |||
@@ -205,7 +205,7 @@ mod tests { | |||
205 | "The amount of fold kinds is different than the expected amount" | 205 | "The amount of fold kinds is different than the expected amount" |
206 | ); | 206 | ); |
207 | for ((fold, range), fold_kind) in | 207 | for ((fold, range), fold_kind) in |
208 | folds.into_iter().zip(ranges.into_iter()).zip(fold_kinds.into_iter()) | 208 | folds.iter().zip(ranges.into_iter()).zip(fold_kinds.iter()) |
209 | { | 209 | { |
210 | assert_eq!(fold.range.start(), range.start()); | 210 | assert_eq!(fold.range.start(), range.start()); |
211 | assert_eq!(fold.range.end(), range.end()); | 211 | assert_eq!(fold.range.end(), range.end()); |
diff --git a/crates/ra_ide_api/src/hover.rs b/crates/ra_ide_api/src/hover.rs index 9c35db2a4..f56965ef5 100644 --- a/crates/ra_ide_api/src/hover.rs +++ b/crates/ra_ide_api/src/hover.rs | |||
@@ -18,6 +18,12 @@ pub struct HoverResult { | |||
18 | exact: bool, | 18 | exact: bool, |
19 | } | 19 | } |
20 | 20 | ||
21 | impl Default for HoverResult { | ||
22 | fn default() -> Self { | ||
23 | HoverResult::new() | ||
24 | } | ||
25 | } | ||
26 | |||
21 | impl HoverResult { | 27 | impl HoverResult { |
22 | pub fn new() -> HoverResult { | 28 | pub fn new() -> HoverResult { |
23 | HoverResult { | 29 | HoverResult { |
diff --git a/crates/ra_ide_api/src/line_index.rs b/crates/ra_ide_api/src/line_index.rs index fd33d6767..087dfafed 100644 --- a/crates/ra_ide_api/src/line_index.rs +++ b/crates/ra_ide_api/src/line_index.rs | |||
@@ -41,7 +41,7 @@ impl LineIndex { | |||
41 | newlines.push(curr_row); | 41 | newlines.push(curr_row); |
42 | 42 | ||
43 | // Save any utf-16 characters seen in the previous line | 43 | // Save any utf-16 characters seen in the previous line |
44 | if utf16_chars.len() > 0 { | 44 | if !utf16_chars.is_empty() { |
45 | utf16_lines.insert(line, utf16_chars); | 45 | utf16_lines.insert(line, utf16_chars); |
46 | utf16_chars = Vec::new(); | 46 | utf16_chars = Vec::new(); |
47 | } | 47 | } |
@@ -61,7 +61,7 @@ impl LineIndex { | |||
61 | } | 61 | } |
62 | 62 | ||
63 | // Save any utf-16 characters seen in the last line | 63 | // Save any utf-16 characters seen in the last line |
64 | if utf16_chars.len() > 0 { | 64 | if !utf16_chars.is_empty() { |
65 | utf16_lines.insert(line, utf16_chars); | 65 | utf16_lines.insert(line, utf16_chars); |
66 | } | 66 | } |
67 | 67 | ||
diff --git a/crates/ra_ide_api/src/line_index_utils.rs b/crates/ra_ide_api/src/line_index_utils.rs index 799a920ad..a03467011 100644 --- a/crates/ra_ide_api/src/line_index_utils.rs +++ b/crates/ra_ide_api/src/line_index_utils.rs | |||
@@ -133,9 +133,9 @@ impl<'a> Edits<'a> { | |||
133 | } | 133 | } |
134 | 134 | ||
135 | fn next_steps(&mut self, step: &Step) -> NextSteps { | 135 | fn next_steps(&mut self, step: &Step) -> NextSteps { |
136 | let step_pos = match step { | 136 | let step_pos = match *step { |
137 | &Step::Newline(n) => n, | 137 | Step::Newline(n) => n, |
138 | &Step::Utf16Char(r) => r.end(), | 138 | Step::Utf16Char(r) => r.end(), |
139 | }; | 139 | }; |
140 | let res = match &mut self.current { | 140 | let res = match &mut self.current { |
141 | Some(edit) => { | 141 | Some(edit) => { |
@@ -181,9 +181,9 @@ impl<'a> Edits<'a> { | |||
181 | if self.acc_diff == 0 { | 181 | if self.acc_diff == 0 { |
182 | x.clone() | 182 | x.clone() |
183 | } else { | 183 | } else { |
184 | match x { | 184 | match *x { |
185 | &Step::Newline(n) => Step::Newline(self.translate(n)), | 185 | Step::Newline(n) => Step::Newline(self.translate(n)), |
186 | &Step::Utf16Char(r) => Step::Utf16Char(self.translate_range(r)), | 186 | Step::Utf16Char(r) => Step::Utf16Char(self.translate_range(r)), |
187 | } | 187 | } |
188 | } | 188 | } |
189 | } | 189 | } |
diff --git a/crates/ra_ide_api/src/typing.rs b/crates/ra_ide_api/src/typing.rs index 63bc0cf88..3e35d8352 100644 --- a/crates/ra_ide_api/src/typing.rs +++ b/crates/ra_ide_api/src/typing.rs | |||
@@ -110,7 +110,7 @@ pub(crate) fn on_dot_typed(db: &RootDatabase, position: FilePosition) -> Option< | |||
110 | let mut edit = TextEditBuilder::default(); | 110 | let mut edit = TextEditBuilder::default(); |
111 | edit.replace( | 111 | edit.replace( |
112 | TextRange::from_to(position.offset - current_indent_len, position.offset), | 112 | TextRange::from_to(position.offset - current_indent_len, position.offset), |
113 | target_indent.into(), | 113 | target_indent, |
114 | ); | 114 | ); |
115 | 115 | ||
116 | let res = SourceChange::source_file_edit_from("reindent dot", position.file_id, edit.finish()) | 116 | let res = SourceChange::source_file_edit_from("reindent dot", position.file_id, edit.finish()) |
diff --git a/crates/ra_lsp_server/src/cargo_target_spec.rs b/crates/ra_lsp_server/src/cargo_target_spec.rs index 742361155..082ac8609 100644 --- a/crates/ra_lsp_server/src/cargo_target_spec.rs +++ b/crates/ra_lsp_server/src/cargo_target_spec.rs | |||
@@ -64,7 +64,7 @@ impl CargoTargetSpec { | |||
64 | None => return Ok(None), | 64 | None => return Ok(None), |
65 | }; | 65 | }; |
66 | let file_id = world.analysis().crate_root(crate_id)?; | 66 | let file_id = world.analysis().crate_root(crate_id)?; |
67 | let path = world.vfs.read().file2path(ra_vfs::VfsFile(file_id.0.into())); | 67 | let path = world.vfs.read().file2path(ra_vfs::VfsFile(file_id.0)); |
68 | let res = world.workspaces.iter().find_map(|ws| match ws { | 68 | let res = world.workspaces.iter().find_map(|ws| match ws { |
69 | project_model::ProjectWorkspace::Cargo { cargo, .. } => { | 69 | project_model::ProjectWorkspace::Cargo { cargo, .. } => { |
70 | let tgt = cargo.target_by_root(&path)?; | 70 | let tgt = cargo.target_by_root(&path)?; |
diff --git a/crates/ra_lsp_server/src/main.rs b/crates/ra_lsp_server/src/main.rs index b0b70df5c..a0df32dde 100644 --- a/crates/ra_lsp_server/src/main.rs +++ b/crates/ra_lsp_server/src/main.rs | |||
@@ -49,7 +49,7 @@ fn main_inner() -> Result<()> { | |||
49 | let opts = params | 49 | let opts = params |
50 | .initialization_options | 50 | .initialization_options |
51 | .and_then(|v| InitializationOptions::deserialize(v).ok()) | 51 | .and_then(|v| InitializationOptions::deserialize(v).ok()) |
52 | .unwrap_or(InitializationOptions::default()); | 52 | .unwrap_or_default(); |
53 | 53 | ||
54 | ra_lsp_server::main_loop(workspace_roots, opts, r, s) | 54 | ra_lsp_server::main_loop(workspace_roots, opts, r, s) |
55 | })?; | 55 | })?; |
diff --git a/crates/ra_lsp_server/src/main_loop.rs b/crates/ra_lsp_server/src/main_loop.rs index 6080a3a4e..090fb9b1b 100644 --- a/crates/ra_lsp_server/src/main_loop.rs +++ b/crates/ra_lsp_server/src/main_loop.rs | |||
@@ -384,7 +384,7 @@ fn on_notification( | |||
384 | if let Some(file_id) = | 384 | if let Some(file_id) = |
385 | state.vfs.write().add_file_overlay(&path, params.text_document.text) | 385 | state.vfs.write().add_file_overlay(&path, params.text_document.text) |
386 | { | 386 | { |
387 | subs.add_sub(FileId(file_id.0.into())); | 387 | subs.add_sub(FileId(file_id.0)); |
388 | } | 388 | } |
389 | return Ok(()); | 389 | return Ok(()); |
390 | } | 390 | } |
@@ -406,7 +406,7 @@ fn on_notification( | |||
406 | let uri = params.text_document.uri; | 406 | let uri = params.text_document.uri; |
407 | let path = uri.to_file_path().map_err(|()| format_err!("invalid uri: {}", uri))?; | 407 | let path = uri.to_file_path().map_err(|()| format_err!("invalid uri: {}", uri))?; |
408 | if let Some(file_id) = state.vfs.write().remove_file_overlay(path.as_path()) { | 408 | if let Some(file_id) = state.vfs.write().remove_file_overlay(path.as_path()) { |
409 | subs.remove_sub(FileId(file_id.0.into())); | 409 | subs.remove_sub(FileId(file_id.0)); |
410 | } | 410 | } |
411 | let params = req::PublishDiagnosticsParams { uri, diagnostics: Vec::new() }; | 411 | let params = req::PublishDiagnosticsParams { uri, diagnostics: Vec::new() }; |
412 | let not = RawNotification::new::<req::PublishDiagnostics>(¶ms); | 412 | let not = RawNotification::new::<req::PublishDiagnostics>(¶ms); |
diff --git a/crates/ra_lsp_server/src/world.rs b/crates/ra_lsp_server/src/world.rs index e0d2f6306..cd8df4fdb 100644 --- a/crates/ra_lsp_server/src/world.rs +++ b/crates/ra_lsp_server/src/world.rs | |||
@@ -60,14 +60,14 @@ impl WorldState { | |||
60 | for r in vfs_roots { | 60 | for r in vfs_roots { |
61 | let vfs_root_path = vfs.root2path(r); | 61 | let vfs_root_path = vfs.root2path(r); |
62 | let is_local = folder_roots.iter().any(|it| vfs_root_path.starts_with(it)); | 62 | let is_local = folder_roots.iter().any(|it| vfs_root_path.starts_with(it)); |
63 | change.add_root(SourceRootId(r.0.into()), is_local); | 63 | change.add_root(SourceRootId(r.0), is_local); |
64 | } | 64 | } |
65 | 65 | ||
66 | // Create crate graph from all the workspaces | 66 | // Create crate graph from all the workspaces |
67 | let mut crate_graph = CrateGraph::default(); | 67 | let mut crate_graph = CrateGraph::default(); |
68 | let mut load = |path: &std::path::Path| { | 68 | let mut load = |path: &std::path::Path| { |
69 | let vfs_file = vfs.load(path); | 69 | let vfs_file = vfs.load(path); |
70 | vfs_file.map(|f| FileId(f.0.into())) | 70 | vfs_file.map(|f| FileId(f.0)) |
71 | }; | 71 | }; |
72 | for ws in workspaces.iter() { | 72 | for ws in workspaces.iter() { |
73 | crate_graph.extend(ws.to_crate_graph(&mut load)); | 73 | crate_graph.extend(ws.to_crate_graph(&mut load)); |
@@ -105,29 +105,24 @@ impl WorldState { | |||
105 | if is_local { | 105 | if is_local { |
106 | self.roots_to_scan -= 1; | 106 | self.roots_to_scan -= 1; |
107 | for (file, path, text) in files { | 107 | for (file, path, text) in files { |
108 | change.add_file( | 108 | change.add_file(SourceRootId(root.0), FileId(file.0), path, text); |
109 | SourceRootId(root.0.into()), | ||
110 | FileId(file.0.into()), | ||
111 | path, | ||
112 | text, | ||
113 | ); | ||
114 | } | 109 | } |
115 | } else { | 110 | } else { |
116 | let files = files | 111 | let files = files |
117 | .into_iter() | 112 | .into_iter() |
118 | .map(|(vfsfile, path, text)| (FileId(vfsfile.0.into()), path, text)) | 113 | .map(|(vfsfile, path, text)| (FileId(vfsfile.0), path, text)) |
119 | .collect(); | 114 | .collect(); |
120 | libs.push((SourceRootId(root.0.into()), files)); | 115 | libs.push((SourceRootId(root.0), files)); |
121 | } | 116 | } |
122 | } | 117 | } |
123 | VfsChange::AddFile { root, file, path, text } => { | 118 | VfsChange::AddFile { root, file, path, text } => { |
124 | change.add_file(SourceRootId(root.0.into()), FileId(file.0.into()), path, text); | 119 | change.add_file(SourceRootId(root.0), FileId(file.0), path, text); |
125 | } | 120 | } |
126 | VfsChange::RemoveFile { root, file, path } => { | 121 | VfsChange::RemoveFile { root, file, path } => { |
127 | change.remove_file(SourceRootId(root.0.into()), FileId(file.0.into()), path) | 122 | change.remove_file(SourceRootId(root.0), FileId(file.0), path) |
128 | } | 123 | } |
129 | VfsChange::ChangeFile { file, text } => { | 124 | VfsChange::ChangeFile { file, text } => { |
130 | change.change_file(FileId(file.0.into()), text); | 125 | change.change_file(FileId(file.0), text); |
131 | } | 126 | } |
132 | } | 127 | } |
133 | } | 128 | } |
@@ -178,18 +173,18 @@ impl WorldSnapshot { | |||
178 | message: "Rust file outside current workspace is not supported yet.".to_string(), | 173 | message: "Rust file outside current workspace is not supported yet.".to_string(), |
179 | }) | 174 | }) |
180 | })?; | 175 | })?; |
181 | Ok(FileId(file.0.into())) | 176 | Ok(FileId(file.0)) |
182 | } | 177 | } |
183 | 178 | ||
184 | pub fn file_id_to_uri(&self, id: FileId) -> Result<Url> { | 179 | pub fn file_id_to_uri(&self, id: FileId) -> Result<Url> { |
185 | let path = self.vfs.read().file2path(VfsFile(id.0.into())); | 180 | let path = self.vfs.read().file2path(VfsFile(id.0)); |
186 | let url = Url::from_file_path(&path) | 181 | let url = Url::from_file_path(&path) |
187 | .map_err(|_| format_err!("can't convert path to url: {}", path.display()))?; | 182 | .map_err(|_| format_err!("can't convert path to url: {}", path.display()))?; |
188 | Ok(url) | 183 | Ok(url) |
189 | } | 184 | } |
190 | 185 | ||
191 | pub fn path_to_uri(&self, root: SourceRootId, path: &RelativePathBuf) -> Result<Url> { | 186 | pub fn path_to_uri(&self, root: SourceRootId, path: &RelativePathBuf) -> Result<Url> { |
192 | let base = self.vfs.read().root2path(VfsRoot(root.0.into())); | 187 | let base = self.vfs.read().root2path(VfsRoot(root.0)); |
193 | let path = path.to_path(base); | 188 | let path = path.to_path(base); |
194 | let url = Url::from_file_path(&path) | 189 | let url = Url::from_file_path(&path) |
195 | .map_err(|_| format_err!("can't convert path to url: {}", path.display()))?; | 190 | .map_err(|_| format_err!("can't convert path to url: {}", path.display()))?; |
@@ -212,7 +207,7 @@ impl WorldSnapshot { | |||
212 | } | 207 | } |
213 | 208 | ||
214 | pub fn workspace_root_for(&self, file_id: FileId) -> Option<&Path> { | 209 | pub fn workspace_root_for(&self, file_id: FileId) -> Option<&Path> { |
215 | let path = self.vfs.read().file2path(VfsFile(file_id.0.into())); | 210 | let path = self.vfs.read().file2path(VfsFile(file_id.0)); |
216 | self.workspaces.iter().find_map(|ws| ws.workspace_root_for(&path)) | 211 | self.workspaces.iter().find_map(|ws| ws.workspace_root_for(&path)) |
217 | } | 212 | } |
218 | } | 213 | } |
diff --git a/crates/ra_lsp_server/tests/heavy_tests/support.rs b/crates/ra_lsp_server/tests/heavy_tests/support.rs index f952a03a3..75912afdd 100644 --- a/crates/ra_lsp_server/tests/heavy_tests/support.rs +++ b/crates/ra_lsp_server/tests/heavy_tests/support.rs | |||
@@ -94,14 +94,9 @@ impl Server { | |||
94 | let worker = Worker::<RawMessage, RawMessage>::spawn( | 94 | let worker = Worker::<RawMessage, RawMessage>::spawn( |
95 | "test server", | 95 | "test server", |
96 | 128, | 96 | 128, |
97 | move |mut msg_receiver, mut msg_sender| { | 97 | move |msg_receiver, msg_sender| { |
98 | main_loop( | 98 | main_loop(roots, InitializationOptions::default(), &msg_receiver, &msg_sender) |
99 | roots, | 99 | .unwrap() |
100 | InitializationOptions::default(), | ||
101 | &mut msg_receiver, | ||
102 | &mut msg_sender, | ||
103 | ) | ||
104 | .unwrap() | ||
105 | }, | 100 | }, |
106 | ); | 101 | ); |
107 | let res = Server { req_id: Cell::new(1), dir, messages: Default::default(), worker }; | 102 | let res = Server { req_id: Cell::new(1), dir, messages: Default::default(), worker }; |
@@ -141,15 +136,14 @@ impl Server { | |||
141 | R::Params: Serialize, | 136 | R::Params: Serialize, |
142 | { | 137 | { |
143 | let actual = self.send_request::<R>(params); | 138 | let actual = self.send_request::<R>(params); |
144 | match find_mismatch(&expected_resp, &actual) { | 139 | if let Some((expected_part, actual_part)) = find_mismatch(&expected_resp, &actual) { |
145 | Some((expected_part, actual_part)) => panic!( | 140 | panic!( |
146 | "JSON mismatch\nExpected:\n{}\nWas:\n{}\nExpected part:\n{}\nActual part:\n{}\n", | 141 | "JSON mismatch\nExpected:\n{}\nWas:\n{}\nExpected part:\n{}\nActual part:\n{}\n", |
147 | to_string_pretty(&expected_resp).unwrap(), | 142 | to_string_pretty(&expected_resp).unwrap(), |
148 | to_string_pretty(&actual).unwrap(), | 143 | to_string_pretty(&actual).unwrap(), |
149 | to_string_pretty(expected_part).unwrap(), | 144 | to_string_pretty(expected_part).unwrap(), |
150 | to_string_pretty(actual_part).unwrap(), | 145 | to_string_pretty(actual_part).unwrap(), |
151 | ), | 146 | ); |
152 | None => {} | ||
153 | } | 147 | } |
154 | } | 148 | } |
155 | 149 | ||
diff --git a/crates/ra_mbe/src/mbe_expander.rs b/crates/ra_mbe/src/mbe_expander.rs index a0bd0c5f8..55a6ecf58 100644 --- a/crates/ra_mbe/src/mbe_expander.rs +++ b/crates/ra_mbe/src/mbe_expander.rs | |||
@@ -105,17 +105,15 @@ impl Bindings { | |||
105 | } | 105 | } |
106 | 106 | ||
107 | fn get(&self, name: &SmolStr, nesting: &[usize]) -> Result<&tt::TokenTree, ExpandError> { | 107 | fn get(&self, name: &SmolStr, nesting: &[usize]) -> Result<&tt::TokenTree, ExpandError> { |
108 | let mut b = self | 108 | let mut b = self.inner.get(name).ok_or_else(|| { |
109 | .inner | 109 | ExpandError::BindingError(format!("could not find binding `{}`", name)) |
110 | .get(name) | 110 | })?; |
111 | .ok_or(ExpandError::BindingError(format!("could not find binding `{}`", name)))?; | ||
112 | for &idx in nesting.iter() { | 111 | for &idx in nesting.iter() { |
113 | b = match b { | 112 | b = match b { |
114 | Binding::Simple(_) => break, | 113 | Binding::Simple(_) => break, |
115 | Binding::Nested(bs) => bs.get(idx).ok_or(ExpandError::BindingError(format!( | 114 | Binding::Nested(bs) => bs.get(idx).ok_or_else(|| { |
116 | "could not find nested binding `{}`", | 115 | ExpandError::BindingError(format!("could not find nested binding `{}`", name)) |
117 | name | 116 | })?, |
118 | )))?, | ||
119 | Binding::Empty => { | 117 | Binding::Empty => { |
120 | return Err(ExpandError::BindingError(format!( | 118 | return Err(ExpandError::BindingError(format!( |
121 | "could not find empty binding `{}`", | 119 | "could not find empty binding `{}`", |
@@ -206,48 +204,48 @@ fn match_lhs(pattern: &crate::Subtree, input: &mut TtCursor) -> Result<Bindings, | |||
206 | "path" => { | 204 | "path" => { |
207 | let path = | 205 | let path = |
208 | input.eat_path().ok_or(ExpandError::UnexpectedToken)?.clone(); | 206 | input.eat_path().ok_or(ExpandError::UnexpectedToken)?.clone(); |
209 | res.inner.insert(text.clone(), Binding::Simple(path.into())); | 207 | res.inner.insert(text.clone(), Binding::Simple(path)); |
210 | } | 208 | } |
211 | "expr" => { | 209 | "expr" => { |
212 | let expr = | 210 | let expr = |
213 | input.eat_expr().ok_or(ExpandError::UnexpectedToken)?.clone(); | 211 | input.eat_expr().ok_or(ExpandError::UnexpectedToken)?.clone(); |
214 | res.inner.insert(text.clone(), Binding::Simple(expr.into())); | 212 | res.inner.insert(text.clone(), Binding::Simple(expr)); |
215 | } | 213 | } |
216 | "ty" => { | 214 | "ty" => { |
217 | let ty = input.eat_ty().ok_or(ExpandError::UnexpectedToken)?.clone(); | 215 | let ty = input.eat_ty().ok_or(ExpandError::UnexpectedToken)?.clone(); |
218 | res.inner.insert(text.clone(), Binding::Simple(ty.into())); | 216 | res.inner.insert(text.clone(), Binding::Simple(ty)); |
219 | } | 217 | } |
220 | "pat" => { | 218 | "pat" => { |
221 | let pat = input.eat_pat().ok_or(ExpandError::UnexpectedToken)?.clone(); | 219 | let pat = input.eat_pat().ok_or(ExpandError::UnexpectedToken)?.clone(); |
222 | res.inner.insert(text.clone(), Binding::Simple(pat.into())); | 220 | res.inner.insert(text.clone(), Binding::Simple(pat)); |
223 | } | 221 | } |
224 | "stmt" => { | 222 | "stmt" => { |
225 | let pat = input.eat_stmt().ok_or(ExpandError::UnexpectedToken)?.clone(); | 223 | let pat = input.eat_stmt().ok_or(ExpandError::UnexpectedToken)?.clone(); |
226 | res.inner.insert(text.clone(), Binding::Simple(pat.into())); | 224 | res.inner.insert(text.clone(), Binding::Simple(pat)); |
227 | } | 225 | } |
228 | "block" => { | 226 | "block" => { |
229 | let block = | 227 | let block = |
230 | input.eat_block().ok_or(ExpandError::UnexpectedToken)?.clone(); | 228 | input.eat_block().ok_or(ExpandError::UnexpectedToken)?.clone(); |
231 | res.inner.insert(text.clone(), Binding::Simple(block.into())); | 229 | res.inner.insert(text.clone(), Binding::Simple(block)); |
232 | } | 230 | } |
233 | "meta" => { | 231 | "meta" => { |
234 | let meta = | 232 | let meta = |
235 | input.eat_meta().ok_or(ExpandError::UnexpectedToken)?.clone(); | 233 | input.eat_meta().ok_or(ExpandError::UnexpectedToken)?.clone(); |
236 | res.inner.insert(text.clone(), Binding::Simple(meta.into())); | 234 | res.inner.insert(text.clone(), Binding::Simple(meta)); |
237 | } | 235 | } |
238 | "tt" => { | 236 | "tt" => { |
239 | let token = input.eat().ok_or(ExpandError::UnexpectedToken)?.clone(); | 237 | let token = input.eat().ok_or(ExpandError::UnexpectedToken)?.clone(); |
240 | res.inner.insert(text.clone(), Binding::Simple(token.into())); | 238 | res.inner.insert(text.clone(), Binding::Simple(token)); |
241 | } | 239 | } |
242 | "item" => { | 240 | "item" => { |
243 | let item = | 241 | let item = |
244 | input.eat_item().ok_or(ExpandError::UnexpectedToken)?.clone(); | 242 | input.eat_item().ok_or(ExpandError::UnexpectedToken)?.clone(); |
245 | res.inner.insert(text.clone(), Binding::Simple(item.into())); | 243 | res.inner.insert(text.clone(), Binding::Simple(item)); |
246 | } | 244 | } |
247 | "lifetime" => { | 245 | "lifetime" => { |
248 | let lifetime = | 246 | let lifetime = |
249 | input.eat_lifetime().ok_or(ExpandError::UnexpectedToken)?.clone(); | 247 | input.eat_lifetime().ok_or(ExpandError::UnexpectedToken)?.clone(); |
250 | res.inner.insert(text.clone(), Binding::Simple(lifetime.into())); | 248 | res.inner.insert(text.clone(), Binding::Simple(lifetime)); |
251 | } | 249 | } |
252 | "literal" => { | 250 | "literal" => { |
253 | let literal = | 251 | let literal = |
@@ -262,7 +260,7 @@ fn match_lhs(pattern: &crate::Subtree, input: &mut TtCursor) -> Result<Bindings, | |||
262 | // `vis` is optional | 260 | // `vis` is optional |
263 | if let Some(vis) = input.try_eat_vis() { | 261 | if let Some(vis) = input.try_eat_vis() { |
264 | let vis = vis.clone(); | 262 | let vis = vis.clone(); |
265 | res.inner.insert(text.clone(), Binding::Simple(vis.into())); | 263 | res.inner.insert(text.clone(), Binding::Simple(vis)); |
266 | } else { | 264 | } else { |
267 | res.push_optional(&text); | 265 | res.push_optional(&text); |
268 | } | 266 | } |
@@ -452,7 +450,7 @@ fn expand_tt( | |||
452 | 450 | ||
453 | let idx = ctx.nesting.pop().unwrap(); | 451 | let idx = ctx.nesting.pop().unwrap(); |
454 | ctx.nesting.push(idx + 1); | 452 | ctx.nesting.push(idx + 1); |
455 | token_trees.push(reduce_single_token(t).into()); | 453 | token_trees.push(reduce_single_token(t)); |
456 | 454 | ||
457 | if let Some(ref sep) = repeat.separator { | 455 | if let Some(ref sep) = repeat.separator { |
458 | match sep { | 456 | match sep { |
diff --git a/crates/ra_mbe/src/mbe_parser.rs b/crates/ra_mbe/src/mbe_parser.rs index d8fe293c7..dca16b537 100644 --- a/crates/ra_mbe/src/mbe_parser.rs +++ b/crates/ra_mbe/src/mbe_parser.rs | |||
@@ -125,8 +125,8 @@ fn parse_repeat(p: &mut TtCursor, transcriber: bool) -> Result<crate::Repeat, Pa | |||
125 | } | 125 | } |
126 | } | 126 | } |
127 | 127 | ||
128 | let sep = p.eat_seperator().ok_or(ParseError::Expected(String::from("separator")))?; | 128 | let sep = p.eat_seperator().ok_or_else(|| ParseError::Expected(String::from("separator")))?; |
129 | let rep = p.eat_punct().ok_or(ParseError::Expected(String::from("repeat")))?; | 129 | let rep = p.eat_punct().ok_or_else(|| ParseError::Expected(String::from("repeat")))?; |
130 | 130 | ||
131 | mk_repeat(rep.char, subtree, Some(sep)) | 131 | mk_repeat(rep.char, subtree, Some(sep)) |
132 | } | 132 | } |
diff --git a/crates/ra_mbe/src/syntax_bridge.rs b/crates/ra_mbe/src/syntax_bridge.rs index 0edb6f9a2..cb039ca37 100644 --- a/crates/ra_mbe/src/syntax_bridge.rs +++ b/crates/ra_mbe/src/syntax_bridge.rs | |||
@@ -47,7 +47,7 @@ pub fn syntax_node_to_token_tree(node: &SyntaxNode) -> Option<(tt::Subtree, Toke | |||
47 | 47 | ||
48 | fn token_tree_to_syntax_node<F>(tt: &tt::Subtree, f: F) -> Result<TreeArc<SyntaxNode>, ExpandError> | 48 | fn token_tree_to_syntax_node<F>(tt: &tt::Subtree, f: F) -> Result<TreeArc<SyntaxNode>, ExpandError> |
49 | where | 49 | where |
50 | F: Fn(&mut ra_parser::TokenSource, &mut ra_parser::TreeSink), | 50 | F: Fn(&mut dyn ra_parser::TokenSource, &mut dyn ra_parser::TreeSink), |
51 | { | 51 | { |
52 | let tokens = [tt.clone().into()]; | 52 | let tokens = [tt.clone().into()]; |
53 | let buffer = TokenBuffer::new(&tokens); | 53 | let buffer = TokenBuffer::new(&tokens); |
@@ -155,9 +155,10 @@ fn convert_doc_comment<'a>(token: &ra_syntax::SyntaxToken<'a>) -> Option<Vec<tt: | |||
155 | if let ast::CommentPlacement::Inner = doc { | 155 | if let ast::CommentPlacement::Inner = doc { |
156 | token_trees.push(mk_punct('!')); | 156 | token_trees.push(mk_punct('!')); |
157 | } | 157 | } |
158 | token_trees.push(tt::TokenTree::from(tt::Subtree::from( | 158 | token_trees.push(tt::TokenTree::from(tt::Subtree { |
159 | tt::Subtree { delimiter: tt::Delimiter::Bracket, token_trees: meta_tkns }.into(), | 159 | delimiter: tt::Delimiter::Bracket, |
160 | ))); | 160 | token_trees: meta_tkns, |
161 | })); | ||
161 | 162 | ||
162 | return Some(token_trees); | 163 | return Some(token_trees); |
163 | 164 | ||
@@ -292,7 +293,7 @@ fn delim_to_str(d: tt::Delimiter, closing: bool) -> SmolStr { | |||
292 | }; | 293 | }; |
293 | 294 | ||
294 | let idx = closing as usize; | 295 | let idx = closing as usize; |
295 | let text = if texts.len() > 0 { &texts[idx..texts.len() - (1 - idx)] } else { "" }; | 296 | let text = if !texts.is_empty() { &texts[idx..texts.len() - (1 - idx)] } else { "" }; |
296 | text.into() | 297 | text.into() |
297 | } | 298 | } |
298 | 299 | ||
diff --git a/crates/ra_parser/src/grammar.rs b/crates/ra_parser/src/grammar.rs index cf603eba1..5997636d6 100644 --- a/crates/ra_parser/src/grammar.rs +++ b/crates/ra_parser/src/grammar.rs | |||
@@ -87,10 +87,8 @@ pub(crate) fn pattern(p: &mut Parser) { | |||
87 | } | 87 | } |
88 | 88 | ||
89 | pub(crate) fn stmt(p: &mut Parser, with_semi: bool) { | 89 | pub(crate) fn stmt(p: &mut Parser, with_semi: bool) { |
90 | let with_semi = match with_semi { | 90 | let with_semi = |
91 | true => expressions::StmtWithSemi::Yes, | 91 | if with_semi { expressions::StmtWithSemi::Yes } else { expressions::StmtWithSemi::No }; |
92 | false => expressions::StmtWithSemi::No, | ||
93 | }; | ||
94 | 92 | ||
95 | expressions::stmt(p, with_semi) | 93 | expressions::stmt(p, with_semi) |
96 | } | 94 | } |
diff --git a/crates/ra_parser/src/grammar/expressions.rs b/crates/ra_parser/src/grammar/expressions.rs index bb6c78b5f..99e32c4e8 100644 --- a/crates/ra_parser/src/grammar/expressions.rs +++ b/crates/ra_parser/src/grammar/expressions.rs | |||
@@ -454,6 +454,7 @@ fn method_call_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker { | |||
454 | // x.1i32; | 454 | // x.1i32; |
455 | // x.0x01; | 455 | // x.0x01; |
456 | // } | 456 | // } |
457 | #[allow(clippy::if_same_then_else)] | ||
457 | fn field_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker { | 458 | fn field_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker { |
458 | assert!(p.at(T![.])); | 459 | assert!(p.at(T![.])); |
459 | let m = lhs.precede(p); | 460 | let m = lhs.precede(p); |
diff --git a/crates/ra_parser/src/grammar/expressions/atom.rs b/crates/ra_parser/src/grammar/expressions/atom.rs index 8b1a1de49..725fb99f6 100644 --- a/crates/ra_parser/src/grammar/expressions/atom.rs +++ b/crates/ra_parser/src/grammar/expressions/atom.rs | |||
@@ -52,6 +52,7 @@ pub(super) const ATOM_EXPR_FIRST: TokenSet = | |||
52 | CONTINUE_KW, | 52 | CONTINUE_KW, |
53 | LIFETIME, | 53 | LIFETIME, |
54 | ASYNC_KW, | 54 | ASYNC_KW, |
55 | TRY_KW, | ||
55 | ]); | 56 | ]); |
56 | 57 | ||
57 | const EXPR_RECOVERY_SET: TokenSet = token_set![LET_KW]; | 58 | const EXPR_RECOVERY_SET: TokenSet = token_set![LET_KW]; |
@@ -75,6 +76,7 @@ pub(super) fn atom_expr(p: &mut Parser, r: Restrictions) -> Option<(CompletedMar | |||
75 | T![loop] => loop_expr(p, None), | 76 | T![loop] => loop_expr(p, None), |
76 | T![for] => for_expr(p, None), | 77 | T![for] => for_expr(p, None), |
77 | T![while] => while_expr(p, None), | 78 | T![while] => while_expr(p, None), |
79 | T![try] => try_block_expr(p, None), | ||
78 | LIFETIME if la == T![:] => { | 80 | LIFETIME if la == T![:] => { |
79 | let m = p.start(); | 81 | let m = p.start(); |
80 | label(p); | 82 | label(p); |
@@ -116,7 +118,9 @@ pub(super) fn atom_expr(p: &mut Parser, r: Restrictions) -> Option<(CompletedMar | |||
116 | } | 118 | } |
117 | }; | 119 | }; |
118 | let blocklike = match done.kind() { | 120 | let blocklike = match done.kind() { |
119 | IF_EXPR | WHILE_EXPR | FOR_EXPR | LOOP_EXPR | MATCH_EXPR | BLOCK_EXPR => BlockLike::Block, | 121 | IF_EXPR | WHILE_EXPR | FOR_EXPR | LOOP_EXPR | MATCH_EXPR | BLOCK_EXPR | TRY_BLOCK_EXPR => { |
122 | BlockLike::Block | ||
123 | } | ||
120 | _ => BlockLike::NotBlock, | 124 | _ => BlockLike::NotBlock, |
121 | }; | 125 | }; |
122 | Some((done, blocklike)) | 126 | Some((done, blocklike)) |
@@ -491,3 +495,15 @@ fn break_expr(p: &mut Parser, r: Restrictions) -> CompletedMarker { | |||
491 | } | 495 | } |
492 | m.complete(p, BREAK_EXPR) | 496 | m.complete(p, BREAK_EXPR) |
493 | } | 497 | } |
498 | |||
499 | // test try_block_expr | ||
500 | // fn foo() { | ||
501 | // let _ = try {}; | ||
502 | // } | ||
503 | fn try_block_expr(p: &mut Parser, m: Option<Marker>) -> CompletedMarker { | ||
504 | assert!(p.at(T![try])); | ||
505 | let m = m.unwrap_or_else(|| p.start()); | ||
506 | p.bump(); | ||
507 | block(p); | ||
508 | m.complete(p, TRY_EXPR) | ||
509 | } | ||
diff --git a/crates/ra_parser/src/syntax_kind/generated.rs b/crates/ra_parser/src/syntax_kind/generated.rs index d7926bd91..2c021f3e9 100644 --- a/crates/ra_parser/src/syntax_kind/generated.rs +++ b/crates/ra_parser/src/syntax_kind/generated.rs | |||
@@ -103,6 +103,7 @@ pub enum SyntaxKind { | |||
103 | LET_KW, | 103 | LET_KW, |
104 | MOVE_KW, | 104 | MOVE_KW, |
105 | RETURN_KW, | 105 | RETURN_KW, |
106 | TRY_KW, | ||
106 | AUTO_KW, | 107 | AUTO_KW, |
107 | DEFAULT_KW, | 108 | DEFAULT_KW, |
108 | UNION_KW, | 109 | UNION_KW, |
@@ -184,6 +185,7 @@ pub enum SyntaxKind { | |||
184 | STRUCT_LIT, | 185 | STRUCT_LIT, |
185 | NAMED_FIELD_LIST, | 186 | NAMED_FIELD_LIST, |
186 | NAMED_FIELD, | 187 | NAMED_FIELD, |
188 | TRY_BLOCK_EXPR, | ||
187 | CALL_EXPR, | 189 | CALL_EXPR, |
188 | INDEX_EXPR, | 190 | INDEX_EXPR, |
189 | METHOD_CALL_EXPR, | 191 | METHOD_CALL_EXPR, |
@@ -331,6 +333,7 @@ macro_rules! T { | |||
331 | (let) => { $crate::SyntaxKind::LET_KW }; | 333 | (let) => { $crate::SyntaxKind::LET_KW }; |
332 | (move) => { $crate::SyntaxKind::MOVE_KW }; | 334 | (move) => { $crate::SyntaxKind::MOVE_KW }; |
333 | (return) => { $crate::SyntaxKind::RETURN_KW }; | 335 | (return) => { $crate::SyntaxKind::RETURN_KW }; |
336 | (try) => { $crate::SyntaxKind::TRY_KW }; | ||
334 | (auto) => { $crate::SyntaxKind::AUTO_KW }; | 337 | (auto) => { $crate::SyntaxKind::AUTO_KW }; |
335 | (default) => { $crate::SyntaxKind::DEFAULT_KW }; | 338 | (default) => { $crate::SyntaxKind::DEFAULT_KW }; |
336 | (union) => { $crate::SyntaxKind::UNION_KW }; | 339 | (union) => { $crate::SyntaxKind::UNION_KW }; |
@@ -388,6 +391,7 @@ impl SyntaxKind { | |||
388 | | LET_KW | 391 | | LET_KW |
389 | | MOVE_KW | 392 | | MOVE_KW |
390 | | RETURN_KW | 393 | | RETURN_KW |
394 | | TRY_KW | ||
391 | | AUTO_KW | 395 | | AUTO_KW |
392 | | DEFAULT_KW | 396 | | DEFAULT_KW |
393 | | UNION_KW | 397 | | UNION_KW |
@@ -559,6 +563,7 @@ impl SyntaxKind { | |||
559 | LET_KW => &SyntaxInfo { name: "LET_KW" }, | 563 | LET_KW => &SyntaxInfo { name: "LET_KW" }, |
560 | MOVE_KW => &SyntaxInfo { name: "MOVE_KW" }, | 564 | MOVE_KW => &SyntaxInfo { name: "MOVE_KW" }, |
561 | RETURN_KW => &SyntaxInfo { name: "RETURN_KW" }, | 565 | RETURN_KW => &SyntaxInfo { name: "RETURN_KW" }, |
566 | TRY_KW => &SyntaxInfo { name: "TRY_KW" }, | ||
562 | AUTO_KW => &SyntaxInfo { name: "AUTO_KW" }, | 567 | AUTO_KW => &SyntaxInfo { name: "AUTO_KW" }, |
563 | DEFAULT_KW => &SyntaxInfo { name: "DEFAULT_KW" }, | 568 | DEFAULT_KW => &SyntaxInfo { name: "DEFAULT_KW" }, |
564 | UNION_KW => &SyntaxInfo { name: "UNION_KW" }, | 569 | UNION_KW => &SyntaxInfo { name: "UNION_KW" }, |
@@ -640,6 +645,7 @@ impl SyntaxKind { | |||
640 | STRUCT_LIT => &SyntaxInfo { name: "STRUCT_LIT" }, | 645 | STRUCT_LIT => &SyntaxInfo { name: "STRUCT_LIT" }, |
641 | NAMED_FIELD_LIST => &SyntaxInfo { name: "NAMED_FIELD_LIST" }, | 646 | NAMED_FIELD_LIST => &SyntaxInfo { name: "NAMED_FIELD_LIST" }, |
642 | NAMED_FIELD => &SyntaxInfo { name: "NAMED_FIELD" }, | 647 | NAMED_FIELD => &SyntaxInfo { name: "NAMED_FIELD" }, |
648 | TRY_BLOCK_EXPR => &SyntaxInfo { name: "TRY_BLOCK_EXPR" }, | ||
643 | CALL_EXPR => &SyntaxInfo { name: "CALL_EXPR" }, | 649 | CALL_EXPR => &SyntaxInfo { name: "CALL_EXPR" }, |
644 | INDEX_EXPR => &SyntaxInfo { name: "INDEX_EXPR" }, | 650 | INDEX_EXPR => &SyntaxInfo { name: "INDEX_EXPR" }, |
645 | METHOD_CALL_EXPR => &SyntaxInfo { name: "METHOD_CALL_EXPR" }, | 651 | METHOD_CALL_EXPR => &SyntaxInfo { name: "METHOD_CALL_EXPR" }, |
@@ -734,6 +740,7 @@ impl SyntaxKind { | |||
734 | "let" => LET_KW, | 740 | "let" => LET_KW, |
735 | "move" => MOVE_KW, | 741 | "move" => MOVE_KW, |
736 | "return" => RETURN_KW, | 742 | "return" => RETURN_KW, |
743 | "try" => TRY_KW, | ||
737 | _ => return None, | 744 | _ => return None, |
738 | }; | 745 | }; |
739 | Some(kw) | 746 | Some(kw) |
diff --git a/crates/ra_prof/Cargo.toml b/crates/ra_prof/Cargo.toml index efcce3d65..d55af18f5 100644 --- a/crates/ra_prof/Cargo.toml +++ b/crates/ra_prof/Cargo.toml | |||
@@ -8,3 +8,4 @@ publish = false | |||
8 | [dependencies] | 8 | [dependencies] |
9 | once_cell = "0.2.0" | 9 | once_cell = "0.2.0" |
10 | itertools = "0.8.0" | 10 | itertools = "0.8.0" |
11 | backtrace = "0.3.28" | ||
diff --git a/crates/ra_prof/src/lib.rs b/crates/ra_prof/src/lib.rs index e681b8e0b..de67b4031 100644 --- a/crates/ra_prof/src/lib.rs +++ b/crates/ra_prof/src/lib.rs | |||
@@ -225,6 +225,36 @@ fn print(lvl: usize, msgs: &[Message], out: &mut impl Write, longer_than: Durati | |||
225 | } | 225 | } |
226 | } | 226 | } |
227 | 227 | ||
228 | /// Prints backtrace to stderr, useful for debugging. | ||
229 | pub fn print_backtrace() { | ||
230 | let bt = backtrace::Backtrace::new(); | ||
231 | eprintln!("{:?}", bt); | ||
232 | } | ||
233 | |||
234 | thread_local!(static IN_SCOPE: RefCell<bool> = RefCell::new(false)); | ||
235 | |||
236 | /// Allows to check if the current code is withing some dynamic scope, can be | ||
237 | /// useful during debugging to figure out why a function is called. | ||
238 | pub struct Scope { | ||
239 | prev: bool, | ||
240 | } | ||
241 | |||
242 | impl Scope { | ||
243 | pub fn enter() -> Scope { | ||
244 | let prev = IN_SCOPE.with(|slot| std::mem::replace(&mut *slot.borrow_mut(), true)); | ||
245 | Scope { prev } | ||
246 | } | ||
247 | pub fn is_active() -> bool { | ||
248 | IN_SCOPE.with(|slot| *slot.borrow()) | ||
249 | } | ||
250 | } | ||
251 | |||
252 | impl Drop for Scope { | ||
253 | fn drop(&mut self) { | ||
254 | IN_SCOPE.with(|slot| *slot.borrow_mut() = self.prev); | ||
255 | } | ||
256 | } | ||
257 | |||
228 | #[cfg(test)] | 258 | #[cfg(test)] |
229 | mod tests { | 259 | mod tests { |
230 | use super::*; | 260 | use super::*; |
diff --git a/crates/ra_project_model/src/cargo_workspace.rs b/crates/ra_project_model/src/cargo_workspace.rs index 71976071f..5a1657788 100644 --- a/crates/ra_project_model/src/cargo_workspace.rs +++ b/crates/ra_project_model/src/cargo_workspace.rs | |||
@@ -137,7 +137,7 @@ impl CargoWorkspace { | |||
137 | for meta_pkg in meta.packages { | 137 | for meta_pkg in meta.packages { |
138 | let is_member = ws_members.contains(&meta_pkg.id); | 138 | let is_member = ws_members.contains(&meta_pkg.id); |
139 | let pkg = packages.alloc(PackageData { | 139 | let pkg = packages.alloc(PackageData { |
140 | name: meta_pkg.name.into(), | 140 | name: meta_pkg.name, |
141 | manifest: meta_pkg.manifest_path.clone(), | 141 | manifest: meta_pkg.manifest_path.clone(), |
142 | targets: Vec::new(), | 142 | targets: Vec::new(), |
143 | is_member, | 143 | is_member, |
@@ -149,7 +149,7 @@ impl CargoWorkspace { | |||
149 | for meta_tgt in meta_pkg.targets { | 149 | for meta_tgt in meta_pkg.targets { |
150 | let tgt = targets.alloc(TargetData { | 150 | let tgt = targets.alloc(TargetData { |
151 | pkg, | 151 | pkg, |
152 | name: meta_tgt.name.into(), | 152 | name: meta_tgt.name, |
153 | root: meta_tgt.src_path.clone(), | 153 | root: meta_tgt.src_path.clone(), |
154 | kind: TargetKind::new(meta_tgt.kind.as_slice()), | 154 | kind: TargetKind::new(meta_tgt.kind.as_slice()), |
155 | }); | 155 | }); |
@@ -160,8 +160,7 @@ impl CargoWorkspace { | |||
160 | for node in resolve.nodes { | 160 | for node in resolve.nodes { |
161 | let source = pkg_by_id[&node.id]; | 161 | let source = pkg_by_id[&node.id]; |
162 | for dep_node in node.deps { | 162 | for dep_node in node.deps { |
163 | let dep = | 163 | let dep = PackageDependency { name: dep_node.name, pkg: pkg_by_id[&dep_node.pkg] }; |
164 | PackageDependency { name: dep_node.name.into(), pkg: pkg_by_id[&dep_node.pkg] }; | ||
165 | packages[source].dependencies.push(dep); | 164 | packages[source].dependencies.push(dep); |
166 | } | 165 | } |
167 | } | 166 | } |
diff --git a/crates/ra_project_model/src/lib.rs b/crates/ra_project_model/src/lib.rs index 63eb7041e..4ae7f685c 100644 --- a/crates/ra_project_model/src/lib.rs +++ b/crates/ra_project_model/src/lib.rs | |||
@@ -70,7 +70,7 @@ impl ProjectRoot { | |||
70 | }) | 70 | }) |
71 | }; | 71 | }; |
72 | 72 | ||
73 | let hidden = dir_path.components().any(|c| c.as_str().starts_with(".")); | 73 | let hidden = dir_path.components().any(|c| c.as_str().starts_with('.')); |
74 | 74 | ||
75 | !is_ignored && !hidden | 75 | !is_ignored && !hidden |
76 | } | 76 | } |
diff --git a/crates/ra_syntax/src/ast/extensions.rs b/crates/ra_syntax/src/ast/extensions.rs index e4c99784c..930b2d9fa 100644 --- a/crates/ra_syntax/src/ast/extensions.rs +++ b/crates/ra_syntax/src/ast/extensions.rs | |||
@@ -78,7 +78,7 @@ impl ast::Attr { | |||
78 | if attr.kind() == IDENT { | 78 | if attr.kind() == IDENT { |
79 | let key = attr.as_token()?.text().clone(); | 79 | let key = attr.as_token()?.text().clone(); |
80 | let val_node = tt_node.children_with_tokens().find(|t| t.kind() == STRING)?; | 80 | let val_node = tt_node.children_with_tokens().find(|t| t.kind() == STRING)?; |
81 | let val = val_node.as_token()?.text().trim_start_matches("\"").trim_end_matches("\""); | 81 | let val = val_node.as_token()?.text().trim_start_matches('"').trim_end_matches('"'); |
82 | Some((key, SmolStr::new(val))) | 82 | Some((key, SmolStr::new(val))) |
83 | } else { | 83 | } else { |
84 | None | 84 | None |
diff --git a/crates/ra_syntax/src/ast/generated.rs b/crates/ra_syntax/src/ast/generated.rs index e73fe22e9..1d888e709 100644 --- a/crates/ra_syntax/src/ast/generated.rs +++ b/crates/ra_syntax/src/ast/generated.rs | |||
@@ -713,6 +713,7 @@ pub enum ExprKind<'a> { | |||
713 | MethodCallExpr(&'a MethodCallExpr), | 713 | MethodCallExpr(&'a MethodCallExpr), |
714 | FieldExpr(&'a FieldExpr), | 714 | FieldExpr(&'a FieldExpr), |
715 | TryExpr(&'a TryExpr), | 715 | TryExpr(&'a TryExpr), |
716 | TryBlockExpr(&'a TryBlockExpr), | ||
716 | CastExpr(&'a CastExpr), | 717 | CastExpr(&'a CastExpr), |
717 | RefExpr(&'a RefExpr), | 718 | RefExpr(&'a RefExpr), |
718 | PrefixExpr(&'a PrefixExpr), | 719 | PrefixExpr(&'a PrefixExpr), |
@@ -826,6 +827,11 @@ impl<'a> From<&'a TryExpr> for &'a Expr { | |||
826 | Expr::cast(&n.syntax).unwrap() | 827 | Expr::cast(&n.syntax).unwrap() |
827 | } | 828 | } |
828 | } | 829 | } |
830 | impl<'a> From<&'a TryBlockExpr> for &'a Expr { | ||
831 | fn from(n: &'a TryBlockExpr) -> &'a Expr { | ||
832 | Expr::cast(&n.syntax).unwrap() | ||
833 | } | ||
834 | } | ||
829 | impl<'a> From<&'a CastExpr> for &'a Expr { | 835 | impl<'a> From<&'a CastExpr> for &'a Expr { |
830 | fn from(n: &'a CastExpr) -> &'a Expr { | 836 | fn from(n: &'a CastExpr) -> &'a Expr { |
831 | Expr::cast(&n.syntax).unwrap() | 837 | Expr::cast(&n.syntax).unwrap() |
@@ -887,6 +893,7 @@ impl AstNode for Expr { | |||
887 | | METHOD_CALL_EXPR | 893 | | METHOD_CALL_EXPR |
888 | | FIELD_EXPR | 894 | | FIELD_EXPR |
889 | | TRY_EXPR | 895 | | TRY_EXPR |
896 | | TRY_BLOCK_EXPR | ||
890 | | CAST_EXPR | 897 | | CAST_EXPR |
891 | | REF_EXPR | 898 | | REF_EXPR |
892 | | PREFIX_EXPR | 899 | | PREFIX_EXPR |
@@ -929,6 +936,7 @@ impl Expr { | |||
929 | METHOD_CALL_EXPR => ExprKind::MethodCallExpr(MethodCallExpr::cast(&self.syntax).unwrap()), | 936 | METHOD_CALL_EXPR => ExprKind::MethodCallExpr(MethodCallExpr::cast(&self.syntax).unwrap()), |
930 | FIELD_EXPR => ExprKind::FieldExpr(FieldExpr::cast(&self.syntax).unwrap()), | 937 | FIELD_EXPR => ExprKind::FieldExpr(FieldExpr::cast(&self.syntax).unwrap()), |
931 | TRY_EXPR => ExprKind::TryExpr(TryExpr::cast(&self.syntax).unwrap()), | 938 | TRY_EXPR => ExprKind::TryExpr(TryExpr::cast(&self.syntax).unwrap()), |
939 | TRY_BLOCK_EXPR => ExprKind::TryBlockExpr(TryBlockExpr::cast(&self.syntax).unwrap()), | ||
932 | CAST_EXPR => ExprKind::CastExpr(CastExpr::cast(&self.syntax).unwrap()), | 940 | CAST_EXPR => ExprKind::CastExpr(CastExpr::cast(&self.syntax).unwrap()), |
933 | REF_EXPR => ExprKind::RefExpr(RefExpr::cast(&self.syntax).unwrap()), | 941 | REF_EXPR => ExprKind::RefExpr(RefExpr::cast(&self.syntax).unwrap()), |
934 | PREFIX_EXPR => ExprKind::PrefixExpr(PrefixExpr::cast(&self.syntax).unwrap()), | 942 | PREFIX_EXPR => ExprKind::PrefixExpr(PrefixExpr::cast(&self.syntax).unwrap()), |
@@ -3672,6 +3680,35 @@ impl TraitDef { | |||
3672 | } | 3680 | } |
3673 | } | 3681 | } |
3674 | 3682 | ||
3683 | // TryBlockExpr | ||
3684 | #[derive(Debug, PartialEq, Eq, Hash)] | ||
3685 | #[repr(transparent)] | ||
3686 | pub struct TryBlockExpr { | ||
3687 | pub(crate) syntax: SyntaxNode, | ||
3688 | } | ||
3689 | unsafe impl TransparentNewType for TryBlockExpr { | ||
3690 | type Repr = rowan::SyntaxNode; | ||
3691 | } | ||
3692 | |||
3693 | impl AstNode for TryBlockExpr { | ||
3694 | fn cast(syntax: &SyntaxNode) -> Option<&Self> { | ||
3695 | match syntax.kind() { | ||
3696 | TRY_BLOCK_EXPR => Some(TryBlockExpr::from_repr(syntax.into_repr())), | ||
3697 | _ => None, | ||
3698 | } | ||
3699 | } | ||
3700 | fn syntax(&self) -> &SyntaxNode { &self.syntax } | ||
3701 | } | ||
3702 | |||
3703 | impl ToOwned for TryBlockExpr { | ||
3704 | type Owned = TreeArc<TryBlockExpr>; | ||
3705 | fn to_owned(&self) -> TreeArc<TryBlockExpr> { TreeArc::cast(self.syntax.to_owned()) } | ||
3706 | } | ||
3707 | |||
3708 | |||
3709 | impl ast::TryBlockBodyOwner for TryBlockExpr {} | ||
3710 | impl TryBlockExpr {} | ||
3711 | |||
3675 | // TryExpr | 3712 | // TryExpr |
3676 | #[derive(Debug, PartialEq, Eq, Hash)] | 3713 | #[derive(Debug, PartialEq, Eq, Hash)] |
3677 | #[repr(transparent)] | 3714 | #[repr(transparent)] |
diff --git a/crates/ra_syntax/src/ast/traits.rs b/crates/ra_syntax/src/ast/traits.rs index 1c90cf148..433485400 100644 --- a/crates/ra_syntax/src/ast/traits.rs +++ b/crates/ra_syntax/src/ast/traits.rs | |||
@@ -33,6 +33,12 @@ pub trait LoopBodyOwner: AstNode { | |||
33 | } | 33 | } |
34 | } | 34 | } |
35 | 35 | ||
36 | pub trait TryBlockBodyOwner: AstNode { | ||
37 | fn try_body(&self) -> Option<&ast::Block> { | ||
38 | child_opt(self) | ||
39 | } | ||
40 | } | ||
41 | |||
36 | pub trait ArgListOwner: AstNode { | 42 | pub trait ArgListOwner: AstNode { |
37 | fn arg_list(&self) -> Option<&ast::ArgList> { | 43 | fn arg_list(&self) -> Option<&ast::ArgList> { |
38 | child_opt(self) | 44 | child_opt(self) |
diff --git a/crates/ra_syntax/src/grammar.ron b/crates/ra_syntax/src/grammar.ron index b8665bbc8..1c2714307 100644 --- a/crates/ra_syntax/src/grammar.ron +++ b/crates/ra_syntax/src/grammar.ron | |||
@@ -95,6 +95,7 @@ Grammar( | |||
95 | "let", | 95 | "let", |
96 | "move", | 96 | "move", |
97 | "return", | 97 | "return", |
98 | "try", | ||
98 | ], | 99 | ], |
99 | contextual_keywords: [ | 100 | contextual_keywords: [ |
100 | "auto", | 101 | "auto", |
@@ -189,6 +190,7 @@ Grammar( | |||
189 | "STRUCT_LIT", | 190 | "STRUCT_LIT", |
190 | "NAMED_FIELD_LIST", | 191 | "NAMED_FIELD_LIST", |
191 | "NAMED_FIELD", | 192 | "NAMED_FIELD", |
193 | "TRY_BLOCK_EXPR", | ||
192 | 194 | ||
193 | // postfix | 195 | // postfix |
194 | "CALL_EXPR", | 196 | "CALL_EXPR", |
@@ -417,6 +419,9 @@ Grammar( | |||
417 | "LoopExpr": ( | 419 | "LoopExpr": ( |
418 | traits: ["LoopBodyOwner"], | 420 | traits: ["LoopBodyOwner"], |
419 | ), | 421 | ), |
422 | "TryBlockExpr": ( | ||
423 | traits: ["TryBlockBodyOwner"], | ||
424 | ), | ||
420 | "ForExpr": ( | 425 | "ForExpr": ( |
421 | traits: ["LoopBodyOwner"], | 426 | traits: ["LoopBodyOwner"], |
422 | options: [ | 427 | options: [ |
@@ -499,6 +504,7 @@ Grammar( | |||
499 | "MethodCallExpr", | 504 | "MethodCallExpr", |
500 | "FieldExpr", | 505 | "FieldExpr", |
501 | "TryExpr", | 506 | "TryExpr", |
507 | "TryBlockExpr", | ||
502 | "CastExpr", | 508 | "CastExpr", |
503 | "RefExpr", | 509 | "RefExpr", |
504 | "PrefixExpr", | 510 | "PrefixExpr", |
diff --git a/crates/ra_syntax/src/parsing/lexer/numbers.rs b/crates/ra_syntax/src/parsing/lexer/numbers.rs index 7f6abe1d5..874fb8b32 100644 --- a/crates/ra_syntax/src/parsing/lexer/numbers.rs +++ b/crates/ra_syntax/src/parsing/lexer/numbers.rs | |||
@@ -16,7 +16,7 @@ pub(crate) fn scan_number(c: char, ptr: &mut Ptr) -> SyntaxKind { | |||
16 | ptr.bump(); | 16 | ptr.bump(); |
17 | scan_digits(ptr, true); | 17 | scan_digits(ptr, true); |
18 | } | 18 | } |
19 | '0'...'9' | '_' | '.' | 'e' | 'E' => { | 19 | '0'..='9' | '_' | '.' | 'e' | 'E' => { |
20 | scan_digits(ptr, true); | 20 | scan_digits(ptr, true); |
21 | } | 21 | } |
22 | _ => return INT_NUMBER, | 22 | _ => return INT_NUMBER, |
@@ -47,10 +47,10 @@ pub(crate) fn scan_number(c: char, ptr: &mut Ptr) -> SyntaxKind { | |||
47 | fn scan_digits(ptr: &mut Ptr, allow_hex: bool) { | 47 | fn scan_digits(ptr: &mut Ptr, allow_hex: bool) { |
48 | while let Some(c) = ptr.current() { | 48 | while let Some(c) = ptr.current() { |
49 | match c { | 49 | match c { |
50 | '_' | '0'...'9' => { | 50 | '_' | '0'..='9' => { |
51 | ptr.bump(); | 51 | ptr.bump(); |
52 | } | 52 | } |
53 | 'a'...'f' | 'A'...'F' if allow_hex => { | 53 | 'a'..='f' | 'A'..='F' if allow_hex => { |
54 | ptr.bump(); | 54 | ptr.bump(); |
55 | } | 55 | } |
56 | _ => return, | 56 | _ => return, |
diff --git a/crates/ra_syntax/src/validation/unescape.rs b/crates/ra_syntax/src/validation/unescape.rs index 2086046b6..91dbcfae8 100644 --- a/crates/ra_syntax/src/validation/unescape.rs +++ b/crates/ra_syntax/src/validation/unescape.rs | |||
@@ -255,7 +255,7 @@ where | |||
255 | let first_non_space = str | 255 | let first_non_space = str |
256 | .bytes() | 256 | .bytes() |
257 | .position(|b| b != b' ' && b != b'\t' && b != b'\n' && b != b'\r') | 257 | .position(|b| b != b' ' && b != b'\t' && b != b'\n' && b != b'\r') |
258 | .unwrap_or(str.len()); | 258 | .unwrap_or_else(|| str.len()); |
259 | *chars = str[first_non_space..].chars() | 259 | *chars = str[first_non_space..].chars() |
260 | } | 260 | } |
261 | } | 261 | } |
diff --git a/crates/ra_syntax/tests/data/parser/inline/ok/0130_try_block_expr.rs b/crates/ra_syntax/tests/data/parser/inline/ok/0130_try_block_expr.rs new file mode 100644 index 000000000..0f1b41eb6 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/ok/0130_try_block_expr.rs | |||
@@ -0,0 +1,3 @@ | |||
1 | fn foo() { | ||
2 | let _ = try {}; | ||
3 | } | ||
diff --git a/crates/ra_syntax/tests/data/parser/inline/ok/0130_try_block_expr.txt b/crates/ra_syntax/tests/data/parser/inline/ok/0130_try_block_expr.txt new file mode 100644 index 000000000..53f49b9b5 --- /dev/null +++ b/crates/ra_syntax/tests/data/parser/inline/ok/0130_try_block_expr.txt | |||
@@ -0,0 +1,31 @@ | |||
1 | SOURCE_FILE@[0; 33) | ||
2 | FN_DEF@[0; 32) | ||
3 | FN_KW@[0; 2) "fn" | ||
4 | WHITESPACE@[2; 3) " " | ||
5 | NAME@[3; 6) | ||
6 | IDENT@[3; 6) "foo" | ||
7 | PARAM_LIST@[6; 8) | ||
8 | L_PAREN@[6; 7) "(" | ||
9 | R_PAREN@[7; 8) ")" | ||
10 | WHITESPACE@[8; 9) " " | ||
11 | BLOCK@[9; 32) | ||
12 | L_CURLY@[9; 10) "{" | ||
13 | WHITESPACE@[10; 15) "\n " | ||
14 | LET_STMT@[15; 30) | ||
15 | LET_KW@[15; 18) "let" | ||
16 | WHITESPACE@[18; 19) " " | ||
17 | PLACEHOLDER_PAT@[19; 20) | ||
18 | UNDERSCORE@[19; 20) "_" | ||
19 | WHITESPACE@[20; 21) " " | ||
20 | EQ@[21; 22) "=" | ||
21 | WHITESPACE@[22; 23) " " | ||
22 | TRY_EXPR@[23; 29) | ||
23 | TRY_KW@[23; 26) "try" | ||
24 | WHITESPACE@[26; 27) " " | ||
25 | BLOCK@[27; 29) | ||
26 | L_CURLY@[27; 28) "{" | ||
27 | R_CURLY@[28; 29) "}" | ||
28 | SEMI@[29; 30) ";" | ||
29 | WHITESPACE@[30; 31) "\n" | ||
30 | R_CURLY@[31; 32) "}" | ||
31 | WHITESPACE@[32; 33) "\n" | ||
diff --git a/crates/ra_text_edit/src/test_utils.rs b/crates/ra_text_edit/src/test_utils.rs index 9e21b24f6..2dc0e71af 100644 --- a/crates/ra_text_edit/src/test_utils.rs +++ b/crates/ra_text_edit/src/test_utils.rs | |||
@@ -42,8 +42,8 @@ pub fn arb_text_edit(text: &str) -> BoxedStrategy<TextEdit> { | |||
42 | .prop_flat_map(|cuts| { | 42 | .prop_flat_map(|cuts| { |
43 | let strategies: Vec<_> = cuts | 43 | let strategies: Vec<_> = cuts |
44 | .chunks(2) | 44 | .chunks(2) |
45 | .map(|chunk| match chunk { | 45 | .map(|chunk| match *chunk { |
46 | &[from, to] => { | 46 | [from, to] => { |
47 | let range = TextRange::from_to(from, to); | 47 | let range = TextRange::from_to(from, to); |
48 | Just(AtomTextEdit::delete(range)) | 48 | Just(AtomTextEdit::delete(range)) |
49 | .boxed() | 49 | .boxed() |
@@ -54,7 +54,7 @@ pub fn arb_text_edit(text: &str) -> BoxedStrategy<TextEdit> { | |||
54 | ) | 54 | ) |
55 | .boxed() | 55 | .boxed() |
56 | } | 56 | } |
57 | &[x] => arb_text().prop_map(move |text| AtomTextEdit::insert(x, text)).boxed(), | 57 | [x] => arb_text().prop_map(move |text| AtomTextEdit::insert(x, text)).boxed(), |
58 | _ => unreachable!(), | 58 | _ => unreachable!(), |
59 | }) | 59 | }) |
60 | .collect(); | 60 | .collect(); |
diff --git a/crates/ra_tt/src/buffer.rs b/crates/ra_tt/src/buffer.rs index 995c9f90b..5659aeae8 100644 --- a/crates/ra_tt/src/buffer.rs +++ b/crates/ra_tt/src/buffer.rs | |||
@@ -179,6 +179,6 @@ impl<'a> Cursor<'a> { | |||
179 | /// Check whether it is a top level | 179 | /// Check whether it is a top level |
180 | pub fn is_root(&self) -> bool { | 180 | pub fn is_root(&self) -> bool { |
181 | let entry_id = self.ptr.0; | 181 | let entry_id = self.ptr.0; |
182 | return entry_id.0 == 0; | 182 | entry_id.0 == 0 |
183 | } | 183 | } |
184 | } | 184 | } |
diff --git a/crates/test_utils/src/lib.rs b/crates/test_utils/src/lib.rs index 7f55779cf..8bb3b3937 100644 --- a/crates/test_utils/src/lib.rs +++ b/crates/test_utils/src/lib.rs | |||
@@ -318,7 +318,7 @@ pub fn project_dir() -> PathBuf { | |||
318 | /// so this should always be correct. | 318 | /// so this should always be correct. |
319 | pub fn read_text(path: &Path) -> String { | 319 | pub fn read_text(path: &Path) -> String { |
320 | fs::read_to_string(path) | 320 | fs::read_to_string(path) |
321 | .expect(&format!("File at {:?} should be valid", path)) | 321 | .unwrap_or_else(|_| panic!("File at {:?} should be valid", path)) |
322 | .replace("\r\n", "\n") | 322 | .replace("\r\n", "\n") |
323 | } | 323 | } |
324 | 324 | ||
diff --git a/crates/thread_worker/src/lib.rs b/crates/thread_worker/src/lib.rs index d67e44e38..d8d0d9bf2 100644 --- a/crates/thread_worker/src/lib.rs +++ b/crates/thread_worker/src/lib.rs | |||
@@ -19,13 +19,10 @@ impl Drop for ScopedThread { | |||
19 | log::info!(".. {} terminated with {}", name, if res.is_ok() { "ok" } else { "err" }); | 19 | log::info!(".. {} terminated with {}", name, if res.is_ok() { "ok" } else { "err" }); |
20 | 20 | ||
21 | // escalate panic, but avoid aborting the process | 21 | // escalate panic, but avoid aborting the process |
22 | match res { | 22 | if let Err(e) = res { |
23 | Err(e) => { | 23 | if !thread::panicking() { |
24 | if !thread::panicking() { | 24 | panic!(e) |
25 | panic!(e) | ||
26 | } | ||
27 | } | 25 | } |
28 | _ => (), | ||
29 | } | 26 | } |
30 | } | 27 | } |
31 | } | 28 | } |
diff --git a/crates/tools/src/lib.rs b/crates/tools/src/lib.rs index 11b52ccb7..2446fdf28 100644 --- a/crates/tools/src/lib.rs +++ b/crates/tools/src/lib.rs | |||
@@ -133,6 +133,40 @@ pub fn install_format_hook() -> Result<()> { | |||
133 | Ok(()) | 133 | Ok(()) |
134 | } | 134 | } |
135 | 135 | ||
136 | pub fn run_clippy() -> Result<()> { | ||
137 | match Command::new("rustup") | ||
138 | .args(&["run", TOOLCHAIN, "--", "cargo", "clippy", "--version"]) | ||
139 | .stderr(Stdio::null()) | ||
140 | .stdout(Stdio::null()) | ||
141 | .status() | ||
142 | { | ||
143 | Ok(status) if status.success() => (), | ||
144 | _ => install_clippy()?, | ||
145 | }; | ||
146 | |||
147 | let allowed_lints = [ | ||
148 | "clippy::collapsible_if", | ||
149 | "clippy::map_clone", // FIXME: remove when Iterator::copied stabilizes (1.36.0) | ||
150 | "clippy::needless_pass_by_value", | ||
151 | "clippy::nonminimal_bool", | ||
152 | "clippy::redundant_pattern_matching", | ||
153 | ]; | ||
154 | run( | ||
155 | &format!( | ||
156 | "rustup run {} -- cargo clippy --all-features --all-targets -- -A {}", | ||
157 | TOOLCHAIN, | ||
158 | allowed_lints.join(" -A ") | ||
159 | ), | ||
160 | ".", | ||
161 | )?; | ||
162 | Ok(()) | ||
163 | } | ||
164 | |||
165 | pub fn install_clippy() -> Result<()> { | ||
166 | run(&format!("rustup install {}", TOOLCHAIN), ".")?; | ||
167 | run(&format!("rustup component add clippy --toolchain {}", TOOLCHAIN), ".") | ||
168 | } | ||
169 | |||
136 | pub fn run_fuzzer() -> Result<()> { | 170 | pub fn run_fuzzer() -> Result<()> { |
137 | match Command::new("cargo") | 171 | match Command::new("cargo") |
138 | .args(&["fuzz", "--help"]) | 172 | .args(&["fuzz", "--help"]) |
diff --git a/crates/tools/src/main.rs b/crates/tools/src/main.rs index 0c3339685..8027ff833 100644 --- a/crates/tools/src/main.rs +++ b/crates/tools/src/main.rs | |||
@@ -3,7 +3,7 @@ use core::str; | |||
3 | use failure::bail; | 3 | use failure::bail; |
4 | use tools::{ | 4 | use tools::{ |
5 | generate, gen_tests, install_format_hook, run, run_with_output, run_rustfmt, | 5 | generate, gen_tests, install_format_hook, run, run_with_output, run_rustfmt, |
6 | Overwrite, Result, run_fuzzer, | 6 | Overwrite, Result, run_fuzzer, run_clippy, |
7 | }; | 7 | }; |
8 | use std::{path::{PathBuf}, env}; | 8 | use std::{path::{PathBuf}, env}; |
9 | 9 | ||
@@ -16,6 +16,7 @@ fn main() -> Result<()> { | |||
16 | .subcommand(SubCommand::with_name("format")) | 16 | .subcommand(SubCommand::with_name("format")) |
17 | .subcommand(SubCommand::with_name("format-hook")) | 17 | .subcommand(SubCommand::with_name("format-hook")) |
18 | .subcommand(SubCommand::with_name("fuzz-tests")) | 18 | .subcommand(SubCommand::with_name("fuzz-tests")) |
19 | .subcommand(SubCommand::with_name("lint")) | ||
19 | .get_matches(); | 20 | .get_matches(); |
20 | match matches.subcommand_name().expect("Subcommand must be specified") { | 21 | match matches.subcommand_name().expect("Subcommand must be specified") { |
21 | "install-code" => { | 22 | "install-code" => { |
@@ -28,6 +29,7 @@ fn main() -> Result<()> { | |||
28 | "gen-syntax" => generate(Overwrite)?, | 29 | "gen-syntax" => generate(Overwrite)?, |
29 | "format" => run_rustfmt(Overwrite)?, | 30 | "format" => run_rustfmt(Overwrite)?, |
30 | "format-hook" => install_format_hook()?, | 31 | "format-hook" => install_format_hook()?, |
32 | "lint" => run_clippy()?, | ||
31 | "fuzz-tests" => run_fuzzer()?, | 33 | "fuzz-tests" => run_fuzzer()?, |
32 | _ => unreachable!(), | 34 | _ => unreachable!(), |
33 | } | 35 | } |
@@ -82,7 +84,7 @@ fn fix_path_for_mac() -> Result<()> { | |||
82 | 84 | ||
83 | [ROOT_DIR, &home_dir] | 85 | [ROOT_DIR, &home_dir] |
84 | .iter() | 86 | .iter() |
85 | .map(|dir| String::from(dir.clone()) + COMMON_APP_PATH) | 87 | .map(|dir| String::from(*dir) + COMMON_APP_PATH) |
86 | .map(PathBuf::from) | 88 | .map(PathBuf::from) |
87 | .filter(|path| path.exists()) | 89 | .filter(|path| path.exists()) |
88 | .collect() | 90 | .collect() |