diff options
Diffstat (limited to 'crates/syntax/src')
-rw-r--r-- | crates/syntax/src/algo.rs | 4 | ||||
-rw-r--r-- | crates/syntax/src/ast/edit.rs | 52 | ||||
-rw-r--r-- | crates/syntax/src/ast/edit_in_place.rs | 44 | ||||
-rw-r--r-- | crates/syntax/src/ast/expr_ext.rs | 44 | ||||
-rw-r--r-- | crates/syntax/src/ast/make.rs | 4 | ||||
-rw-r--r-- | crates/syntax/src/ast/node_ext.rs | 28 | ||||
-rw-r--r-- | crates/syntax/src/ast/token_ext.rs | 10 | ||||
-rw-r--r-- | crates/syntax/src/fuzz.rs | 2 | ||||
-rw-r--r-- | crates/syntax/src/ted.rs | 28 | ||||
-rw-r--r-- | crates/syntax/src/validation.rs | 4 |
10 files changed, 122 insertions, 98 deletions
diff --git a/crates/syntax/src/algo.rs b/crates/syntax/src/algo.rs index 82ebf9037..a153a9e1c 100644 --- a/crates/syntax/src/algo.rs +++ b/crates/syntax/src/algo.rs | |||
@@ -567,7 +567,7 @@ impl<'a> SyntaxRewriter<'a> { | |||
567 | 567 | ||
568 | fn element_to_green(element: SyntaxElement) -> NodeOrToken<rowan::GreenNode, rowan::GreenToken> { | 568 | fn element_to_green(element: SyntaxElement) -> NodeOrToken<rowan::GreenNode, rowan::GreenToken> { |
569 | match element { | 569 | match element { |
570 | NodeOrToken::Node(it) => NodeOrToken::Node(it.green().to_owned()), | 570 | NodeOrToken::Node(it) => NodeOrToken::Node(it.green()), |
571 | NodeOrToken::Token(it) => NodeOrToken::Token(it.green().to_owned()), | 571 | NodeOrToken::Token(it) => NodeOrToken::Token(it.green().to_owned()), |
572 | } | 572 | } |
573 | } | 573 | } |
@@ -625,7 +625,7 @@ fn position_of_child(parent: &SyntaxNode, child: SyntaxElement) -> usize { | |||
625 | 625 | ||
626 | fn to_green_element(element: SyntaxElement) -> NodeOrToken<rowan::GreenNode, rowan::GreenToken> { | 626 | fn to_green_element(element: SyntaxElement) -> NodeOrToken<rowan::GreenNode, rowan::GreenToken> { |
627 | match element { | 627 | match element { |
628 | NodeOrToken::Node(it) => it.green().to_owned().into(), | 628 | NodeOrToken::Node(it) => it.green().into(), |
629 | NodeOrToken::Token(it) => it.green().to_owned().into(), | 629 | NodeOrToken::Token(it) => it.green().to_owned().into(), |
630 | } | 630 | } |
631 | } | 631 | } |
diff --git a/crates/syntax/src/ast/edit.rs b/crates/syntax/src/ast/edit.rs index 64fac13a7..18820786a 100644 --- a/crates/syntax/src/ast/edit.rs +++ b/crates/syntax/src/ast/edit.rs | |||
@@ -9,7 +9,7 @@ use std::{ | |||
9 | use arrayvec::ArrayVec; | 9 | use arrayvec::ArrayVec; |
10 | 10 | ||
11 | use crate::{ | 11 | use crate::{ |
12 | algo::{self, neighbor, SyntaxRewriter}, | 12 | algo::{self, SyntaxRewriter}, |
13 | ast::{ | 13 | ast::{ |
14 | self, | 14 | self, |
15 | make::{self, tokens}, | 15 | make::{self, tokens}, |
@@ -322,28 +322,6 @@ impl ast::Use { | |||
322 | } | 322 | } |
323 | self.clone() | 323 | self.clone() |
324 | } | 324 | } |
325 | |||
326 | pub fn remove(&self) -> SyntaxRewriter<'static> { | ||
327 | let mut res = SyntaxRewriter::default(); | ||
328 | res.delete(self.syntax()); | ||
329 | let next_ws = self | ||
330 | .syntax() | ||
331 | .next_sibling_or_token() | ||
332 | .and_then(|it| it.into_token()) | ||
333 | .and_then(ast::Whitespace::cast); | ||
334 | if let Some(next_ws) = next_ws { | ||
335 | let ws_text = next_ws.syntax().text(); | ||
336 | if ws_text.starts_with('\n') { | ||
337 | let rest = &ws_text[1..]; | ||
338 | if rest.is_empty() { | ||
339 | res.delete(next_ws.syntax()) | ||
340 | } else { | ||
341 | res.replace(next_ws.syntax(), &make::tokens::whitespace(rest)); | ||
342 | } | ||
343 | } | ||
344 | } | ||
345 | res | ||
346 | } | ||
347 | } | 325 | } |
348 | 326 | ||
349 | impl ast::UseTree { | 327 | impl ast::UseTree { |
@@ -397,22 +375,6 @@ impl ast::UseTree { | |||
397 | Some(res) | 375 | Some(res) |
398 | } | 376 | } |
399 | } | 377 | } |
400 | |||
401 | pub fn remove(&self) -> SyntaxRewriter<'static> { | ||
402 | let mut res = SyntaxRewriter::default(); | ||
403 | res.delete(self.syntax()); | ||
404 | for &dir in [Direction::Next, Direction::Prev].iter() { | ||
405 | if let Some(nb) = neighbor(self, dir) { | ||
406 | self.syntax() | ||
407 | .siblings_with_tokens(dir) | ||
408 | .skip(1) | ||
409 | .take_while(|it| it.as_node() != Some(nb.syntax())) | ||
410 | .for_each(|el| res.delete(&el)); | ||
411 | return res; | ||
412 | } | ||
413 | } | ||
414 | res | ||
415 | } | ||
416 | } | 378 | } |
417 | 379 | ||
418 | impl ast::MatchArmList { | 380 | impl ast::MatchArmList { |
@@ -462,8 +424,7 @@ impl ast::MatchArmList { | |||
462 | let end = if let Some(comma) = start | 424 | let end = if let Some(comma) = start |
463 | .siblings_with_tokens(Direction::Next) | 425 | .siblings_with_tokens(Direction::Next) |
464 | .skip(1) | 426 | .skip(1) |
465 | .skip_while(|it| it.kind().is_trivia()) | 427 | .find(|it| !it.kind().is_trivia()) |
466 | .next() | ||
467 | .filter(|it| it.kind() == T![,]) | 428 | .filter(|it| it.kind() == T![,]) |
468 | { | 429 | { |
469 | comma | 430 | comma |
@@ -594,10 +555,17 @@ impl ops::Add<u8> for IndentLevel { | |||
594 | } | 555 | } |
595 | 556 | ||
596 | impl IndentLevel { | 557 | impl IndentLevel { |
558 | pub fn from_element(element: &SyntaxElement) -> IndentLevel { | ||
559 | match element { | ||
560 | rowan::NodeOrToken::Node(it) => IndentLevel::from_node(it), | ||
561 | rowan::NodeOrToken::Token(it) => IndentLevel::from_token(it), | ||
562 | } | ||
563 | } | ||
564 | |||
597 | pub fn from_node(node: &SyntaxNode) -> IndentLevel { | 565 | pub fn from_node(node: &SyntaxNode) -> IndentLevel { |
598 | match node.first_token() { | 566 | match node.first_token() { |
599 | Some(it) => Self::from_token(&it), | 567 | Some(it) => Self::from_token(&it), |
600 | None => return IndentLevel(0), | 568 | None => IndentLevel(0), |
601 | } | 569 | } |
602 | } | 570 | } |
603 | 571 | ||
diff --git a/crates/syntax/src/ast/edit_in_place.rs b/crates/syntax/src/ast/edit_in_place.rs index b1eed0a2c..529bd0eb1 100644 --- a/crates/syntax/src/ast/edit_in_place.rs +++ b/crates/syntax/src/ast/edit_in_place.rs | |||
@@ -2,13 +2,13 @@ | |||
2 | 2 | ||
3 | use std::iter::empty; | 3 | use std::iter::empty; |
4 | 4 | ||
5 | use ast::{edit::AstNodeEdit, make, GenericParamsOwner, WhereClause}; | ||
6 | use parser::T; | 5 | use parser::T; |
7 | 6 | ||
8 | use crate::{ | 7 | use crate::{ |
9 | ast, | 8 | algo::neighbor, |
9 | ast::{self, edit::AstNodeEdit, make, GenericParamsOwner, WhereClause}, | ||
10 | ted::{self, Position}, | 10 | ted::{self, Position}, |
11 | AstNode, Direction, | 11 | AstNode, AstToken, Direction, |
12 | }; | 12 | }; |
13 | 13 | ||
14 | use super::NameOwner; | 14 | use super::NameOwner; |
@@ -126,3 +126,41 @@ impl ast::TypeBoundList { | |||
126 | } | 126 | } |
127 | } | 127 | } |
128 | } | 128 | } |
129 | |||
130 | impl ast::UseTree { | ||
131 | pub fn remove(&self) { | ||
132 | for &dir in [Direction::Next, Direction::Prev].iter() { | ||
133 | if let Some(next_use_tree) = neighbor(self, dir) { | ||
134 | let separators = self | ||
135 | .syntax() | ||
136 | .siblings_with_tokens(dir) | ||
137 | .skip(1) | ||
138 | .take_while(|it| it.as_node() != Some(next_use_tree.syntax())); | ||
139 | ted::remove_all_iter(separators); | ||
140 | break; | ||
141 | } | ||
142 | } | ||
143 | ted::remove(self.syntax()) | ||
144 | } | ||
145 | } | ||
146 | |||
147 | impl ast::Use { | ||
148 | pub fn remove(&self) { | ||
149 | let next_ws = self | ||
150 | .syntax() | ||
151 | .next_sibling_or_token() | ||
152 | .and_then(|it| it.into_token()) | ||
153 | .and_then(ast::Whitespace::cast); | ||
154 | if let Some(next_ws) = next_ws { | ||
155 | let ws_text = next_ws.syntax().text(); | ||
156 | if let Some(rest) = ws_text.strip_prefix('\n') { | ||
157 | if rest.is_empty() { | ||
158 | ted::remove(next_ws.syntax()) | ||
159 | } else { | ||
160 | ted::replace(next_ws.syntax(), make::tokens::whitespace(rest)) | ||
161 | } | ||
162 | } | ||
163 | } | ||
164 | ted::remove(self.syntax()) | ||
165 | } | ||
166 | } | ||
diff --git a/crates/syntax/src/ast/expr_ext.rs b/crates/syntax/src/ast/expr_ext.rs index 636ce166d..6317d84ba 100644 --- a/crates/syntax/src/ast/expr_ext.rs +++ b/crates/syntax/src/ast/expr_ext.rs | |||
@@ -11,16 +11,16 @@ impl ast::AttrsOwner for ast::Expr {} | |||
11 | 11 | ||
12 | impl ast::Expr { | 12 | impl ast::Expr { |
13 | pub fn is_block_like(&self) -> bool { | 13 | pub fn is_block_like(&self) -> bool { |
14 | match self { | 14 | matches!( |
15 | self, | ||
15 | ast::Expr::IfExpr(_) | 16 | ast::Expr::IfExpr(_) |
16 | | ast::Expr::LoopExpr(_) | 17 | | ast::Expr::LoopExpr(_) |
17 | | ast::Expr::ForExpr(_) | 18 | | ast::Expr::ForExpr(_) |
18 | | ast::Expr::WhileExpr(_) | 19 | | ast::Expr::WhileExpr(_) |
19 | | ast::Expr::BlockExpr(_) | 20 | | ast::Expr::BlockExpr(_) |
20 | | ast::Expr::MatchExpr(_) | 21 | | ast::Expr::MatchExpr(_) |
21 | | ast::Expr::EffectExpr(_) => true, | 22 | | ast::Expr::EffectExpr(_) |
22 | _ => false, | 23 | ) |
23 | } | ||
24 | } | 24 | } |
25 | 25 | ||
26 | pub fn name_ref(&self) -> Option<ast::NameRef> { | 26 | pub fn name_ref(&self) -> Option<ast::NameRef> { |
@@ -151,20 +151,20 @@ pub enum BinOp { | |||
151 | 151 | ||
152 | impl BinOp { | 152 | impl BinOp { |
153 | pub fn is_assignment(self) -> bool { | 153 | pub fn is_assignment(self) -> bool { |
154 | match self { | 154 | matches!( |
155 | self, | ||
155 | BinOp::Assignment | 156 | BinOp::Assignment |
156 | | BinOp::AddAssign | 157 | | BinOp::AddAssign |
157 | | BinOp::DivAssign | 158 | | BinOp::DivAssign |
158 | | BinOp::MulAssign | 159 | | BinOp::MulAssign |
159 | | BinOp::RemAssign | 160 | | BinOp::RemAssign |
160 | | BinOp::ShrAssign | 161 | | BinOp::ShrAssign |
161 | | BinOp::ShlAssign | 162 | | BinOp::ShlAssign |
162 | | BinOp::SubAssign | 163 | | BinOp::SubAssign |
163 | | BinOp::BitOrAssign | 164 | | BinOp::BitOrAssign |
164 | | BinOp::BitAndAssign | 165 | | BinOp::BitAndAssign |
165 | | BinOp::BitXorAssign => true, | 166 | | BinOp::BitXorAssign |
166 | _ => false, | 167 | ) |
167 | } | ||
168 | } | 168 | } |
169 | } | 169 | } |
170 | 170 | ||
diff --git a/crates/syntax/src/ast/make.rs b/crates/syntax/src/ast/make.rs index 810c8d4c8..c08f2c14f 100644 --- a/crates/syntax/src/ast/make.rs +++ b/crates/syntax/src/ast/make.rs | |||
@@ -532,7 +532,7 @@ fn ast_from_text<N: AstNode>(text: &str) -> N { | |||
532 | } | 532 | } |
533 | 533 | ||
534 | fn unroot(n: SyntaxNode) -> SyntaxNode { | 534 | fn unroot(n: SyntaxNode) -> SyntaxNode { |
535 | SyntaxNode::new_root(n.green().to_owned()) | 535 | SyntaxNode::new_root(n.green()) |
536 | } | 536 | } |
537 | 537 | ||
538 | pub mod tokens { | 538 | pub mod tokens { |
@@ -560,7 +560,7 @@ pub mod tokens { | |||
560 | pub fn whitespace(text: &str) -> SyntaxToken { | 560 | pub fn whitespace(text: &str) -> SyntaxToken { |
561 | assert!(text.trim().is_empty()); | 561 | assert!(text.trim().is_empty()); |
562 | let sf = SourceFile::parse(text).ok().unwrap(); | 562 | let sf = SourceFile::parse(text).ok().unwrap(); |
563 | sf.syntax().first_child_or_token().unwrap().into_token().unwrap() | 563 | sf.syntax().clone_for_update().first_child_or_token().unwrap().into_token().unwrap() |
564 | } | 564 | } |
565 | 565 | ||
566 | pub fn doc_comment(text: &str) -> SyntaxToken { | 566 | pub fn doc_comment(text: &str) -> SyntaxToken { |
diff --git a/crates/syntax/src/ast/node_ext.rs b/crates/syntax/src/ast/node_ext.rs index 01f580a40..bdf907a21 100644 --- a/crates/syntax/src/ast/node_ext.rs +++ b/crates/syntax/src/ast/node_ext.rs | |||
@@ -58,10 +58,7 @@ impl From<ast::MacroDef> for Macro { | |||
58 | 58 | ||
59 | impl AstNode for Macro { | 59 | impl AstNode for Macro { |
60 | fn can_cast(kind: SyntaxKind) -> bool { | 60 | fn can_cast(kind: SyntaxKind) -> bool { |
61 | match kind { | 61 | matches!(kind, SyntaxKind::MACRO_RULES | SyntaxKind::MACRO_DEF) |
62 | SyntaxKind::MACRO_RULES | SyntaxKind::MACRO_DEF => true, | ||
63 | _ => false, | ||
64 | } | ||
65 | } | 62 | } |
66 | fn cast(syntax: SyntaxNode) -> Option<Self> { | 63 | fn cast(syntax: SyntaxNode) -> Option<Self> { |
67 | let res = match syntax.kind() { | 64 | let res = match syntax.kind() { |
@@ -380,6 +377,15 @@ impl fmt::Display for NameOrNameRef { | |||
380 | } | 377 | } |
381 | } | 378 | } |
382 | 379 | ||
380 | impl NameOrNameRef { | ||
381 | pub fn text(&self) -> &str { | ||
382 | match self { | ||
383 | NameOrNameRef::Name(name) => name.text(), | ||
384 | NameOrNameRef::NameRef(name_ref) => name_ref.text(), | ||
385 | } | ||
386 | } | ||
387 | } | ||
388 | |||
383 | impl ast::RecordPatField { | 389 | impl ast::RecordPatField { |
384 | pub fn for_field_name_ref(field_name: &ast::NameRef) -> Option<ast::RecordPatField> { | 390 | pub fn for_field_name_ref(field_name: &ast::NameRef) -> Option<ast::RecordPatField> { |
385 | let candidate = field_name.syntax().parent().and_then(ast::RecordPatField::cast)?; | 391 | let candidate = field_name.syntax().parent().and_then(ast::RecordPatField::cast)?; |
@@ -453,10 +459,8 @@ impl ast::FieldExpr { | |||
453 | pub fn field_access(&self) -> Option<FieldKind> { | 459 | pub fn field_access(&self) -> Option<FieldKind> { |
454 | if let Some(nr) = self.name_ref() { | 460 | if let Some(nr) = self.name_ref() { |
455 | Some(FieldKind::Name(nr)) | 461 | Some(FieldKind::Name(nr)) |
456 | } else if let Some(tok) = self.index_token() { | ||
457 | Some(FieldKind::Index(tok)) | ||
458 | } else { | 462 | } else { |
459 | None | 463 | self.index_token().map(FieldKind::Index) |
460 | } | 464 | } |
461 | } | 465 | } |
462 | } | 466 | } |
@@ -473,16 +477,10 @@ impl ast::SlicePat { | |||
473 | let prefix = args | 477 | let prefix = args |
474 | .peeking_take_while(|p| match p { | 478 | .peeking_take_while(|p| match p { |
475 | ast::Pat::RestPat(_) => false, | 479 | ast::Pat::RestPat(_) => false, |
476 | ast::Pat::IdentPat(bp) => match bp.pat() { | 480 | ast::Pat::IdentPat(bp) => !matches!(bp.pat(), Some(ast::Pat::RestPat(_))), |
477 | Some(ast::Pat::RestPat(_)) => false, | ||
478 | _ => true, | ||
479 | }, | ||
480 | ast::Pat::RefPat(rp) => match rp.pat() { | 481 | ast::Pat::RefPat(rp) => match rp.pat() { |
481 | Some(ast::Pat::RestPat(_)) => false, | 482 | Some(ast::Pat::RestPat(_)) => false, |
482 | Some(ast::Pat::IdentPat(bp)) => match bp.pat() { | 483 | Some(ast::Pat::IdentPat(bp)) => !matches!(bp.pat(), Some(ast::Pat::RestPat(_))), |
483 | Some(ast::Pat::RestPat(_)) => false, | ||
484 | _ => true, | ||
485 | }, | ||
486 | _ => true, | 484 | _ => true, |
487 | }, | 485 | }, |
488 | _ => true, | 486 | _ => true, |
diff --git a/crates/syntax/src/ast/token_ext.rs b/crates/syntax/src/ast/token_ext.rs index 6c242d126..29d25a58a 100644 --- a/crates/syntax/src/ast/token_ext.rs +++ b/crates/syntax/src/ast/token_ext.rs | |||
@@ -102,8 +102,9 @@ impl CommentKind { | |||
102 | kind | 102 | kind |
103 | } | 103 | } |
104 | 104 | ||
105 | fn prefix(&self) -> &'static str { | 105 | pub fn prefix(&self) -> &'static str { |
106 | let &(prefix, _) = CommentKind::BY_PREFIX.iter().find(|(_, kind)| kind == self).unwrap(); | 106 | let &(prefix, _) = |
107 | CommentKind::BY_PREFIX.iter().rev().find(|(_, kind)| kind == self).unwrap(); | ||
107 | prefix | 108 | prefix |
108 | } | 109 | } |
109 | } | 110 | } |
@@ -494,9 +495,8 @@ pub trait HasFormatSpecifier: AstToken { | |||
494 | } | 495 | } |
495 | _ => { | 496 | _ => { |
496 | while let Some((_, Ok(next_char))) = chars.peek() { | 497 | while let Some((_, Ok(next_char))) = chars.peek() { |
497 | match next_char { | 498 | if next_char == &'{' { |
498 | '{' => break, | 499 | break; |
499 | _ => {} | ||
500 | } | 500 | } |
501 | chars.next(); | 501 | chars.next(); |
502 | } | 502 | } |
diff --git a/crates/syntax/src/fuzz.rs b/crates/syntax/src/fuzz.rs index fbb97aa27..aa84239d2 100644 --- a/crates/syntax/src/fuzz.rs +++ b/crates/syntax/src/fuzz.rs | |||
@@ -43,7 +43,7 @@ impl CheckReparse { | |||
43 | TextRange::at(delete_start.try_into().unwrap(), delete_len.try_into().unwrap()); | 43 | TextRange::at(delete_start.try_into().unwrap(), delete_len.try_into().unwrap()); |
44 | let edited_text = | 44 | let edited_text = |
45 | format!("{}{}{}", &text[..delete_start], &insert, &text[delete_start + delete_len..]); | 45 | format!("{}{}{}", &text[..delete_start], &insert, &text[delete_start + delete_len..]); |
46 | let edit = Indel { delete, insert }; | 46 | let edit = Indel { insert, delete }; |
47 | Some(CheckReparse { text, edit, edited_text }) | 47 | Some(CheckReparse { text, edit, edited_text }) |
48 | } | 48 | } |
49 | 49 | ||
diff --git a/crates/syntax/src/ted.rs b/crates/syntax/src/ted.rs index be2b846b1..177d4ff67 100644 --- a/crates/syntax/src/ted.rs +++ b/crates/syntax/src/ted.rs | |||
@@ -2,11 +2,14 @@ | |||
2 | //! | 2 | //! |
3 | //! The `_raw`-suffixed functions insert elements as is, unsuffixed versions fix | 3 | //! The `_raw`-suffixed functions insert elements as is, unsuffixed versions fix |
4 | //! up elements around the edges. | 4 | //! up elements around the edges. |
5 | use std::ops::RangeInclusive; | 5 | use std::{mem, ops::RangeInclusive}; |
6 | 6 | ||
7 | use parser::T; | 7 | use parser::T; |
8 | 8 | ||
9 | use crate::{ast::make, SyntaxElement, SyntaxKind, SyntaxNode, SyntaxToken}; | 9 | use crate::{ |
10 | ast::{edit::IndentLevel, make}, | ||
11 | SyntaxElement, SyntaxKind, SyntaxNode, SyntaxToken, | ||
12 | }; | ||
10 | 13 | ||
11 | /// Utility trait to allow calling `ted` functions with references or owned | 14 | /// Utility trait to allow calling `ted` functions with references or owned |
12 | /// nodes. Do not use outside of this module. | 15 | /// nodes. Do not use outside of this module. |
@@ -101,12 +104,25 @@ pub fn insert_all_raw(position: Position, elements: Vec<SyntaxElement>) { | |||
101 | } | 104 | } |
102 | 105 | ||
103 | pub fn remove(elem: impl Element) { | 106 | pub fn remove(elem: impl Element) { |
104 | let elem = elem.syntax_element(); | 107 | elem.syntax_element().detach() |
105 | remove_all(elem.clone()..=elem) | ||
106 | } | 108 | } |
107 | pub fn remove_all(range: RangeInclusive<SyntaxElement>) { | 109 | pub fn remove_all(range: RangeInclusive<SyntaxElement>) { |
108 | replace_all(range, Vec::new()) | 110 | replace_all(range, Vec::new()) |
109 | } | 111 | } |
112 | pub fn remove_all_iter(range: impl IntoIterator<Item = SyntaxElement>) { | ||
113 | let mut it = range.into_iter(); | ||
114 | if let Some(mut first) = it.next() { | ||
115 | match it.last() { | ||
116 | Some(mut last) => { | ||
117 | if first.index() > last.index() { | ||
118 | mem::swap(&mut first, &mut last) | ||
119 | } | ||
120 | remove_all(first..=last) | ||
121 | } | ||
122 | None => remove(first), | ||
123 | } | ||
124 | } | ||
125 | } | ||
110 | 126 | ||
111 | pub fn replace(old: impl Element, new: impl Element) { | 127 | pub fn replace(old: impl Element, new: impl Element) { |
112 | let old = old.syntax_element(); | 128 | let old = old.syntax_element(); |
@@ -149,5 +165,9 @@ fn ws_between(left: &SyntaxElement, right: &SyntaxElement) -> Option<SyntaxToken | |||
149 | if right.kind() == T![;] || right.kind() == T![,] { | 165 | if right.kind() == T![;] || right.kind() == T![,] { |
150 | return None; | 166 | return None; |
151 | } | 167 | } |
168 | if right.kind() == SyntaxKind::USE { | ||
169 | let indent = IndentLevel::from_element(left); | ||
170 | return Some(make::tokens::whitespace(&format!("\n{}", indent))); | ||
171 | } | ||
152 | Some(make::tokens::single_space()) | 172 | Some(make::tokens::single_space()) |
153 | } | 173 | } |
diff --git a/crates/syntax/src/validation.rs b/crates/syntax/src/validation.rs index 3e216fb70..bbe802174 100644 --- a/crates/syntax/src/validation.rs +++ b/crates/syntax/src/validation.rs | |||
@@ -297,7 +297,7 @@ fn validate_path_keywords(segment: ast::PathSegment, errors: &mut Vec<SyntaxErro | |||
297 | } | 297 | } |
298 | }; | 298 | }; |
299 | } | 299 | } |
300 | return None; | 300 | None |
301 | } | 301 | } |
302 | 302 | ||
303 | fn all_supers(path: &ast::Path) -> bool { | 303 | fn all_supers(path: &ast::Path) -> bool { |
@@ -314,7 +314,7 @@ fn validate_path_keywords(segment: ast::PathSegment, errors: &mut Vec<SyntaxErro | |||
314 | return all_supers(subpath); | 314 | return all_supers(subpath); |
315 | } | 315 | } |
316 | 316 | ||
317 | return true; | 317 | true |
318 | } | 318 | } |
319 | } | 319 | } |
320 | 320 | ||