diff options
26 files changed, 204 insertions, 362 deletions
diff --git a/Cargo.lock b/Cargo.lock index f9f1c041e..dcf939d60 100644 --- a/Cargo.lock +++ b/Cargo.lock | |||
@@ -26,9 +26,9 @@ dependencies = [ | |||
26 | 26 | ||
27 | [[package]] | 27 | [[package]] |
28 | name = "anyhow" | 28 | name = "anyhow" |
29 | version = "1.0.38" | 29 | version = "1.0.37" |
30 | source = "registry+https://github.com/rust-lang/crates.io-index" | 30 | source = "registry+https://github.com/rust-lang/crates.io-index" |
31 | checksum = "afddf7f520a80dbf76e6f50a35bca42a2331ef227a28b3b6dc5c2e2338d114b1" | 31 | checksum = "ee67c11feeac938fae061b232e38e0b6d94f97a9df10e6271319325ac4c56a86" |
32 | 32 | ||
33 | [[package]] | 33 | [[package]] |
34 | name = "anymap" | 34 | name = "anymap" |
@@ -118,9 +118,9 @@ checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" | |||
118 | 118 | ||
119 | [[package]] | 119 | [[package]] |
120 | name = "byteorder" | 120 | name = "byteorder" |
121 | version = "1.4.2" | 121 | version = "1.3.4" |
122 | source = "registry+https://github.com/rust-lang/crates.io-index" | 122 | source = "registry+https://github.com/rust-lang/crates.io-index" |
123 | checksum = "ae44d1a3d5a19df61dd0c8beb138458ac2a53a7ac09eba97d55592540004306b" | 123 | checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de" |
124 | 124 | ||
125 | [[package]] | 125 | [[package]] |
126 | name = "cargo-platform" | 126 | name = "cargo-platform" |
@@ -269,9 +269,9 @@ dependencies = [ | |||
269 | 269 | ||
270 | [[package]] | 270 | [[package]] |
271 | name = "const_fn" | 271 | name = "const_fn" |
272 | version = "0.4.5" | 272 | version = "0.4.4" |
273 | source = "registry+https://github.com/rust-lang/crates.io-index" | 273 | source = "registry+https://github.com/rust-lang/crates.io-index" |
274 | checksum = "28b9d6de7f49e22cf97ad17fc4036ece69300032f45f78f30b4a4482cdc3f4a6" | 274 | checksum = "cd51eab21ab4fd6a3bf889e2d0958c0a6e3a61ad04260325e919e652a2a62826" |
275 | 275 | ||
276 | [[package]] | 276 | [[package]] |
277 | name = "crc32fast" | 277 | name = "crc32fast" |
@@ -791,9 +791,9 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" | |||
791 | 791 | ||
792 | [[package]] | 792 | [[package]] |
793 | name = "libc" | 793 | name = "libc" |
794 | version = "0.2.82" | 794 | version = "0.2.81" |
795 | source = "registry+https://github.com/rust-lang/crates.io-index" | 795 | source = "registry+https://github.com/rust-lang/crates.io-index" |
796 | checksum = "89203f3fba0a3795506acaad8ebce3c80c0af93f994d5a1d7a0b1eeb23271929" | 796 | checksum = "1482821306169ec4d07f6aca392a4681f66c75c9918aa49641a2595db64053cb" |
797 | 797 | ||
798 | [[package]] | 798 | [[package]] |
799 | name = "libloading" | 799 | name = "libloading" |
@@ -825,9 +825,9 @@ dependencies = [ | |||
825 | 825 | ||
826 | [[package]] | 826 | [[package]] |
827 | name = "log" | 827 | name = "log" |
828 | version = "0.4.13" | 828 | version = "0.4.11" |
829 | source = "registry+https://github.com/rust-lang/crates.io-index" | 829 | source = "registry+https://github.com/rust-lang/crates.io-index" |
830 | checksum = "fcf3805d4480bb5b86070dcfeb9e2cb2ebc148adb753c5cca5f884d1d65a42b2" | 830 | checksum = "4fabed175da42fed1fa0746b0ea71f412aa9d35e76e95e59b192c64b9dc2bf8b" |
831 | dependencies = [ | 831 | dependencies = [ |
832 | "cfg-if 0.1.10", | 832 | "cfg-if 0.1.10", |
833 | ] | 833 | ] |
@@ -1160,9 +1160,9 @@ checksum = "28b9b4df73455c861d7cbf8be42f01d3b373ed7f02e378d55fa84eafc6f638b1" | |||
1160 | 1160 | ||
1161 | [[package]] | 1161 | [[package]] |
1162 | name = "pin-project-lite" | 1162 | name = "pin-project-lite" |
1163 | version = "0.2.4" | 1163 | version = "0.2.0" |
1164 | source = "registry+https://github.com/rust-lang/crates.io-index" | 1164 | source = "registry+https://github.com/rust-lang/crates.io-index" |
1165 | checksum = "439697af366c49a6d0a010c56a0d97685bc140ce0d377b13a2ea2aa42d64a827" | 1165 | checksum = "6b063f57ec186e6140e2b8b6921e5f1bd89c7356dda5b33acc5401203ca6131c" |
1166 | 1166 | ||
1167 | [[package]] | 1167 | [[package]] |
1168 | name = "proc-macro2" | 1168 | name = "proc-macro2" |
@@ -1300,9 +1300,9 @@ checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce" | |||
1300 | 1300 | ||
1301 | [[package]] | 1301 | [[package]] |
1302 | name = "regex" | 1302 | name = "regex" |
1303 | version = "1.4.3" | 1303 | version = "1.4.2" |
1304 | source = "registry+https://github.com/rust-lang/crates.io-index" | 1304 | source = "registry+https://github.com/rust-lang/crates.io-index" |
1305 | checksum = "d9251239e129e16308e70d853559389de218ac275b515068abc96829d05b948a" | 1305 | checksum = "38cf2c13ed4745de91a5eb834e11c00bcc3709e773173b2ce4c56c9fbde04b9c" |
1306 | dependencies = [ | 1306 | dependencies = [ |
1307 | "regex-syntax", | 1307 | "regex-syntax", |
1308 | ] | 1308 | ] |
@@ -1319,9 +1319,9 @@ dependencies = [ | |||
1319 | 1319 | ||
1320 | [[package]] | 1320 | [[package]] |
1321 | name = "regex-syntax" | 1321 | name = "regex-syntax" |
1322 | version = "0.6.22" | 1322 | version = "0.6.21" |
1323 | source = "registry+https://github.com/rust-lang/crates.io-index" | 1323 | source = "registry+https://github.com/rust-lang/crates.io-index" |
1324 | checksum = "b5eb417147ba9860a96cfe72a0b93bf88fee1744b5636ec99ab20c1aa9376581" | 1324 | checksum = "3b181ba2dcf07aaccad5448e8ead58db5b742cf85dfe035e2227f137a539a189" |
1325 | 1325 | ||
1326 | [[package]] | 1326 | [[package]] |
1327 | name = "rowan" | 1327 | name = "rowan" |
@@ -1550,9 +1550,9 @@ checksum = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8" | |||
1550 | 1550 | ||
1551 | [[package]] | 1551 | [[package]] |
1552 | name = "smallvec" | 1552 | name = "smallvec" |
1553 | version = "1.6.1" | 1553 | version = "1.6.0" |
1554 | source = "registry+https://github.com/rust-lang/crates.io-index" | 1554 | source = "registry+https://github.com/rust-lang/crates.io-index" |
1555 | checksum = "fe0f37c9e8f3c5a4a66ad655a93c74daac4ad00c441533bf5c6e7990bb42604e" | 1555 | checksum = "1a55ca5f3b68e41c979bf8c46a6f1da892ca4db8f94023ce0bd32407573b1ac0" |
1556 | 1556 | ||
1557 | [[package]] | 1557 | [[package]] |
1558 | name = "smol_str" | 1558 | name = "smol_str" |
@@ -1592,9 +1592,9 @@ dependencies = [ | |||
1592 | 1592 | ||
1593 | [[package]] | 1593 | [[package]] |
1594 | name = "syn" | 1594 | name = "syn" |
1595 | version = "1.0.58" | 1595 | version = "1.0.57" |
1596 | source = "registry+https://github.com/rust-lang/crates.io-index" | 1596 | source = "registry+https://github.com/rust-lang/crates.io-index" |
1597 | checksum = "cc60a3d73ea6594cd712d830cc1f0390fd71542d8c8cd24e70cc54cdfd5e05d5" | 1597 | checksum = "4211ce9909eb971f111059df92c45640aad50a619cf55cd76476be803c4c68e6" |
1598 | dependencies = [ | 1598 | dependencies = [ |
1599 | "proc-macro2", | 1599 | "proc-macro2", |
1600 | "quote", | 1600 | "quote", |
@@ -1671,9 +1671,9 @@ dependencies = [ | |||
1671 | 1671 | ||
1672 | [[package]] | 1672 | [[package]] |
1673 | name = "thread_local" | 1673 | name = "thread_local" |
1674 | version = "1.1.0" | 1674 | version = "1.0.1" |
1675 | source = "registry+https://github.com/rust-lang/crates.io-index" | 1675 | source = "registry+https://github.com/rust-lang/crates.io-index" |
1676 | checksum = "bb9bc092d0d51e76b2b19d9d85534ffc9ec2db959a2523cdae0697e2972cd447" | 1676 | checksum = "d40c6d1b69745a6ec6fb1ca717914848da4b44ae29d9b3080cbee91d72a69b14" |
1677 | dependencies = [ | 1677 | dependencies = [ |
1678 | "lazy_static", | 1678 | "lazy_static", |
1679 | ] | 1679 | ] |
@@ -1837,9 +1837,9 @@ checksum = "56dee185309b50d1f11bfedef0fe6d036842e3fb77413abef29f8f8d1c5d4c1c" | |||
1837 | 1837 | ||
1838 | [[package]] | 1838 | [[package]] |
1839 | name = "ungrammar" | 1839 | name = "ungrammar" |
1840 | version = "1.6.0" | 1840 | version = "1.7.0" |
1841 | source = "registry+https://github.com/rust-lang/crates.io-index" | 1841 | source = "registry+https://github.com/rust-lang/crates.io-index" |
1842 | checksum = "f96cc1b6938f7c548fbcc630bac5c896ae77a130909829ab18b8eab78c51b7ee" | 1842 | checksum = "7758fccf6038d5c368a17c7224abc85d6508d5ae266d5a3de25faac3cc168509" |
1843 | 1843 | ||
1844 | [[package]] | 1844 | [[package]] |
1845 | name = "unicase" | 1845 | name = "unicase" |
diff --git a/crates/assists/src/assist_context.rs b/crates/assists/src/assist_context.rs index 321fe77f3..8d93edba2 100644 --- a/crates/assists/src/assist_context.rs +++ b/crates/assists/src/assist_context.rs | |||
@@ -2,7 +2,6 @@ | |||
2 | 2 | ||
3 | use std::mem; | 3 | use std::mem; |
4 | 4 | ||
5 | use algo::find_covering_element; | ||
6 | use hir::Semantics; | 5 | use hir::Semantics; |
7 | use ide_db::{ | 6 | use ide_db::{ |
8 | base_db::{AnchoredPathBuf, FileId, FileRange}, | 7 | base_db::{AnchoredPathBuf, FileId, FileRange}, |
@@ -94,11 +93,11 @@ impl<'a> AssistContext<'a> { | |||
94 | self.sema.find_node_at_offset_with_descend(self.source_file.syntax(), self.offset()) | 93 | self.sema.find_node_at_offset_with_descend(self.source_file.syntax(), self.offset()) |
95 | } | 94 | } |
96 | pub(crate) fn covering_element(&self) -> SyntaxElement { | 95 | pub(crate) fn covering_element(&self) -> SyntaxElement { |
97 | find_covering_element(self.source_file.syntax(), self.frange.range) | 96 | self.source_file.syntax().covering_element(self.frange.range) |
98 | } | 97 | } |
99 | // FIXME: remove | 98 | // FIXME: remove |
100 | pub(crate) fn covering_node_for_range(&self, range: TextRange) -> SyntaxElement { | 99 | pub(crate) fn covering_node_for_range(&self, range: TextRange) -> SyntaxElement { |
101 | find_covering_element(self.source_file.syntax(), range) | 100 | self.source_file.syntax().covering_element(range) |
102 | } | 101 | } |
103 | } | 102 | } |
104 | 103 | ||
diff --git a/crates/assists/src/handlers/inline_local_variable.rs b/crates/assists/src/handlers/inline_local_variable.rs index dc798daaa..0e63a60e8 100644 --- a/crates/assists/src/handlers/inline_local_variable.rs +++ b/crates/assists/src/handlers/inline_local_variable.rs | |||
@@ -79,29 +79,30 @@ pub(crate) fn inline_local_variable(acc: &mut Assists, ctx: &AssistContext) -> O | |||
79 | None => return Ok(false), | 79 | None => return Ok(false), |
80 | }; | 80 | }; |
81 | 81 | ||
82 | Ok(!matches!((&initializer_expr, usage_parent), | 82 | Ok(!matches!( |
83 | (&initializer_expr, usage_parent), | ||
83 | (ast::Expr::CallExpr(_), _) | 84 | (ast::Expr::CallExpr(_), _) |
84 | | (ast::Expr::IndexExpr(_), _) | 85 | | (ast::Expr::IndexExpr(_), _) |
85 | | (ast::Expr::MethodCallExpr(_), _) | 86 | | (ast::Expr::MethodCallExpr(_), _) |
86 | | (ast::Expr::FieldExpr(_), _) | 87 | | (ast::Expr::FieldExpr(_), _) |
87 | | (ast::Expr::TryExpr(_), _) | 88 | | (ast::Expr::TryExpr(_), _) |
88 | | (ast::Expr::RefExpr(_), _) | 89 | | (ast::Expr::RefExpr(_), _) |
89 | | (ast::Expr::Literal(_), _) | 90 | | (ast::Expr::Literal(_), _) |
90 | | (ast::Expr::TupleExpr(_), _) | 91 | | (ast::Expr::TupleExpr(_), _) |
91 | | (ast::Expr::ArrayExpr(_), _) | 92 | | (ast::Expr::ArrayExpr(_), _) |
92 | | (ast::Expr::ParenExpr(_), _) | 93 | | (ast::Expr::ParenExpr(_), _) |
93 | | (ast::Expr::PathExpr(_), _) | 94 | | (ast::Expr::PathExpr(_), _) |
94 | | (ast::Expr::BlockExpr(_), _) | 95 | | (ast::Expr::BlockExpr(_), _) |
95 | | (ast::Expr::EffectExpr(_), _) | 96 | | (ast::Expr::EffectExpr(_), _) |
96 | | (_, ast::Expr::CallExpr(_)) | 97 | | (_, ast::Expr::CallExpr(_)) |
97 | | (_, ast::Expr::TupleExpr(_)) | 98 | | (_, ast::Expr::TupleExpr(_)) |
98 | | (_, ast::Expr::ArrayExpr(_)) | 99 | | (_, ast::Expr::ArrayExpr(_)) |
99 | | (_, ast::Expr::ParenExpr(_)) | 100 | | (_, ast::Expr::ParenExpr(_)) |
100 | | (_, ast::Expr::ForExpr(_)) | 101 | | (_, ast::Expr::ForExpr(_)) |
101 | | (_, ast::Expr::WhileExpr(_)) | 102 | | (_, ast::Expr::WhileExpr(_)) |
102 | | (_, ast::Expr::BreakExpr(_)) | 103 | | (_, ast::Expr::BreakExpr(_)) |
103 | | (_, ast::Expr::ReturnExpr(_)) | 104 | | (_, ast::Expr::ReturnExpr(_)) |
104 | | (_, ast::Expr::MatchExpr(_)) | 105 | | (_, ast::Expr::MatchExpr(_)) |
105 | )) | 106 | )) |
106 | }) | 107 | }) |
107 | .collect::<Result<Vec<_>, _>>()?; | 108 | .collect::<Result<Vec<_>, _>>()?; |
diff --git a/crates/completion/src/context.rs b/crates/completion/src/context.rs index d809460e2..b1e8eba85 100644 --- a/crates/completion/src/context.rs +++ b/crates/completion/src/context.rs | |||
@@ -4,10 +4,8 @@ use hir::{Local, ScopeDef, Semantics, SemanticsScope, Type}; | |||
4 | use ide_db::base_db::{FilePosition, SourceDatabase}; | 4 | use ide_db::base_db::{FilePosition, SourceDatabase}; |
5 | use ide_db::{call_info::ActiveParameter, RootDatabase}; | 5 | use ide_db::{call_info::ActiveParameter, RootDatabase}; |
6 | use syntax::{ | 6 | use syntax::{ |
7 | algo::{find_covering_element, find_node_at_offset}, | 7 | algo::find_node_at_offset, ast, match_ast, AstNode, NodeOrToken, SyntaxKind::*, SyntaxNode, |
8 | ast, match_ast, AstNode, NodeOrToken, | 8 | SyntaxToken, TextRange, TextSize, |
9 | SyntaxKind::*, | ||
10 | SyntaxNode, SyntaxToken, TextRange, TextSize, | ||
11 | }; | 9 | }; |
12 | use test_utils::mark; | 10 | use test_utils::mark; |
13 | use text_edit::Indel; | 11 | use text_edit::Indel; |
@@ -513,7 +511,7 @@ impl<'a> CompletionContext<'a> { | |||
513 | } | 511 | } |
514 | 512 | ||
515 | fn find_node_with_range<N: AstNode>(syntax: &SyntaxNode, range: TextRange) -> Option<N> { | 513 | fn find_node_with_range<N: AstNode>(syntax: &SyntaxNode, range: TextRange) -> Option<N> { |
516 | find_covering_element(syntax, range).ancestors().find_map(N::cast) | 514 | syntax.covering_element(range).ancestors().find_map(N::cast) |
517 | } | 515 | } |
518 | 516 | ||
519 | fn is_node<N: AstNode>(node: &SyntaxNode) -> bool { | 517 | fn is_node<N: AstNode>(node: &SyntaxNode) -> bool { |
diff --git a/crates/hir_def/src/body/lower.rs b/crates/hir_def/src/body/lower.rs index 27575c537..4ce5e5b72 100644 --- a/crates/hir_def/src/body/lower.rs +++ b/crates/hir_def/src/body/lower.rs | |||
@@ -386,6 +386,10 @@ impl ExprCollector<'_> { | |||
386 | let expr = e.expr().map(|e| self.collect_expr(e)); | 386 | let expr = e.expr().map(|e| self.collect_expr(e)); |
387 | self.alloc_expr(Expr::Return { expr }, syntax_ptr) | 387 | self.alloc_expr(Expr::Return { expr }, syntax_ptr) |
388 | } | 388 | } |
389 | ast::Expr::YieldExpr(e) => { | ||
390 | let expr = e.expr().map(|e| self.collect_expr(e)); | ||
391 | self.alloc_expr(Expr::Yield { expr }, syntax_ptr) | ||
392 | } | ||
389 | ast::Expr::RecordExpr(e) => { | 393 | ast::Expr::RecordExpr(e) => { |
390 | let path = e.path().and_then(|path| self.expander.parse_path(path)); | 394 | let path = e.path().and_then(|path| self.expander.parse_path(path)); |
391 | let mut field_ptrs = Vec::new(); | 395 | let mut field_ptrs = Vec::new(); |
diff --git a/crates/hir_def/src/expr.rs b/crates/hir_def/src/expr.rs index af01d32dc..a293df9f1 100644 --- a/crates/hir_def/src/expr.rs +++ b/crates/hir_def/src/expr.rs | |||
@@ -99,6 +99,9 @@ pub enum Expr { | |||
99 | Return { | 99 | Return { |
100 | expr: Option<ExprId>, | 100 | expr: Option<ExprId>, |
101 | }, | 101 | }, |
102 | Yield { | ||
103 | expr: Option<ExprId>, | ||
104 | }, | ||
102 | RecordLit { | 105 | RecordLit { |
103 | path: Option<Path>, | 106 | path: Option<Path>, |
104 | fields: Vec<RecordLitField>, | 107 | fields: Vec<RecordLitField>, |
@@ -294,7 +297,7 @@ impl Expr { | |||
294 | } | 297 | } |
295 | } | 298 | } |
296 | Expr::Continue { .. } => {} | 299 | Expr::Continue { .. } => {} |
297 | Expr::Break { expr, .. } | Expr::Return { expr } => { | 300 | Expr::Break { expr, .. } | Expr::Return { expr } | Expr::Yield { expr } => { |
298 | if let Some(expr) = expr { | 301 | if let Some(expr) = expr { |
299 | f(*expr); | 302 | f(*expr); |
300 | } | 303 | } |
diff --git a/crates/hir_expand/src/db.rs b/crates/hir_expand/src/db.rs index c62086390..467516eb7 100644 --- a/crates/hir_expand/src/db.rs +++ b/crates/hir_expand/src/db.rs | |||
@@ -118,7 +118,7 @@ pub fn expand_hypothetical( | |||
118 | parse_macro_with_arg(db, macro_file, Some(std::sync::Arc::new((tt, tmap_1)))).value?; | 118 | parse_macro_with_arg(db, macro_file, Some(std::sync::Arc::new((tt, tmap_1)))).value?; |
119 | let token_id = macro_def.0.map_id_down(token_id); | 119 | let token_id = macro_def.0.map_id_down(token_id); |
120 | let range = tmap_2.range_by_token(token_id)?.by_kind(token_to_map.kind())?; | 120 | let range = tmap_2.range_by_token(token_id)?.by_kind(token_to_map.kind())?; |
121 | let token = syntax::algo::find_covering_element(&node.syntax_node(), range).into_token()?; | 121 | let token = node.syntax_node().covering_element(range).into_token()?; |
122 | Some((node.syntax_node(), token)) | 122 | Some((node.syntax_node(), token)) |
123 | } | 123 | } |
124 | 124 | ||
diff --git a/crates/hir_expand/src/lib.rs b/crates/hir_expand/src/lib.rs index 3fa1b1d77..e388ddacc 100644 --- a/crates/hir_expand/src/lib.rs +++ b/crates/hir_expand/src/lib.rs | |||
@@ -22,7 +22,7 @@ use std::sync::Arc; | |||
22 | 22 | ||
23 | use base_db::{impl_intern_key, salsa, CrateId, FileId, FileRange}; | 23 | use base_db::{impl_intern_key, salsa, CrateId, FileId, FileRange}; |
24 | use syntax::{ | 24 | use syntax::{ |
25 | algo::{self, skip_trivia_token}, | 25 | algo::skip_trivia_token, |
26 | ast::{self, AstNode}, | 26 | ast::{self, AstNode}, |
27 | Direction, SyntaxNode, SyntaxToken, TextRange, TextSize, | 27 | Direction, SyntaxNode, SyntaxToken, TextRange, TextSize, |
28 | }; | 28 | }; |
@@ -335,7 +335,7 @@ impl ExpansionInfo { | |||
335 | 335 | ||
336 | let range = self.exp_map.range_by_token(token_id)?.by_kind(token.value.kind())?; | 336 | let range = self.exp_map.range_by_token(token_id)?.by_kind(token.value.kind())?; |
337 | 337 | ||
338 | let token = algo::find_covering_element(&self.expanded.value, range).into_token()?; | 338 | let token = self.expanded.value.covering_element(range).into_token()?; |
339 | 339 | ||
340 | Some(self.expanded.with_value(token)) | 340 | Some(self.expanded.with_value(token)) |
341 | } | 341 | } |
@@ -360,8 +360,8 @@ impl ExpansionInfo { | |||
360 | }; | 360 | }; |
361 | 361 | ||
362 | let range = token_map.range_by_token(token_id)?.by_kind(token.value.kind())?; | 362 | let range = token_map.range_by_token(token_id)?.by_kind(token.value.kind())?; |
363 | let token = algo::find_covering_element(&tt.value, range + tt.value.text_range().start()) | 363 | let token = |
364 | .into_token()?; | 364 | tt.value.covering_element(range + tt.value.text_range().start()).into_token()?; |
365 | Some((tt.with_value(token), origin)) | 365 | Some((tt.with_value(token), origin)) |
366 | } | 366 | } |
367 | } | 367 | } |
diff --git a/crates/hir_ty/src/infer/expr.rs b/crates/hir_ty/src/infer/expr.rs index f2fc69b2f..9bf3b51b0 100644 --- a/crates/hir_ty/src/infer/expr.rs +++ b/crates/hir_ty/src/infer/expr.rs | |||
@@ -367,6 +367,13 @@ impl<'a> InferenceContext<'a> { | |||
367 | } | 367 | } |
368 | Ty::simple(TypeCtor::Never) | 368 | Ty::simple(TypeCtor::Never) |
369 | } | 369 | } |
370 | Expr::Yield { expr } => { | ||
371 | // FIXME: track yield type for coercion | ||
372 | if let Some(expr) = expr { | ||
373 | self.infer_expr(*expr, &Expectation::none()); | ||
374 | } | ||
375 | Ty::simple(TypeCtor::Never) | ||
376 | } | ||
370 | Expr::RecordLit { path, fields, spread } => { | 377 | Expr::RecordLit { path, fields, spread } => { |
371 | let (ty, def_id) = self.resolve_variant(path.as_ref()); | 378 | let (ty, def_id) = self.resolve_variant(path.as_ref()); |
372 | if let Some(variant) = def_id { | 379 | if let Some(variant) = def_id { |
diff --git a/crates/ide/src/extend_selection.rs b/crates/ide/src/extend_selection.rs index 56418c960..17a540972 100644 --- a/crates/ide/src/extend_selection.rs +++ b/crates/ide/src/extend_selection.rs | |||
@@ -3,7 +3,7 @@ use std::iter::successors; | |||
3 | use hir::Semantics; | 3 | use hir::Semantics; |
4 | use ide_db::RootDatabase; | 4 | use ide_db::RootDatabase; |
5 | use syntax::{ | 5 | use syntax::{ |
6 | algo::{self, find_covering_element, skip_trivia_token}, | 6 | algo::{self, skip_trivia_token}, |
7 | ast::{self, AstNode, AstToken}, | 7 | ast::{self, AstNode, AstToken}, |
8 | Direction, NodeOrToken, | 8 | Direction, NodeOrToken, |
9 | SyntaxKind::{self, *}, | 9 | SyntaxKind::{self, *}, |
@@ -76,7 +76,7 @@ fn try_extend_selection( | |||
76 | }; | 76 | }; |
77 | return Some(leaf_range); | 77 | return Some(leaf_range); |
78 | }; | 78 | }; |
79 | let node = match find_covering_element(root, range) { | 79 | let node = match root.covering_element(range) { |
80 | NodeOrToken::Token(token) => { | 80 | NodeOrToken::Token(token) => { |
81 | if token.text_range() != range { | 81 | if token.text_range() != range { |
82 | return Some(token.text_range()); | 82 | return Some(token.text_range()); |
@@ -120,7 +120,7 @@ fn extend_tokens_from_range( | |||
120 | macro_call: ast::MacroCall, | 120 | macro_call: ast::MacroCall, |
121 | original_range: TextRange, | 121 | original_range: TextRange, |
122 | ) -> Option<TextRange> { | 122 | ) -> Option<TextRange> { |
123 | let src = find_covering_element(¯o_call.syntax(), original_range); | 123 | let src = macro_call.syntax().covering_element(original_range); |
124 | let (first_token, last_token) = match src { | 124 | let (first_token, last_token) = match src { |
125 | NodeOrToken::Node(it) => (it.first_token()?, it.last_token()?), | 125 | NodeOrToken::Node(it) => (it.first_token()?, it.last_token()?), |
126 | NodeOrToken::Token(it) => (it.clone(), it), | 126 | NodeOrToken::Token(it) => (it.clone(), it), |
diff --git a/crates/ide/src/join_lines.rs b/crates/ide/src/join_lines.rs index 05380f2a1..981467c8d 100644 --- a/crates/ide/src/join_lines.rs +++ b/crates/ide/src/join_lines.rs | |||
@@ -1,7 +1,7 @@ | |||
1 | use assists::utils::extract_trivial_expression; | 1 | use assists::utils::extract_trivial_expression; |
2 | use itertools::Itertools; | 2 | use itertools::Itertools; |
3 | use syntax::{ | 3 | use syntax::{ |
4 | algo::{find_covering_element, non_trivia_sibling}, | 4 | algo::non_trivia_sibling, |
5 | ast::{self, AstNode, AstToken}, | 5 | ast::{self, AstNode, AstToken}, |
6 | Direction, NodeOrToken, SourceFile, | 6 | Direction, NodeOrToken, SourceFile, |
7 | SyntaxKind::{self, USE_TREE, WHITESPACE}, | 7 | SyntaxKind::{self, USE_TREE, WHITESPACE}, |
@@ -31,7 +31,7 @@ pub(crate) fn join_lines(file: &SourceFile, range: TextRange) -> TextEdit { | |||
31 | range | 31 | range |
32 | }; | 32 | }; |
33 | 33 | ||
34 | let node = match find_covering_element(file.syntax(), range) { | 34 | let node = match file.syntax().covering_element(range) { |
35 | NodeOrToken::Node(node) => node, | 35 | NodeOrToken::Node(node) => node, |
36 | NodeOrToken::Token(token) => token.parent(), | 36 | NodeOrToken::Token(token) => token.parent(), |
37 | }; | 37 | }; |
diff --git a/crates/ide/src/syntax_tree.rs b/crates/ide/src/syntax_tree.rs index 1f26f8043..1d4bac7ad 100644 --- a/crates/ide/src/syntax_tree.rs +++ b/crates/ide/src/syntax_tree.rs | |||
@@ -1,7 +1,7 @@ | |||
1 | use ide_db::base_db::{FileId, SourceDatabase}; | 1 | use ide_db::base_db::{FileId, SourceDatabase}; |
2 | use ide_db::RootDatabase; | 2 | use ide_db::RootDatabase; |
3 | use syntax::{ | 3 | use syntax::{ |
4 | algo, AstNode, NodeOrToken, SourceFile, SyntaxKind::STRING, SyntaxToken, TextRange, TextSize, | 4 | AstNode, NodeOrToken, SourceFile, SyntaxKind::STRING, SyntaxToken, TextRange, TextSize, |
5 | }; | 5 | }; |
6 | 6 | ||
7 | // Feature: Show Syntax Tree | 7 | // Feature: Show Syntax Tree |
@@ -21,7 +21,7 @@ pub(crate) fn syntax_tree( | |||
21 | ) -> String { | 21 | ) -> String { |
22 | let parse = db.parse(file_id); | 22 | let parse = db.parse(file_id); |
23 | if let Some(text_range) = text_range { | 23 | if let Some(text_range) = text_range { |
24 | let node = match algo::find_covering_element(parse.tree().syntax(), text_range) { | 24 | let node = match parse.tree().syntax().covering_element(text_range) { |
25 | NodeOrToken::Node(node) => node, | 25 | NodeOrToken::Node(node) => node, |
26 | NodeOrToken::Token(token) => { | 26 | NodeOrToken::Token(token) => { |
27 | if let Some(tree) = syntax_tree_for_string(&token, text_range) { | 27 | if let Some(tree) = syntax_tree_for_string(&token, text_range) { |
diff --git a/crates/parser/src/grammar/expressions/atom.rs b/crates/parser/src/grammar/expressions/atom.rs index d61950b96..093a9890d 100644 --- a/crates/parser/src/grammar/expressions/atom.rs +++ b/crates/parser/src/grammar/expressions/atom.rs | |||
@@ -50,6 +50,7 @@ pub(super) const ATOM_EXPR_FIRST: TokenSet = | |||
50 | T![match], | 50 | T![match], |
51 | T![unsafe], | 51 | T![unsafe], |
52 | T![return], | 52 | T![return], |
53 | T![yield], | ||
53 | T![break], | 54 | T![break], |
54 | T![continue], | 55 | T![continue], |
55 | T![async], | 56 | T![async], |
@@ -142,6 +143,7 @@ pub(super) fn atom_expr(p: &mut Parser, r: Restrictions) -> Option<(CompletedMar | |||
142 | block_expr_unchecked(p) | 143 | block_expr_unchecked(p) |
143 | } | 144 | } |
144 | T![return] => return_expr(p), | 145 | T![return] => return_expr(p), |
146 | T![yield] => yield_expr(p), | ||
145 | T![continue] => continue_expr(p), | 147 | T![continue] => continue_expr(p), |
146 | T![break] => break_expr(p, r), | 148 | T![break] => break_expr(p, r), |
147 | _ => { | 149 | _ => { |
@@ -508,6 +510,20 @@ fn return_expr(p: &mut Parser) -> CompletedMarker { | |||
508 | } | 510 | } |
509 | m.complete(p, RETURN_EXPR) | 511 | m.complete(p, RETURN_EXPR) |
510 | } | 512 | } |
513 | // test yield_expr | ||
514 | // fn foo() { | ||
515 | // yield; | ||
516 | // yield 1; | ||
517 | // } | ||
518 | fn yield_expr(p: &mut Parser) -> CompletedMarker { | ||
519 | assert!(p.at(T![yield])); | ||
520 | let m = p.start(); | ||
521 | p.bump(T![yield]); | ||
522 | if p.at_ts(EXPR_FIRST) { | ||
523 | expr(p); | ||
524 | } | ||
525 | m.complete(p, YIELD_EXPR) | ||
526 | } | ||
511 | 527 | ||
512 | // test continue_expr | 528 | // test continue_expr |
513 | // fn foo() { | 529 | // fn foo() { |
diff --git a/crates/parser/src/syntax_kind/generated.rs b/crates/parser/src/syntax_kind/generated.rs index f69e71bdb..7d53cc4cd 100644 --- a/crates/parser/src/syntax_kind/generated.rs +++ b/crates/parser/src/syntax_kind/generated.rs | |||
@@ -101,6 +101,7 @@ pub enum SyntaxKind { | |||
101 | USE_KW, | 101 | USE_KW, |
102 | WHERE_KW, | 102 | WHERE_KW, |
103 | WHILE_KW, | 103 | WHILE_KW, |
104 | YIELD_KW, | ||
104 | AUTO_KW, | 105 | AUTO_KW, |
105 | DEFAULT_KW, | 106 | DEFAULT_KW, |
106 | EXISTENTIAL_KW, | 107 | EXISTENTIAL_KW, |
@@ -186,6 +187,7 @@ pub enum SyntaxKind { | |||
186 | LABEL, | 187 | LABEL, |
187 | BLOCK_EXPR, | 188 | BLOCK_EXPR, |
188 | RETURN_EXPR, | 189 | RETURN_EXPR, |
190 | YIELD_EXPR, | ||
189 | MATCH_EXPR, | 191 | MATCH_EXPR, |
190 | MATCH_ARM_LIST, | 192 | MATCH_ARM_LIST, |
191 | MATCH_ARM, | 193 | MATCH_ARM, |
@@ -263,7 +265,8 @@ impl SyntaxKind { | |||
263 | | IMPL_KW | IN_KW | LET_KW | LOOP_KW | MACRO_KW | MATCH_KW | MOD_KW | MOVE_KW | 265 | | IMPL_KW | IN_KW | LET_KW | LOOP_KW | MACRO_KW | MATCH_KW | MOD_KW | MOVE_KW |
264 | | MUT_KW | PUB_KW | REF_KW | RETURN_KW | SELF_KW | STATIC_KW | STRUCT_KW | SUPER_KW | 266 | | MUT_KW | PUB_KW | REF_KW | RETURN_KW | SELF_KW | STATIC_KW | STRUCT_KW | SUPER_KW |
265 | | TRAIT_KW | TRUE_KW | TRY_KW | TYPE_KW | UNSAFE_KW | USE_KW | WHERE_KW | WHILE_KW | 267 | | TRAIT_KW | TRUE_KW | TRY_KW | TYPE_KW | UNSAFE_KW | USE_KW | WHERE_KW | WHILE_KW |
266 | | AUTO_KW | DEFAULT_KW | EXISTENTIAL_KW | UNION_KW | RAW_KW | MACRO_RULES_KW => true, | 268 | | YIELD_KW | AUTO_KW | DEFAULT_KW | EXISTENTIAL_KW | UNION_KW | RAW_KW |
269 | | MACRO_RULES_KW => true, | ||
267 | _ => false, | 270 | _ => false, |
268 | } | 271 | } |
269 | } | 272 | } |
@@ -326,6 +329,7 @@ impl SyntaxKind { | |||
326 | "use" => USE_KW, | 329 | "use" => USE_KW, |
327 | "where" => WHERE_KW, | 330 | "where" => WHERE_KW, |
328 | "while" => WHILE_KW, | 331 | "while" => WHILE_KW, |
332 | "yield" => YIELD_KW, | ||
329 | _ => return None, | 333 | _ => return None, |
330 | }; | 334 | }; |
331 | Some(kw) | 335 | Some(kw) |
@@ -366,4 +370,4 @@ impl SyntaxKind { | |||
366 | } | 370 | } |
367 | } | 371 | } |
368 | #[macro_export] | 372 | #[macro_export] |
369 | macro_rules ! T { [;] => { $ crate :: SyntaxKind :: SEMICOLON } ; [,] => { $ crate :: SyntaxKind :: COMMA } ; ['('] => { $ crate :: SyntaxKind :: L_PAREN } ; [')'] => { $ crate :: SyntaxKind :: R_PAREN } ; ['{'] => { $ crate :: SyntaxKind :: L_CURLY } ; ['}'] => { $ crate :: SyntaxKind :: R_CURLY } ; ['['] => { $ crate :: SyntaxKind :: L_BRACK } ; [']'] => { $ crate :: SyntaxKind :: R_BRACK } ; [<] => { $ crate :: SyntaxKind :: L_ANGLE } ; [>] => { $ crate :: SyntaxKind :: R_ANGLE } ; [@] => { $ crate :: SyntaxKind :: AT } ; [#] => { $ crate :: SyntaxKind :: POUND } ; [~] => { $ crate :: SyntaxKind :: TILDE } ; [?] => { $ crate :: SyntaxKind :: QUESTION } ; [$] => { $ crate :: SyntaxKind :: DOLLAR } ; [&] => { $ crate :: SyntaxKind :: AMP } ; [|] => { $ crate :: SyntaxKind :: PIPE } ; [+] => { $ crate :: SyntaxKind :: PLUS } ; [*] => { $ crate :: SyntaxKind :: STAR } ; [/] => { $ crate :: SyntaxKind :: SLASH } ; [^] => { $ crate :: SyntaxKind :: CARET } ; [%] => { $ crate :: SyntaxKind :: PERCENT } ; [_] => { $ crate :: SyntaxKind :: UNDERSCORE } ; [.] => { $ crate :: SyntaxKind :: DOT } ; [..] => { $ crate :: SyntaxKind :: DOT2 } ; [...] => { $ crate :: SyntaxKind :: DOT3 } ; [..=] => { $ crate :: SyntaxKind :: DOT2EQ } ; [:] => { $ crate :: SyntaxKind :: COLON } ; [::] => { $ crate :: SyntaxKind :: COLON2 } ; [=] => { $ crate :: SyntaxKind :: EQ } ; [==] => { $ crate :: SyntaxKind :: EQ2 } ; [=>] => { $ crate :: SyntaxKind :: FAT_ARROW } ; [!] => { $ crate :: SyntaxKind :: BANG } ; [!=] => { $ crate :: SyntaxKind :: NEQ } ; [-] => { $ crate :: SyntaxKind :: MINUS } ; [->] => { $ crate :: SyntaxKind :: THIN_ARROW } ; [<=] => { $ crate :: SyntaxKind :: LTEQ } ; [>=] => { $ crate :: SyntaxKind :: GTEQ } ; [+=] => { $ crate :: SyntaxKind :: PLUSEQ } ; [-=] => { $ crate :: SyntaxKind :: MINUSEQ } ; [|=] => { $ crate :: SyntaxKind :: PIPEEQ } ; [&=] => { $ crate :: SyntaxKind :: AMPEQ } ; [^=] => { $ crate :: SyntaxKind :: CARETEQ } ; [/=] => { $ crate :: SyntaxKind :: SLASHEQ } ; [*=] => { $ crate :: SyntaxKind :: STAREQ } ; [%=] => { $ crate :: SyntaxKind :: PERCENTEQ } ; [&&] => { $ crate :: SyntaxKind :: AMP2 } ; [||] => { $ crate :: SyntaxKind :: PIPE2 } ; [<<] => { $ crate :: SyntaxKind :: SHL } ; [>>] => { $ crate :: SyntaxKind :: SHR } ; [<<=] => { $ crate :: SyntaxKind :: SHLEQ } ; [>>=] => { $ crate :: SyntaxKind :: SHREQ } ; [as] => { $ crate :: SyntaxKind :: AS_KW } ; [async] => { $ crate :: SyntaxKind :: ASYNC_KW } ; [await] => { $ crate :: SyntaxKind :: AWAIT_KW } ; [box] => { $ crate :: SyntaxKind :: BOX_KW } ; [break] => { $ crate :: SyntaxKind :: BREAK_KW } ; [const] => { $ crate :: SyntaxKind :: CONST_KW } ; [continue] => { $ crate :: SyntaxKind :: CONTINUE_KW } ; [crate] => { $ crate :: SyntaxKind :: CRATE_KW } ; [dyn] => { $ crate :: SyntaxKind :: DYN_KW } ; [else] => { $ crate :: SyntaxKind :: ELSE_KW } ; [enum] => { $ crate :: SyntaxKind :: ENUM_KW } ; [extern] => { $ crate :: SyntaxKind :: EXTERN_KW } ; [false] => { $ crate :: SyntaxKind :: FALSE_KW } ; [fn] => { $ crate :: SyntaxKind :: FN_KW } ; [for] => { $ crate :: SyntaxKind :: FOR_KW } ; [if] => { $ crate :: SyntaxKind :: IF_KW } ; [impl] => { $ crate :: SyntaxKind :: IMPL_KW } ; [in] => { $ crate :: SyntaxKind :: IN_KW } ; [let] => { $ crate :: SyntaxKind :: LET_KW } ; [loop] => { $ crate :: SyntaxKind :: LOOP_KW } ; [macro] => { $ crate :: SyntaxKind :: MACRO_KW } ; [match] => { $ crate :: SyntaxKind :: MATCH_KW } ; [mod] => { $ crate :: SyntaxKind :: MOD_KW } ; [move] => { $ crate :: SyntaxKind :: MOVE_KW } ; [mut] => { $ crate :: SyntaxKind :: MUT_KW } ; [pub] => { $ crate :: SyntaxKind :: PUB_KW } ; [ref] => { $ crate :: SyntaxKind :: REF_KW } ; [return] => { $ crate :: SyntaxKind :: RETURN_KW } ; [self] => { $ crate :: SyntaxKind :: SELF_KW } ; [static] => { $ crate :: SyntaxKind :: STATIC_KW } ; [struct] => { $ crate :: SyntaxKind :: STRUCT_KW } ; [super] => { $ crate :: SyntaxKind :: SUPER_KW } ; [trait] => { $ crate :: SyntaxKind :: TRAIT_KW } ; [true] => { $ crate :: SyntaxKind :: TRUE_KW } ; [try] => { $ crate :: SyntaxKind :: TRY_KW } ; [type] => { $ crate :: SyntaxKind :: TYPE_KW } ; [unsafe] => { $ crate :: SyntaxKind :: UNSAFE_KW } ; [use] => { $ crate :: SyntaxKind :: USE_KW } ; [where] => { $ crate :: SyntaxKind :: WHERE_KW } ; [while] => { $ crate :: SyntaxKind :: WHILE_KW } ; [auto] => { $ crate :: SyntaxKind :: AUTO_KW } ; [default] => { $ crate :: SyntaxKind :: DEFAULT_KW } ; [existential] => { $ crate :: SyntaxKind :: EXISTENTIAL_KW } ; [union] => { $ crate :: SyntaxKind :: UNION_KW } ; [raw] => { $ crate :: SyntaxKind :: RAW_KW } ; [macro_rules] => { $ crate :: SyntaxKind :: MACRO_RULES_KW } ; [lifetime_ident] => { $ crate :: SyntaxKind :: LIFETIME_IDENT } ; [ident] => { $ crate :: SyntaxKind :: IDENT } ; [shebang] => { $ crate :: SyntaxKind :: SHEBANG } ; } | 373 | macro_rules ! T { [;] => { $ crate :: SyntaxKind :: SEMICOLON } ; [,] => { $ crate :: SyntaxKind :: COMMA } ; ['('] => { $ crate :: SyntaxKind :: L_PAREN } ; [')'] => { $ crate :: SyntaxKind :: R_PAREN } ; ['{'] => { $ crate :: SyntaxKind :: L_CURLY } ; ['}'] => { $ crate :: SyntaxKind :: R_CURLY } ; ['['] => { $ crate :: SyntaxKind :: L_BRACK } ; [']'] => { $ crate :: SyntaxKind :: R_BRACK } ; [<] => { $ crate :: SyntaxKind :: L_ANGLE } ; [>] => { $ crate :: SyntaxKind :: R_ANGLE } ; [@] => { $ crate :: SyntaxKind :: AT } ; [#] => { $ crate :: SyntaxKind :: POUND } ; [~] => { $ crate :: SyntaxKind :: TILDE } ; [?] => { $ crate :: SyntaxKind :: QUESTION } ; [$] => { $ crate :: SyntaxKind :: DOLLAR } ; [&] => { $ crate :: SyntaxKind :: AMP } ; [|] => { $ crate :: SyntaxKind :: PIPE } ; [+] => { $ crate :: SyntaxKind :: PLUS } ; [*] => { $ crate :: SyntaxKind :: STAR } ; [/] => { $ crate :: SyntaxKind :: SLASH } ; [^] => { $ crate :: SyntaxKind :: CARET } ; [%] => { $ crate :: SyntaxKind :: PERCENT } ; [_] => { $ crate :: SyntaxKind :: UNDERSCORE } ; [.] => { $ crate :: SyntaxKind :: DOT } ; [..] => { $ crate :: SyntaxKind :: DOT2 } ; [...] => { $ crate :: SyntaxKind :: DOT3 } ; [..=] => { $ crate :: SyntaxKind :: DOT2EQ } ; [:] => { $ crate :: SyntaxKind :: COLON } ; [::] => { $ crate :: SyntaxKind :: COLON2 } ; [=] => { $ crate :: SyntaxKind :: EQ } ; [==] => { $ crate :: SyntaxKind :: EQ2 } ; [=>] => { $ crate :: SyntaxKind :: FAT_ARROW } ; [!] => { $ crate :: SyntaxKind :: BANG } ; [!=] => { $ crate :: SyntaxKind :: NEQ } ; [-] => { $ crate :: SyntaxKind :: MINUS } ; [->] => { $ crate :: SyntaxKind :: THIN_ARROW } ; [<=] => { $ crate :: SyntaxKind :: LTEQ } ; [>=] => { $ crate :: SyntaxKind :: GTEQ } ; [+=] => { $ crate :: SyntaxKind :: PLUSEQ } ; [-=] => { $ crate :: SyntaxKind :: MINUSEQ } ; [|=] => { $ crate :: SyntaxKind :: PIPEEQ } ; [&=] => { $ crate :: SyntaxKind :: AMPEQ } ; [^=] => { $ crate :: SyntaxKind :: CARETEQ } ; [/=] => { $ crate :: SyntaxKind :: SLASHEQ } ; [*=] => { $ crate :: SyntaxKind :: STAREQ } ; [%=] => { $ crate :: SyntaxKind :: PERCENTEQ } ; [&&] => { $ crate :: SyntaxKind :: AMP2 } ; [||] => { $ crate :: SyntaxKind :: PIPE2 } ; [<<] => { $ crate :: SyntaxKind :: SHL } ; [>>] => { $ crate :: SyntaxKind :: SHR } ; [<<=] => { $ crate :: SyntaxKind :: SHLEQ } ; [>>=] => { $ crate :: SyntaxKind :: SHREQ } ; [as] => { $ crate :: SyntaxKind :: AS_KW } ; [async] => { $ crate :: SyntaxKind :: ASYNC_KW } ; [await] => { $ crate :: SyntaxKind :: AWAIT_KW } ; [box] => { $ crate :: SyntaxKind :: BOX_KW } ; [break] => { $ crate :: SyntaxKind :: BREAK_KW } ; [const] => { $ crate :: SyntaxKind :: CONST_KW } ; [continue] => { $ crate :: SyntaxKind :: CONTINUE_KW } ; [crate] => { $ crate :: SyntaxKind :: CRATE_KW } ; [dyn] => { $ crate :: SyntaxKind :: DYN_KW } ; [else] => { $ crate :: SyntaxKind :: ELSE_KW } ; [enum] => { $ crate :: SyntaxKind :: ENUM_KW } ; [extern] => { $ crate :: SyntaxKind :: EXTERN_KW } ; [false] => { $ crate :: SyntaxKind :: FALSE_KW } ; [fn] => { $ crate :: SyntaxKind :: FN_KW } ; [for] => { $ crate :: SyntaxKind :: FOR_KW } ; [if] => { $ crate :: SyntaxKind :: IF_KW } ; [impl] => { $ crate :: SyntaxKind :: IMPL_KW } ; [in] => { $ crate :: SyntaxKind :: IN_KW } ; [let] => { $ crate :: SyntaxKind :: LET_KW } ; [loop] => { $ crate :: SyntaxKind :: LOOP_KW } ; [macro] => { $ crate :: SyntaxKind :: MACRO_KW } ; [match] => { $ crate :: SyntaxKind :: MATCH_KW } ; [mod] => { $ crate :: SyntaxKind :: MOD_KW } ; [move] => { $ crate :: SyntaxKind :: MOVE_KW } ; [mut] => { $ crate :: SyntaxKind :: MUT_KW } ; [pub] => { $ crate :: SyntaxKind :: PUB_KW } ; [ref] => { $ crate :: SyntaxKind :: REF_KW } ; [return] => { $ crate :: SyntaxKind :: RETURN_KW } ; [self] => { $ crate :: SyntaxKind :: SELF_KW } ; [static] => { $ crate :: SyntaxKind :: STATIC_KW } ; [struct] => { $ crate :: SyntaxKind :: STRUCT_KW } ; [super] => { $ crate :: SyntaxKind :: SUPER_KW } ; [trait] => { $ crate :: SyntaxKind :: TRAIT_KW } ; [true] => { $ crate :: SyntaxKind :: TRUE_KW } ; [try] => { $ crate :: SyntaxKind :: TRY_KW } ; [type] => { $ crate :: SyntaxKind :: TYPE_KW } ; [unsafe] => { $ crate :: SyntaxKind :: UNSAFE_KW } ; [use] => { $ crate :: SyntaxKind :: USE_KW } ; [where] => { $ crate :: SyntaxKind :: WHERE_KW } ; [while] => { $ crate :: SyntaxKind :: WHILE_KW } ; [yield] => { $ crate :: SyntaxKind :: YIELD_KW } ; [auto] => { $ crate :: SyntaxKind :: AUTO_KW } ; [default] => { $ crate :: SyntaxKind :: DEFAULT_KW } ; [existential] => { $ crate :: SyntaxKind :: EXISTENTIAL_KW } ; [union] => { $ crate :: SyntaxKind :: UNION_KW } ; [raw] => { $ crate :: SyntaxKind :: RAW_KW } ; [macro_rules] => { $ crate :: SyntaxKind :: MACRO_RULES_KW } ; [lifetime_ident] => { $ crate :: SyntaxKind :: LIFETIME_IDENT } ; [ident] => { $ crate :: SyntaxKind :: IDENT } ; [shebang] => { $ crate :: SyntaxKind :: SHEBANG } ; } |
diff --git a/crates/rust-analyzer/src/diagnostics/test_data/rustc_unused_variable.txt b/crates/rust-analyzer/src/diagnostics/test_data/rustc_unused_variable.txt index 23d42b4d0..5c282fe67 100644 --- a/crates/rust-analyzer/src/diagnostics/test_data/rustc_unused_variable.txt +++ b/crates/rust-analyzer/src/diagnostics/test_data/rustc_unused_variable.txt | |||
@@ -66,52 +66,7 @@ | |||
66 | ), | 66 | ), |
67 | data: None, | 67 | data: None, |
68 | }, | 68 | }, |
69 | fixes: [ | 69 | fixes: [], |
70 | CodeAction { | ||
71 | title: "consider prefixing with an underscore", | ||
72 | group: None, | ||
73 | kind: Some( | ||
74 | CodeActionKind( | ||
75 | "quickfix", | ||
76 | ), | ||
77 | ), | ||
78 | edit: Some( | ||
79 | SnippetWorkspaceEdit { | ||
80 | changes: Some( | ||
81 | { | ||
82 | Url { | ||
83 | scheme: "file", | ||
84 | host: None, | ||
85 | port: None, | ||
86 | path: "/test/driver/subcommand/repl.rs", | ||
87 | query: None, | ||
88 | fragment: None, | ||
89 | }: [ | ||
90 | TextEdit { | ||
91 | range: Range { | ||
92 | start: Position { | ||
93 | line: 290, | ||
94 | character: 8, | ||
95 | }, | ||
96 | end: Position { | ||
97 | line: 290, | ||
98 | character: 11, | ||
99 | }, | ||
100 | }, | ||
101 | new_text: "_foo", | ||
102 | }, | ||
103 | ], | ||
104 | }, | ||
105 | ), | ||
106 | document_changes: None, | ||
107 | }, | ||
108 | ), | ||
109 | is_preferred: Some( | ||
110 | true, | ||
111 | ), | ||
112 | data: None, | ||
113 | }, | ||
114 | ], | ||
115 | }, | 70 | }, |
116 | MappedRustDiagnostic { | 71 | MappedRustDiagnostic { |
117 | url: Url { | 72 | url: Url { |
diff --git a/crates/rust-analyzer/src/diagnostics/test_data/rustc_unused_variable_as_hint.txt b/crates/rust-analyzer/src/diagnostics/test_data/rustc_unused_variable_as_hint.txt index 4e428bedc..d36d7693d 100644 --- a/crates/rust-analyzer/src/diagnostics/test_data/rustc_unused_variable_as_hint.txt +++ b/crates/rust-analyzer/src/diagnostics/test_data/rustc_unused_variable_as_hint.txt | |||
@@ -66,52 +66,7 @@ | |||
66 | ), | 66 | ), |
67 | data: None, | 67 | data: None, |
68 | }, | 68 | }, |
69 | fixes: [ | 69 | fixes: [], |
70 | CodeAction { | ||
71 | title: "consider prefixing with an underscore", | ||
72 | group: None, | ||
73 | kind: Some( | ||
74 | CodeActionKind( | ||
75 | "quickfix", | ||
76 | ), | ||
77 | ), | ||
78 | edit: Some( | ||
79 | SnippetWorkspaceEdit { | ||
80 | changes: Some( | ||
81 | { | ||
82 | Url { | ||
83 | scheme: "file", | ||
84 | host: None, | ||
85 | port: None, | ||
86 | path: "/test/driver/subcommand/repl.rs", | ||
87 | query: None, | ||
88 | fragment: None, | ||
89 | }: [ | ||
90 | TextEdit { | ||
91 | range: Range { | ||
92 | start: Position { | ||
93 | line: 290, | ||
94 | character: 8, | ||
95 | }, | ||
96 | end: Position { | ||
97 | line: 290, | ||
98 | character: 11, | ||
99 | }, | ||
100 | }, | ||
101 | new_text: "_foo", | ||
102 | }, | ||
103 | ], | ||
104 | }, | ||
105 | ), | ||
106 | document_changes: None, | ||
107 | }, | ||
108 | ), | ||
109 | is_preferred: Some( | ||
110 | true, | ||
111 | ), | ||
112 | data: None, | ||
113 | }, | ||
114 | ], | ||
115 | }, | 70 | }, |
116 | MappedRustDiagnostic { | 71 | MappedRustDiagnostic { |
117 | url: Url { | 72 | url: Url { |
diff --git a/crates/rust-analyzer/src/diagnostics/test_data/rustc_unused_variable_as_info.txt b/crates/rust-analyzer/src/diagnostics/test_data/rustc_unused_variable_as_info.txt index 4ddd7efae..17845b711 100644 --- a/crates/rust-analyzer/src/diagnostics/test_data/rustc_unused_variable_as_info.txt +++ b/crates/rust-analyzer/src/diagnostics/test_data/rustc_unused_variable_as_info.txt | |||
@@ -66,52 +66,7 @@ | |||
66 | ), | 66 | ), |
67 | data: None, | 67 | data: None, |
68 | }, | 68 | }, |
69 | fixes: [ | 69 | fixes: [], |
70 | CodeAction { | ||
71 | title: "consider prefixing with an underscore", | ||
72 | group: None, | ||
73 | kind: Some( | ||
74 | CodeActionKind( | ||
75 | "quickfix", | ||
76 | ), | ||
77 | ), | ||
78 | edit: Some( | ||
79 | SnippetWorkspaceEdit { | ||
80 | changes: Some( | ||
81 | { | ||
82 | Url { | ||
83 | scheme: "file", | ||
84 | host: None, | ||
85 | port: None, | ||
86 | path: "/test/driver/subcommand/repl.rs", | ||
87 | query: None, | ||
88 | fragment: None, | ||
89 | }: [ | ||
90 | TextEdit { | ||
91 | range: Range { | ||
92 | start: Position { | ||
93 | line: 290, | ||
94 | character: 8, | ||
95 | }, | ||
96 | end: Position { | ||
97 | line: 290, | ||
98 | character: 11, | ||
99 | }, | ||
100 | }, | ||
101 | new_text: "_foo", | ||
102 | }, | ||
103 | ], | ||
104 | }, | ||
105 | ), | ||
106 | document_changes: None, | ||
107 | }, | ||
108 | ), | ||
109 | is_preferred: Some( | ||
110 | true, | ||
111 | ), | ||
112 | data: None, | ||
113 | }, | ||
114 | ], | ||
115 | }, | 70 | }, |
116 | MappedRustDiagnostic { | 71 | MappedRustDiagnostic { |
117 | url: Url { | 72 | url: Url { |
diff --git a/crates/rust-analyzer/src/diagnostics/test_data/snap_multi_line_fix.txt b/crates/rust-analyzer/src/diagnostics/test_data/snap_multi_line_fix.txt index 4cbdb3b92..a19962167 100644 --- a/crates/rust-analyzer/src/diagnostics/test_data/snap_multi_line_fix.txt +++ b/crates/rust-analyzer/src/diagnostics/test_data/snap_multi_line_fix.txt | |||
@@ -102,65 +102,7 @@ | |||
102 | tags: None, | 102 | tags: None, |
103 | data: None, | 103 | data: None, |
104 | }, | 104 | }, |
105 | fixes: [ | 105 | fixes: [], |
106 | CodeAction { | ||
107 | title: "return the expression directly", | ||
108 | group: None, | ||
109 | kind: Some( | ||
110 | CodeActionKind( | ||
111 | "quickfix", | ||
112 | ), | ||
113 | ), | ||
114 | edit: Some( | ||
115 | SnippetWorkspaceEdit { | ||
116 | changes: Some( | ||
117 | { | ||
118 | Url { | ||
119 | scheme: "file", | ||
120 | host: None, | ||
121 | port: None, | ||
122 | path: "/test/src/main.rs", | ||
123 | query: None, | ||
124 | fragment: None, | ||
125 | }: [ | ||
126 | TextEdit { | ||
127 | range: Range { | ||
128 | start: Position { | ||
129 | line: 2, | ||
130 | character: 4, | ||
131 | }, | ||
132 | end: Position { | ||
133 | line: 2, | ||
134 | character: 30, | ||
135 | }, | ||
136 | }, | ||
137 | new_text: "", | ||
138 | }, | ||
139 | TextEdit { | ||
140 | range: Range { | ||
141 | start: Position { | ||
142 | line: 3, | ||
143 | character: 4, | ||
144 | }, | ||
145 | end: Position { | ||
146 | line: 3, | ||
147 | character: 5, | ||
148 | }, | ||
149 | }, | ||
150 | new_text: "(0..10).collect()", | ||
151 | }, | ||
152 | ], | ||
153 | }, | ||
154 | ), | ||
155 | document_changes: None, | ||
156 | }, | ||
157 | ), | ||
158 | is_preferred: Some( | ||
159 | true, | ||
160 | ), | ||
161 | data: None, | ||
162 | }, | ||
163 | ], | ||
164 | }, | 106 | }, |
165 | MappedRustDiagnostic { | 107 | MappedRustDiagnostic { |
166 | url: Url { | 108 | url: Url { |
@@ -242,65 +184,7 @@ | |||
242 | tags: None, | 184 | tags: None, |
243 | data: None, | 185 | data: None, |
244 | }, | 186 | }, |
245 | fixes: [ | 187 | fixes: [], |
246 | CodeAction { | ||
247 | title: "return the expression directly", | ||
248 | group: None, | ||
249 | kind: Some( | ||
250 | CodeActionKind( | ||
251 | "quickfix", | ||
252 | ), | ||
253 | ), | ||
254 | edit: Some( | ||
255 | SnippetWorkspaceEdit { | ||
256 | changes: Some( | ||
257 | { | ||
258 | Url { | ||
259 | scheme: "file", | ||
260 | host: None, | ||
261 | port: None, | ||
262 | path: "/test/src/main.rs", | ||
263 | query: None, | ||
264 | fragment: None, | ||
265 | }: [ | ||
266 | TextEdit { | ||
267 | range: Range { | ||
268 | start: Position { | ||
269 | line: 2, | ||
270 | character: 4, | ||
271 | }, | ||
272 | end: Position { | ||
273 | line: 2, | ||
274 | character: 30, | ||
275 | }, | ||
276 | }, | ||
277 | new_text: "", | ||
278 | }, | ||
279 | TextEdit { | ||
280 | range: Range { | ||
281 | start: Position { | ||
282 | line: 3, | ||
283 | character: 4, | ||
284 | }, | ||
285 | end: Position { | ||
286 | line: 3, | ||
287 | character: 5, | ||
288 | }, | ||
289 | }, | ||
290 | new_text: "(0..10).collect()", | ||
291 | }, | ||
292 | ], | ||
293 | }, | ||
294 | ), | ||
295 | document_changes: None, | ||
296 | }, | ||
297 | ), | ||
298 | is_preferred: Some( | ||
299 | true, | ||
300 | ), | ||
301 | data: None, | ||
302 | }, | ||
303 | ], | ||
304 | }, | 188 | }, |
305 | MappedRustDiagnostic { | 189 | MappedRustDiagnostic { |
306 | url: Url { | 190 | url: Url { |
diff --git a/crates/rust-analyzer/src/diagnostics/to_proto.rs b/crates/rust-analyzer/src/diagnostics/to_proto.rs index 540759198..757899484 100644 --- a/crates/rust-analyzer/src/diagnostics/to_proto.rs +++ b/crates/rust-analyzer/src/diagnostics/to_proto.rs | |||
@@ -74,11 +74,13 @@ fn diagnostic_related_information( | |||
74 | Some(lsp_types::DiagnosticRelatedInformation { location, message }) | 74 | Some(lsp_types::DiagnosticRelatedInformation { location, message }) |
75 | } | 75 | } |
76 | 76 | ||
77 | struct SubDiagnostic { | ||
78 | related: lsp_types::DiagnosticRelatedInformation, | ||
79 | suggested_fix: Option<lsp_ext::CodeAction>, | ||
80 | } | ||
81 | |||
77 | enum MappedRustChildDiagnostic { | 82 | enum MappedRustChildDiagnostic { |
78 | Related { | 83 | SubDiagnostic(SubDiagnostic), |
79 | related: lsp_types::DiagnosticRelatedInformation, | ||
80 | suggested_fix: Option<lsp_ext::CodeAction>, | ||
81 | }, | ||
82 | MessageLine(String), | 84 | MessageLine(String), |
83 | } | 85 | } |
84 | 86 | ||
@@ -105,15 +107,15 @@ fn map_rust_child_diagnostic( | |||
105 | } | 107 | } |
106 | 108 | ||
107 | if edit_map.is_empty() { | 109 | if edit_map.is_empty() { |
108 | MappedRustChildDiagnostic::Related { | 110 | MappedRustChildDiagnostic::SubDiagnostic(SubDiagnostic { |
109 | related: lsp_types::DiagnosticRelatedInformation { | 111 | related: lsp_types::DiagnosticRelatedInformation { |
110 | location: location(workspace_root, spans[0]), | 112 | location: location(workspace_root, spans[0]), |
111 | message: rd.message.clone(), | 113 | message: rd.message.clone(), |
112 | }, | 114 | }, |
113 | suggested_fix: None, | 115 | suggested_fix: None, |
114 | } | 116 | }) |
115 | } else { | 117 | } else { |
116 | MappedRustChildDiagnostic::Related { | 118 | MappedRustChildDiagnostic::SubDiagnostic(SubDiagnostic { |
117 | related: lsp_types::DiagnosticRelatedInformation { | 119 | related: lsp_types::DiagnosticRelatedInformation { |
118 | location: location(workspace_root, spans[0]), | 120 | location: location(workspace_root, spans[0]), |
119 | message: rd.message.clone(), | 121 | message: rd.message.clone(), |
@@ -130,7 +132,7 @@ fn map_rust_child_diagnostic( | |||
130 | is_preferred: Some(true), | 132 | is_preferred: Some(true), |
131 | data: None, | 133 | data: None, |
132 | }), | 134 | }), |
133 | } | 135 | }) |
134 | } | 136 | } |
135 | } | 137 | } |
136 | 138 | ||
@@ -175,26 +177,22 @@ pub(crate) fn map_rust_diagnostic_to_lsp( | |||
175 | } | 177 | } |
176 | 178 | ||
177 | let mut needs_primary_span_label = true; | 179 | let mut needs_primary_span_label = true; |
178 | let mut related_information = Vec::new(); | 180 | let mut subdiagnostics = Vec::new(); |
179 | let mut tags = Vec::new(); | 181 | let mut tags = Vec::new(); |
180 | 182 | ||
181 | for secondary_span in rd.spans.iter().filter(|s| !s.is_primary) { | 183 | for secondary_span in rd.spans.iter().filter(|s| !s.is_primary) { |
182 | let related = diagnostic_related_information(workspace_root, secondary_span); | 184 | let related = diagnostic_related_information(workspace_root, secondary_span); |
183 | if let Some(related) = related { | 185 | if let Some(related) = related { |
184 | related_information.push(related); | 186 | subdiagnostics.push(SubDiagnostic { related, suggested_fix: None }); |
185 | } | 187 | } |
186 | } | 188 | } |
187 | 189 | ||
188 | let mut fixes = Vec::new(); | ||
189 | let mut message = rd.message.clone(); | 190 | let mut message = rd.message.clone(); |
190 | for child in &rd.children { | 191 | for child in &rd.children { |
191 | let child = map_rust_child_diagnostic(workspace_root, &child); | 192 | let child = map_rust_child_diagnostic(workspace_root, &child); |
192 | match child { | 193 | match child { |
193 | MappedRustChildDiagnostic::Related { related, suggested_fix } => { | 194 | MappedRustChildDiagnostic::SubDiagnostic(sub) => { |
194 | related_information.push(related); | 195 | subdiagnostics.push(sub); |
195 | if let Some(code_action) = suggested_fix { | ||
196 | fixes.push(code_action); | ||
197 | } | ||
198 | } | 196 | } |
199 | MappedRustChildDiagnostic::MessageLine(message_line) => { | 197 | MappedRustChildDiagnostic::MessageLine(message_line) => { |
200 | format_to!(message, "\n{}", message_line); | 198 | format_to!(message, "\n{}", message_line); |
@@ -284,7 +282,7 @@ pub(crate) fn map_rust_diagnostic_to_lsp( | |||
284 | diagnostics.push(MappedRustDiagnostic { | 282 | diagnostics.push(MappedRustDiagnostic { |
285 | url: in_macro_location.uri, | 283 | url: in_macro_location.uri, |
286 | diagnostic, | 284 | diagnostic, |
287 | fixes: fixes.clone(), | 285 | fixes: Vec::new(), |
288 | }); | 286 | }); |
289 | } | 287 | } |
290 | 288 | ||
@@ -298,17 +296,20 @@ pub(crate) fn map_rust_diagnostic_to_lsp( | |||
298 | code_description: code_description.clone(), | 296 | code_description: code_description.clone(), |
299 | source: Some(source.clone()), | 297 | source: Some(source.clone()), |
300 | message, | 298 | message, |
301 | related_information: if related_information.is_empty() { | 299 | related_information: if subdiagnostics.is_empty() { |
302 | None | 300 | None |
303 | } else { | 301 | } else { |
304 | let mut related = related_information.clone(); | 302 | let mut related = subdiagnostics |
303 | .iter() | ||
304 | .map(|sub| sub.related.clone()) | ||
305 | .collect::<Vec<_>>(); | ||
305 | related.extend(related_macro_info); | 306 | related.extend(related_macro_info); |
306 | Some(related) | 307 | Some(related) |
307 | }, | 308 | }, |
308 | tags: if tags.is_empty() { None } else { Some(tags.clone()) }, | 309 | tags: if tags.is_empty() { None } else { Some(tags.clone()) }, |
309 | data: None, | 310 | data: None, |
310 | }, | 311 | }, |
311 | fixes: fixes.clone(), | 312 | fixes: Vec::new(), |
312 | }); | 313 | }); |
313 | 314 | ||
314 | // Emit hint-level diagnostics for all `related_information` entries such as "help"s. | 315 | // Emit hint-level diagnostics for all `related_information` entries such as "help"s. |
@@ -318,21 +319,21 @@ pub(crate) fn map_rust_diagnostic_to_lsp( | |||
318 | location, | 319 | location, |
319 | message: "original diagnostic".to_string(), | 320 | message: "original diagnostic".to_string(), |
320 | }; | 321 | }; |
321 | for info in &related_information { | 322 | for sub in &subdiagnostics { |
322 | // Filter out empty/non-existent messages, as they greatly confuse VS Code. | 323 | // Filter out empty/non-existent messages, as they greatly confuse VS Code. |
323 | if info.message.is_empty() { | 324 | if sub.related.message.is_empty() { |
324 | continue; | 325 | continue; |
325 | } | 326 | } |
326 | diagnostics.push(MappedRustDiagnostic { | 327 | diagnostics.push(MappedRustDiagnostic { |
327 | url: info.location.uri.clone(), | 328 | url: sub.related.location.uri.clone(), |
328 | fixes: fixes.clone(), // share fixes to make them easier to apply | 329 | fixes: sub.suggested_fix.iter().cloned().collect(), |
329 | diagnostic: lsp_types::Diagnostic { | 330 | diagnostic: lsp_types::Diagnostic { |
330 | range: info.location.range, | 331 | range: sub.related.location.range, |
331 | severity: Some(lsp_types::DiagnosticSeverity::Hint), | 332 | severity: Some(lsp_types::DiagnosticSeverity::Hint), |
332 | code: code.clone().map(lsp_types::NumberOrString::String), | 333 | code: code.clone().map(lsp_types::NumberOrString::String), |
333 | code_description: code_description.clone(), | 334 | code_description: code_description.clone(), |
334 | source: Some(source.clone()), | 335 | source: Some(source.clone()), |
335 | message: info.message.clone(), | 336 | message: sub.related.message.clone(), |
336 | related_information: Some(vec![back_ref.clone()]), | 337 | related_information: Some(vec![back_ref.clone()]), |
337 | tags: None, // don't apply modifiers again | 338 | tags: None, // don't apply modifiers again |
338 | data: None, | 339 | data: None, |
diff --git a/crates/syntax/src/algo.rs b/crates/syntax/src/algo.rs index 384d031e7..1456270d0 100644 --- a/crates/syntax/src/algo.rs +++ b/crates/syntax/src/algo.rs | |||
@@ -45,7 +45,7 @@ pub fn find_node_at_offset<N: AstNode>(syntax: &SyntaxNode, offset: TextSize) -> | |||
45 | } | 45 | } |
46 | 46 | ||
47 | pub fn find_node_at_range<N: AstNode>(syntax: &SyntaxNode, range: TextRange) -> Option<N> { | 47 | pub fn find_node_at_range<N: AstNode>(syntax: &SyntaxNode, range: TextRange) -> Option<N> { |
48 | find_covering_element(syntax, range).ancestors().find_map(N::cast) | 48 | syntax.covering_element(range).ancestors().find_map(N::cast) |
49 | } | 49 | } |
50 | 50 | ||
51 | /// Skip to next non `trivia` token | 51 | /// Skip to next non `trivia` token |
@@ -74,10 +74,6 @@ pub fn non_trivia_sibling(element: SyntaxElement, direction: Direction) -> Optio | |||
74 | } | 74 | } |
75 | } | 75 | } |
76 | 76 | ||
77 | pub fn find_covering_element(root: &SyntaxNode, range: TextRange) -> SyntaxElement { | ||
78 | root.covering_element(range) | ||
79 | } | ||
80 | |||
81 | pub fn least_common_ancestor(u: &SyntaxNode, v: &SyntaxNode) -> Option<SyntaxNode> { | 77 | pub fn least_common_ancestor(u: &SyntaxNode, v: &SyntaxNode) -> Option<SyntaxNode> { |
82 | if u == v { | 78 | if u == v { |
83 | return Some(u.clone()); | 79 | return Some(u.clone()); |
diff --git a/crates/syntax/src/ast/generated/nodes.rs b/crates/syntax/src/ast/generated/nodes.rs index 92ed2ee9d..9c96d3d07 100644 --- a/crates/syntax/src/ast/generated/nodes.rs +++ b/crates/syntax/src/ast/generated/nodes.rs | |||
@@ -931,6 +931,15 @@ impl WhileExpr { | |||
931 | pub fn condition(&self) -> Option<Condition> { support::child(&self.syntax) } | 931 | pub fn condition(&self) -> Option<Condition> { support::child(&self.syntax) } |
932 | } | 932 | } |
933 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | 933 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] |
934 | pub struct YieldExpr { | ||
935 | pub(crate) syntax: SyntaxNode, | ||
936 | } | ||
937 | impl ast::AttrsOwner for YieldExpr {} | ||
938 | impl YieldExpr { | ||
939 | pub fn yield_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![yield]) } | ||
940 | pub fn expr(&self) -> Option<Expr> { support::child(&self.syntax) } | ||
941 | } | ||
942 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | ||
934 | pub struct Label { | 943 | pub struct Label { |
935 | pub(crate) syntax: SyntaxNode, | 944 | pub(crate) syntax: SyntaxNode, |
936 | } | 945 | } |
@@ -1334,6 +1343,7 @@ pub enum Expr { | |||
1334 | TryExpr(TryExpr), | 1343 | TryExpr(TryExpr), |
1335 | TupleExpr(TupleExpr), | 1344 | TupleExpr(TupleExpr), |
1336 | WhileExpr(WhileExpr), | 1345 | WhileExpr(WhileExpr), |
1346 | YieldExpr(YieldExpr), | ||
1337 | } | 1347 | } |
1338 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | 1348 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] |
1339 | pub enum Item { | 1349 | pub enum Item { |
@@ -2386,6 +2396,17 @@ impl AstNode for WhileExpr { | |||
2386 | } | 2396 | } |
2387 | fn syntax(&self) -> &SyntaxNode { &self.syntax } | 2397 | fn syntax(&self) -> &SyntaxNode { &self.syntax } |
2388 | } | 2398 | } |
2399 | impl AstNode for YieldExpr { | ||
2400 | fn can_cast(kind: SyntaxKind) -> bool { kind == YIELD_EXPR } | ||
2401 | fn cast(syntax: SyntaxNode) -> Option<Self> { | ||
2402 | if Self::can_cast(syntax.kind()) { | ||
2403 | Some(Self { syntax }) | ||
2404 | } else { | ||
2405 | None | ||
2406 | } | ||
2407 | } | ||
2408 | fn syntax(&self) -> &SyntaxNode { &self.syntax } | ||
2409 | } | ||
2389 | impl AstNode for Label { | 2410 | impl AstNode for Label { |
2390 | fn can_cast(kind: SyntaxKind) -> bool { kind == LABEL } | 2411 | fn can_cast(kind: SyntaxKind) -> bool { kind == LABEL } |
2391 | fn cast(syntax: SyntaxNode) -> Option<Self> { | 2412 | fn cast(syntax: SyntaxNode) -> Option<Self> { |
@@ -3028,6 +3049,9 @@ impl From<TupleExpr> for Expr { | |||
3028 | impl From<WhileExpr> for Expr { | 3049 | impl From<WhileExpr> for Expr { |
3029 | fn from(node: WhileExpr) -> Expr { Expr::WhileExpr(node) } | 3050 | fn from(node: WhileExpr) -> Expr { Expr::WhileExpr(node) } |
3030 | } | 3051 | } |
3052 | impl From<YieldExpr> for Expr { | ||
3053 | fn from(node: YieldExpr) -> Expr { Expr::YieldExpr(node) } | ||
3054 | } | ||
3031 | impl AstNode for Expr { | 3055 | impl AstNode for Expr { |
3032 | fn can_cast(kind: SyntaxKind) -> bool { | 3056 | fn can_cast(kind: SyntaxKind) -> bool { |
3033 | match kind { | 3057 | match kind { |
@@ -3035,7 +3059,8 @@ impl AstNode for Expr { | |||
3035 | | CAST_EXPR | CLOSURE_EXPR | CONTINUE_EXPR | EFFECT_EXPR | FIELD_EXPR | FOR_EXPR | 3059 | | CAST_EXPR | CLOSURE_EXPR | CONTINUE_EXPR | EFFECT_EXPR | FIELD_EXPR | FOR_EXPR |
3036 | | IF_EXPR | INDEX_EXPR | LITERAL | LOOP_EXPR | MACRO_CALL | MATCH_EXPR | 3060 | | IF_EXPR | INDEX_EXPR | LITERAL | LOOP_EXPR | MACRO_CALL | MATCH_EXPR |
3037 | | METHOD_CALL_EXPR | PAREN_EXPR | PATH_EXPR | PREFIX_EXPR | RANGE_EXPR | 3061 | | METHOD_CALL_EXPR | PAREN_EXPR | PATH_EXPR | PREFIX_EXPR | RANGE_EXPR |
3038 | | RECORD_EXPR | REF_EXPR | RETURN_EXPR | TRY_EXPR | TUPLE_EXPR | WHILE_EXPR => true, | 3062 | | RECORD_EXPR | REF_EXPR | RETURN_EXPR | TRY_EXPR | TUPLE_EXPR | WHILE_EXPR |
3063 | | YIELD_EXPR => true, | ||
3039 | _ => false, | 3064 | _ => false, |
3040 | } | 3065 | } |
3041 | } | 3066 | } |
@@ -3071,6 +3096,7 @@ impl AstNode for Expr { | |||
3071 | TRY_EXPR => Expr::TryExpr(TryExpr { syntax }), | 3096 | TRY_EXPR => Expr::TryExpr(TryExpr { syntax }), |
3072 | TUPLE_EXPR => Expr::TupleExpr(TupleExpr { syntax }), | 3097 | TUPLE_EXPR => Expr::TupleExpr(TupleExpr { syntax }), |
3073 | WHILE_EXPR => Expr::WhileExpr(WhileExpr { syntax }), | 3098 | WHILE_EXPR => Expr::WhileExpr(WhileExpr { syntax }), |
3099 | YIELD_EXPR => Expr::YieldExpr(YieldExpr { syntax }), | ||
3074 | _ => return None, | 3100 | _ => return None, |
3075 | }; | 3101 | }; |
3076 | Some(res) | 3102 | Some(res) |
@@ -3107,6 +3133,7 @@ impl AstNode for Expr { | |||
3107 | Expr::TryExpr(it) => &it.syntax, | 3133 | Expr::TryExpr(it) => &it.syntax, |
3108 | Expr::TupleExpr(it) => &it.syntax, | 3134 | Expr::TupleExpr(it) => &it.syntax, |
3109 | Expr::WhileExpr(it) => &it.syntax, | 3135 | Expr::WhileExpr(it) => &it.syntax, |
3136 | Expr::YieldExpr(it) => &it.syntax, | ||
3110 | } | 3137 | } |
3111 | } | 3138 | } |
3112 | } | 3139 | } |
@@ -3983,6 +4010,11 @@ impl std::fmt::Display for WhileExpr { | |||
3983 | std::fmt::Display::fmt(self.syntax(), f) | 4010 | std::fmt::Display::fmt(self.syntax(), f) |
3984 | } | 4011 | } |
3985 | } | 4012 | } |
4013 | impl std::fmt::Display for YieldExpr { | ||
4014 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | ||
4015 | std::fmt::Display::fmt(self.syntax(), f) | ||
4016 | } | ||
4017 | } | ||
3986 | impl std::fmt::Display for Label { | 4018 | impl std::fmt::Display for Label { |
3987 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { | 4019 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { |
3988 | std::fmt::Display::fmt(self.syntax(), f) | 4020 | std::fmt::Display::fmt(self.syntax(), f) |
diff --git a/crates/syntax/src/parsing/reparsing.rs b/crates/syntax/src/parsing/reparsing.rs index 78eaf3410..76f01084c 100644 --- a/crates/syntax/src/parsing/reparsing.rs +++ b/crates/syntax/src/parsing/reparsing.rs | |||
@@ -10,7 +10,6 @@ use parser::Reparser; | |||
10 | use text_edit::Indel; | 10 | use text_edit::Indel; |
11 | 11 | ||
12 | use crate::{ | 12 | use crate::{ |
13 | algo, | ||
14 | parsing::{ | 13 | parsing::{ |
15 | lexer::{lex_single_syntax_kind, tokenize, Token}, | 14 | lexer::{lex_single_syntax_kind, tokenize, Token}, |
16 | text_token_source::TextTokenSource, | 15 | text_token_source::TextTokenSource, |
@@ -41,7 +40,7 @@ fn reparse_token<'node>( | |||
41 | root: &'node SyntaxNode, | 40 | root: &'node SyntaxNode, |
42 | edit: &Indel, | 41 | edit: &Indel, |
43 | ) -> Option<(GreenNode, Vec<SyntaxError>, TextRange)> { | 42 | ) -> Option<(GreenNode, Vec<SyntaxError>, TextRange)> { |
44 | let prev_token = algo::find_covering_element(root, edit.delete).as_token()?.clone(); | 43 | let prev_token = root.covering_element(edit.delete).as_token()?.clone(); |
45 | let prev_token_kind = prev_token.kind(); | 44 | let prev_token_kind = prev_token.kind(); |
46 | match prev_token_kind { | 45 | match prev_token_kind { |
47 | WHITESPACE | COMMENT | IDENT | STRING => { | 46 | WHITESPACE | COMMENT | IDENT | STRING => { |
@@ -124,7 +123,7 @@ fn is_contextual_kw(text: &str) -> bool { | |||
124 | } | 123 | } |
125 | 124 | ||
126 | fn find_reparsable_node(node: &SyntaxNode, range: TextRange) -> Option<(SyntaxNode, Reparser)> { | 125 | fn find_reparsable_node(node: &SyntaxNode, range: TextRange) -> Option<(SyntaxNode, Reparser)> { |
127 | let node = algo::find_covering_element(node, range); | 126 | let node = node.covering_element(range); |
128 | 127 | ||
129 | let mut ancestors = match node { | 128 | let mut ancestors = match node { |
130 | NodeOrToken::Token(it) => it.parent().ancestors(), | 129 | NodeOrToken::Token(it) => it.parent().ancestors(), |
diff --git a/crates/syntax/test_data/parser/inline/ok/0159_yield_expr.rast b/crates/syntax/test_data/parser/inline/ok/0159_yield_expr.rast new file mode 100644 index 000000000..05fc90743 --- /dev/null +++ b/crates/syntax/test_data/parser/inline/ok/0159_yield_expr.rast | |||
@@ -0,0 +1,28 @@ | |||
1 | [email protected] | ||
2 | [email protected] | ||
3 | [email protected] "fn" | ||
4 | [email protected] " " | ||
5 | [email protected] | ||
6 | [email protected] "foo" | ||
7 | [email protected] | ||
8 | [email protected] "(" | ||
9 | [email protected] ")" | ||
10 | [email protected] " " | ||
11 | [email protected] | ||
12 | [email protected] "{" | ||
13 | [email protected] "\n " | ||
14 | [email protected] | ||
15 | [email protected] | ||
16 | [email protected] "yield" | ||
17 | [email protected] ";" | ||
18 | [email protected] "\n " | ||
19 | [email protected] | ||
20 | [email protected] | ||
21 | [email protected] "yield" | ||
22 | [email protected] " " | ||
23 | [email protected] | ||
24 | [email protected] "1" | ||
25 | [email protected] ";" | ||
26 | [email protected] "\n" | ||
27 | [email protected] "}" | ||
28 | [email protected] "\n" | ||
diff --git a/crates/syntax/test_data/parser/inline/ok/0159_yield_expr.rs b/crates/syntax/test_data/parser/inline/ok/0159_yield_expr.rs new file mode 100644 index 000000000..596e221f7 --- /dev/null +++ b/crates/syntax/test_data/parser/inline/ok/0159_yield_expr.rs | |||
@@ -0,0 +1,4 @@ | |||
1 | fn foo() { | ||
2 | yield; | ||
3 | yield 1; | ||
4 | } | ||
diff --git a/xtask/Cargo.toml b/xtask/Cargo.toml index 7a2937f0e..61a944c13 100644 --- a/xtask/Cargo.toml +++ b/xtask/Cargo.toml | |||
@@ -15,7 +15,7 @@ flate2 = "1.0" | |||
15 | pico-args = "0.3.1" | 15 | pico-args = "0.3.1" |
16 | proc-macro2 = "1.0.8" | 16 | proc-macro2 = "1.0.8" |
17 | quote = "1.0.2" | 17 | quote = "1.0.2" |
18 | ungrammar = "1.6" | 18 | ungrammar = "1.7" |
19 | walkdir = "2.3.1" | 19 | walkdir = "2.3.1" |
20 | write-json = "0.1.0" | 20 | write-json = "0.1.0" |
21 | xshell = "0.1" | 21 | xshell = "0.1" |
diff --git a/xtask/src/ast_src.rs b/xtask/src/ast_src.rs index 2b8012bdd..046d68f52 100644 --- a/xtask/src/ast_src.rs +++ b/xtask/src/ast_src.rs | |||
@@ -68,7 +68,7 @@ pub(crate) const KINDS_SRC: KindsSrc = KindsSrc { | |||
68 | "as", "async", "await", "box", "break", "const", "continue", "crate", "dyn", "else", | 68 | "as", "async", "await", "box", "break", "const", "continue", "crate", "dyn", "else", |
69 | "enum", "extern", "false", "fn", "for", "if", "impl", "in", "let", "loop", "macro", | 69 | "enum", "extern", "false", "fn", "for", "if", "impl", "in", "let", "loop", "macro", |
70 | "match", "mod", "move", "mut", "pub", "ref", "return", "self", "static", "struct", "super", | 70 | "match", "mod", "move", "mut", "pub", "ref", "return", "self", "static", "struct", "super", |
71 | "trait", "true", "try", "type", "unsafe", "use", "where", "while", | 71 | "trait", "true", "try", "type", "unsafe", "use", "where", "while", "yield", |
72 | ], | 72 | ], |
73 | contextual_keywords: &["auto", "default", "existential", "union", "raw", "macro_rules"], | 73 | contextual_keywords: &["auto", "default", "existential", "union", "raw", "macro_rules"], |
74 | literals: &["INT_NUMBER", "FLOAT_NUMBER", "CHAR", "BYTE", "STRING", "BYTE_STRING"], | 74 | literals: &["INT_NUMBER", "FLOAT_NUMBER", "CHAR", "BYTE", "STRING", "BYTE_STRING"], |
@@ -149,6 +149,7 @@ pub(crate) const KINDS_SRC: KindsSrc = KindsSrc { | |||
149 | "LABEL", | 149 | "LABEL", |
150 | "BLOCK_EXPR", | 150 | "BLOCK_EXPR", |
151 | "RETURN_EXPR", | 151 | "RETURN_EXPR", |
152 | "YIELD_EXPR", | ||
152 | "MATCH_EXPR", | 153 | "MATCH_EXPR", |
153 | "MATCH_ARM_LIST", | 154 | "MATCH_ARM_LIST", |
154 | "MATCH_ARM", | 155 | "MATCH_ARM", |