diff options
Diffstat (limited to 'crates')
51 files changed, 1401 insertions, 1151 deletions
diff --git a/crates/assists/src/handlers/remove_dbg.rs b/crates/assists/src/handlers/remove_dbg.rs index 0320c2f12..6114091f2 100644 --- a/crates/assists/src/handlers/remove_dbg.rs +++ b/crates/assists/src/handlers/remove_dbg.rs | |||
@@ -1,6 +1,6 @@ | |||
1 | use syntax::{ | 1 | use syntax::{ |
2 | ast::{self, AstNode}, | 2 | ast::{self, AstNode}, |
3 | match_ast, SyntaxElement, SyntaxKind, TextRange, TextSize, T, | 3 | match_ast, SyntaxElement, TextRange, TextSize, T, |
4 | }; | 4 | }; |
5 | 5 | ||
6 | use crate::{AssistContext, AssistId, AssistKind, Assists}; | 6 | use crate::{AssistContext, AssistId, AssistKind, Assists}; |
@@ -136,14 +136,14 @@ fn needs_parentheses_around_macro_contents(macro_contents: Vec<SyntaxElement>) - | |||
136 | symbol_kind => { | 136 | symbol_kind => { |
137 | let symbol_not_in_bracket = unpaired_brackets_in_contents.is_empty(); | 137 | let symbol_not_in_bracket = unpaired_brackets_in_contents.is_empty(); |
138 | if symbol_not_in_bracket | 138 | if symbol_not_in_bracket |
139 | && symbol_kind != SyntaxKind::COLON // paths | 139 | && symbol_kind != T![:] // paths |
140 | && (symbol_kind != SyntaxKind::DOT // field/method access | 140 | && (symbol_kind != T![.] // field/method access |
141 | || macro_contents // range expressions consist of two SyntaxKind::Dot in macro invocations | 141 | || macro_contents // range expressions consist of two SyntaxKind::Dot in macro invocations |
142 | .peek() | 142 | .peek() |
143 | .map(|element| element.kind() == SyntaxKind::DOT) | 143 | .map(|element| element.kind() == T![.]) |
144 | .unwrap_or(false)) | 144 | .unwrap_or(false)) |
145 | && symbol_kind != SyntaxKind::QUESTION // try operator | 145 | && symbol_kind != T![?] // try operator |
146 | && (symbol_kind.is_punct() || symbol_kind == SyntaxKind::AS_KW) | 146 | && (symbol_kind.is_punct() || symbol_kind == T![as]) |
147 | { | 147 | { |
148 | return true; | 148 | return true; |
149 | } | 149 | } |
diff --git a/crates/completion/src/completions/attribute.rs b/crates/completion/src/completions/attribute.rs index 3a29b5203..e5522980d 100644 --- a/crates/completion/src/completions/attribute.rs +++ b/crates/completion/src/completions/attribute.rs | |||
@@ -5,7 +5,7 @@ | |||
5 | 5 | ||
6 | use itertools::Itertools; | 6 | use itertools::Itertools; |
7 | use rustc_hash::FxHashSet; | 7 | use rustc_hash::FxHashSet; |
8 | use syntax::{ast, AstNode, SyntaxKind}; | 8 | use syntax::{ast, AstNode, T}; |
9 | 9 | ||
10 | use crate::{ | 10 | use crate::{ |
11 | context::CompletionContext, | 11 | context::CompletionContext, |
@@ -21,15 +21,17 @@ pub(crate) fn complete_attribute(acc: &mut Completions, ctx: &CompletionContext) | |||
21 | 21 | ||
22 | let attribute = ctx.attribute_under_caret.as_ref()?; | 22 | let attribute = ctx.attribute_under_caret.as_ref()?; |
23 | match (attribute.path(), attribute.token_tree()) { | 23 | match (attribute.path(), attribute.token_tree()) { |
24 | (Some(path), Some(token_tree)) => match path.to_string().as_str() { | 24 | (Some(path), Some(token_tree)) => { |
25 | "derive" => complete_derive(acc, ctx, token_tree), | 25 | let path = path.syntax().text(); |
26 | "feature" => complete_lint(acc, ctx, token_tree, FEATURES), | 26 | if path == "derive" { |
27 | "allow" | "warn" | "deny" | "forbid" => { | 27 | complete_derive(acc, ctx, token_tree) |
28 | } else if path == "feature" { | ||
29 | complete_lint(acc, ctx, token_tree, FEATURES) | ||
30 | } else if path == "allow" || path == "warn" || path == "deny" || path == "forbid" { | ||
28 | complete_lint(acc, ctx, token_tree.clone(), DEFAULT_LINT_COMPLETIONS); | 31 | complete_lint(acc, ctx, token_tree.clone(), DEFAULT_LINT_COMPLETIONS); |
29 | complete_lint(acc, ctx, token_tree, CLIPPY_LINTS); | 32 | complete_lint(acc, ctx, token_tree, CLIPPY_LINTS); |
30 | } | 33 | } |
31 | _ => {} | 34 | } |
32 | }, | ||
33 | (_, Some(_token_tree)) => {} | 35 | (_, Some(_token_tree)) => {} |
34 | _ => complete_attribute_start(acc, ctx, attribute), | 36 | _ => complete_attribute_start(acc, ctx, attribute), |
35 | } | 37 | } |
@@ -203,8 +205,7 @@ fn complete_lint( | |||
203 | fn parse_comma_sep_input(derive_input: ast::TokenTree) -> Result<FxHashSet<String>, ()> { | 205 | fn parse_comma_sep_input(derive_input: ast::TokenTree) -> Result<FxHashSet<String>, ()> { |
204 | match (derive_input.left_delimiter_token(), derive_input.right_delimiter_token()) { | 206 | match (derive_input.left_delimiter_token(), derive_input.right_delimiter_token()) { |
205 | (Some(left_paren), Some(right_paren)) | 207 | (Some(left_paren), Some(right_paren)) |
206 | if left_paren.kind() == SyntaxKind::L_PAREN | 208 | if left_paren.kind() == T!['('] && right_paren.kind() == T![')'] => |
207 | && right_paren.kind() == SyntaxKind::R_PAREN => | ||
208 | { | 209 | { |
209 | let mut input_derives = FxHashSet::default(); | 210 | let mut input_derives = FxHashSet::default(); |
210 | let mut current_derive = String::new(); | 211 | let mut current_derive = String::new(); |
@@ -216,7 +217,7 @@ fn parse_comma_sep_input(derive_input: ast::TokenTree) -> Result<FxHashSet<Strin | |||
216 | .skip(1) | 217 | .skip(1) |
217 | .take_while(|token| token != &right_paren) | 218 | .take_while(|token| token != &right_paren) |
218 | { | 219 | { |
219 | if SyntaxKind::COMMA == token.kind() { | 220 | if T![,] == token.kind() { |
220 | if !current_derive.is_empty() { | 221 | if !current_derive.is_empty() { |
221 | input_derives.insert(current_derive); | 222 | input_derives.insert(current_derive); |
222 | current_derive = String::new(); | 223 | current_derive = String::new(); |
diff --git a/crates/completion/src/completions/trait_impl.rs b/crates/completion/src/completions/trait_impl.rs index aa9c845da..135ae49dc 100644 --- a/crates/completion/src/completions/trait_impl.rs +++ b/crates/completion/src/completions/trait_impl.rs | |||
@@ -93,11 +93,11 @@ fn completion_match(ctx: &CompletionContext) -> Option<(ImplCompletionKind, Synt | |||
93 | // `impl .. { const $0 }` | 93 | // `impl .. { const $0 }` |
94 | // ERROR 0 | 94 | // ERROR 0 |
95 | // CONST_KW <- * | 95 | // CONST_KW <- * |
96 | SyntaxKind::CONST_KW => 0, | 96 | T![const] => 0, |
97 | // `impl .. { fn/type $0 }` | 97 | // `impl .. { fn/type $0 }` |
98 | // FN/TYPE_ALIAS 0 | 98 | // FN/TYPE_ALIAS 0 |
99 | // FN_KW <- * | 99 | // FN_KW <- * |
100 | SyntaxKind::FN_KW | SyntaxKind::TYPE_KW => 0, | 100 | T![fn] | T![type] => 0, |
101 | // `impl .. { fn/type/const foo$0 }` | 101 | // `impl .. { fn/type/const foo$0 }` |
102 | // FN/TYPE_ALIAS/CONST 1 | 102 | // FN/TYPE_ALIAS/CONST 1 |
103 | // NAME 0 | 103 | // NAME 0 |
@@ -121,7 +121,7 @@ fn completion_match(ctx: &CompletionContext) -> Option<(ImplCompletionKind, Synt | |||
121 | let impl_def = ast::Impl::cast(impl_item.parent()?.parent()?)?; | 121 | let impl_def = ast::Impl::cast(impl_item.parent()?.parent()?)?; |
122 | let kind = match impl_item.kind() { | 122 | let kind = match impl_item.kind() { |
123 | // `impl ... { const $0 fn/type/const }` | 123 | // `impl ... { const $0 fn/type/const }` |
124 | _ if token.kind() == SyntaxKind::CONST_KW => ImplCompletionKind::Const, | 124 | _ if token.kind() == T![const] => ImplCompletionKind::Const, |
125 | SyntaxKind::CONST | SyntaxKind::ERROR => ImplCompletionKind::Const, | 125 | SyntaxKind::CONST | SyntaxKind::ERROR => ImplCompletionKind::Const, |
126 | SyntaxKind::TYPE_ALIAS => ImplCompletionKind::TypeAlias, | 126 | SyntaxKind::TYPE_ALIAS => ImplCompletionKind::TypeAlias, |
127 | SyntaxKind::FN => ImplCompletionKind::Fn, | 127 | SyntaxKind::FN => ImplCompletionKind::Fn, |
diff --git a/crates/completion/src/patterns.rs b/crates/completion/src/patterns.rs index f148b9402..f3ce91dd1 100644 --- a/crates/completion/src/patterns.rs +++ b/crates/completion/src/patterns.rs | |||
@@ -5,7 +5,7 @@ use syntax::{ | |||
5 | ast::{self, LoopBodyOwner}, | 5 | ast::{self, LoopBodyOwner}, |
6 | match_ast, AstNode, Direction, NodeOrToken, SyntaxElement, | 6 | match_ast, AstNode, Direction, NodeOrToken, SyntaxElement, |
7 | SyntaxKind::*, | 7 | SyntaxKind::*, |
8 | SyntaxNode, SyntaxToken, | 8 | SyntaxNode, SyntaxToken, T, |
9 | }; | 9 | }; |
10 | 10 | ||
11 | #[cfg(test)] | 11 | #[cfg(test)] |
@@ -119,7 +119,7 @@ pub(crate) fn unsafe_is_prev(element: SyntaxElement) -> bool { | |||
119 | element | 119 | element |
120 | .into_token() | 120 | .into_token() |
121 | .and_then(|it| previous_non_trivia_token(it)) | 121 | .and_then(|it| previous_non_trivia_token(it)) |
122 | .filter(|it| it.kind() == UNSAFE_KW) | 122 | .filter(|it| it.kind() == T![unsafe]) |
123 | .is_some() | 123 | .is_some() |
124 | } | 124 | } |
125 | #[test] | 125 | #[test] |
@@ -131,7 +131,7 @@ pub(crate) fn if_is_prev(element: SyntaxElement) -> bool { | |||
131 | element | 131 | element |
132 | .into_token() | 132 | .into_token() |
133 | .and_then(|it| previous_non_trivia_token(it)) | 133 | .and_then(|it| previous_non_trivia_token(it)) |
134 | .filter(|it| it.kind() == IF_KW) | 134 | .filter(|it| it.kind() == T![if]) |
135 | .is_some() | 135 | .is_some() |
136 | } | 136 | } |
137 | 137 | ||
@@ -139,7 +139,7 @@ pub(crate) fn fn_is_prev(element: SyntaxElement) -> bool { | |||
139 | element | 139 | element |
140 | .into_token() | 140 | .into_token() |
141 | .and_then(|it| previous_non_trivia_token(it)) | 141 | .and_then(|it| previous_non_trivia_token(it)) |
142 | .filter(|it| it.kind() == FN_KW) | 142 | .filter(|it| it.kind() == T![fn]) |
143 | .is_some() | 143 | .is_some() |
144 | } | 144 | } |
145 | #[test] | 145 | #[test] |
@@ -154,7 +154,7 @@ pub(crate) fn for_is_prev2(element: SyntaxElement) -> bool { | |||
154 | .into_token() | 154 | .into_token() |
155 | .and_then(|it| previous_non_trivia_token(it)) | 155 | .and_then(|it| previous_non_trivia_token(it)) |
156 | .and_then(|it| previous_non_trivia_token(it)) | 156 | .and_then(|it| previous_non_trivia_token(it)) |
157 | .filter(|it| it.kind() == FOR_KW) | 157 | .filter(|it| it.kind() == T![for]) |
158 | .is_some() | 158 | .is_some() |
159 | } | 159 | } |
160 | #[test] | 160 | #[test] |
diff --git a/crates/hir/src/code_model.rs b/crates/hir/src/code_model.rs index cc1938333..6cbf5cecf 100644 --- a/crates/hir/src/code_model.rs +++ b/crates/hir/src/code_model.rs | |||
@@ -1263,6 +1263,24 @@ pub enum GenericParam { | |||
1263 | } | 1263 | } |
1264 | impl_from!(TypeParam, LifetimeParam, ConstParam for GenericParam); | 1264 | impl_from!(TypeParam, LifetimeParam, ConstParam for GenericParam); |
1265 | 1265 | ||
1266 | impl GenericParam { | ||
1267 | pub fn module(self, db: &dyn HirDatabase) -> Module { | ||
1268 | match self { | ||
1269 | GenericParam::TypeParam(it) => it.module(db), | ||
1270 | GenericParam::LifetimeParam(it) => it.module(db), | ||
1271 | GenericParam::ConstParam(it) => it.module(db), | ||
1272 | } | ||
1273 | } | ||
1274 | |||
1275 | pub fn name(self, db: &dyn HirDatabase) -> Name { | ||
1276 | match self { | ||
1277 | GenericParam::TypeParam(it) => it.name(db), | ||
1278 | GenericParam::LifetimeParam(it) => it.name(db), | ||
1279 | GenericParam::ConstParam(it) => it.name(db), | ||
1280 | } | ||
1281 | } | ||
1282 | } | ||
1283 | |||
1266 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] | 1284 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] |
1267 | pub struct TypeParam { | 1285 | pub struct TypeParam { |
1268 | pub(crate) id: TypeParamId, | 1286 | pub(crate) id: TypeParamId, |
diff --git a/crates/ide/src/display/navigation_target.rs b/crates/ide/src/display/navigation_target.rs index e24c78301..4eecae697 100644 --- a/crates/ide/src/display/navigation_target.rs +++ b/crates/ide/src/display/navigation_target.rs | |||
@@ -215,10 +215,8 @@ impl TryToNav for Definition { | |||
215 | Definition::ModuleDef(it) => it.try_to_nav(db), | 215 | Definition::ModuleDef(it) => it.try_to_nav(db), |
216 | Definition::SelfType(it) => it.try_to_nav(db), | 216 | Definition::SelfType(it) => it.try_to_nav(db), |
217 | Definition::Local(it) => Some(it.to_nav(db)), | 217 | Definition::Local(it) => Some(it.to_nav(db)), |
218 | Definition::TypeParam(it) => it.try_to_nav(db), | 218 | Definition::GenericParam(it) => it.try_to_nav(db), |
219 | Definition::LifetimeParam(it) => it.try_to_nav(db), | ||
220 | Definition::Label(it) => Some(it.to_nav(db)), | 219 | Definition::Label(it) => Some(it.to_nav(db)), |
221 | Definition::ConstParam(it) => it.try_to_nav(db), | ||
222 | } | 220 | } |
223 | } | 221 | } |
224 | } | 222 | } |
@@ -389,6 +387,16 @@ impl TryToNav for hir::AssocItem { | |||
389 | } | 387 | } |
390 | } | 388 | } |
391 | 389 | ||
390 | impl TryToNav for hir::GenericParam { | ||
391 | fn try_to_nav(&self, db: &RootDatabase) -> Option<NavigationTarget> { | ||
392 | match self { | ||
393 | hir::GenericParam::TypeParam(it) => it.try_to_nav(db), | ||
394 | hir::GenericParam::ConstParam(it) => it.try_to_nav(db), | ||
395 | hir::GenericParam::LifetimeParam(it) => it.try_to_nav(db), | ||
396 | } | ||
397 | } | ||
398 | } | ||
399 | |||
392 | impl ToNav for hir::Local { | 400 | impl ToNav for hir::Local { |
393 | fn to_nav(&self, db: &RootDatabase) -> NavigationTarget { | 401 | fn to_nav(&self, db: &RootDatabase) -> NavigationTarget { |
394 | let src = self.source(db); | 402 | let src = self.source(db); |
diff --git a/crates/ide/src/doc_links.rs b/crates/ide/src/doc_links.rs index 72ddf3690..de10406bc 100644 --- a/crates/ide/src/doc_links.rs +++ b/crates/ide/src/doc_links.rs | |||
@@ -1,6 +1,6 @@ | |||
1 | //! Resolves and rewrites links in markdown documentation. | 1 | //! Resolves and rewrites links in markdown documentation. |
2 | 2 | ||
3 | use std::{convert::TryFrom, iter::once}; | 3 | use std::{convert::TryFrom, iter::once, ops::Range}; |
4 | 4 | ||
5 | use itertools::Itertools; | 5 | use itertools::Itertools; |
6 | use pulldown_cmark::{BrokenLink, CowStr, Event, InlineStr, LinkType, Options, Parser, Tag}; | 6 | use pulldown_cmark::{BrokenLink, CowStr, Event, InlineStr, LinkType, Options, Parser, Tag}; |
@@ -61,6 +61,30 @@ pub(crate) fn rewrite_links(db: &RootDatabase, markdown: &str, definition: &Defi | |||
61 | out | 61 | out |
62 | } | 62 | } |
63 | 63 | ||
64 | pub(crate) fn extract_definitions_from_markdown( | ||
65 | markdown: &str, | ||
66 | ) -> Vec<(String, Option<hir::Namespace>, Range<usize>)> { | ||
67 | let mut res = vec![]; | ||
68 | let mut cb = |link: BrokenLink| { | ||
69 | Some(( | ||
70 | /*url*/ link.reference.to_owned().into(), | ||
71 | /*title*/ link.reference.to_owned().into(), | ||
72 | )) | ||
73 | }; | ||
74 | let doc = Parser::new_with_broken_link_callback(markdown, Options::empty(), Some(&mut cb)); | ||
75 | for (event, range) in doc.into_offset_iter() { | ||
76 | match event { | ||
77 | Event::Start(Tag::Link(_link_type, ref target, ref title)) => { | ||
78 | let link = if target.is_empty() { title } else { target }; | ||
79 | let (link, ns) = parse_link(link); | ||
80 | res.push((link.to_string(), ns, range)); | ||
81 | } | ||
82 | _ => {} | ||
83 | } | ||
84 | } | ||
85 | res | ||
86 | } | ||
87 | |||
64 | /// Remove all links in markdown documentation. | 88 | /// Remove all links in markdown documentation. |
65 | pub(crate) fn remove_links(markdown: &str) -> String { | 89 | pub(crate) fn remove_links(markdown: &str) -> String { |
66 | let mut drop_link = false; | 90 | let mut drop_link = false; |
@@ -192,9 +216,7 @@ fn rewrite_intra_doc_link( | |||
192 | Definition::Field(it) => it.resolve_doc_path(db, link, ns), | 216 | Definition::Field(it) => it.resolve_doc_path(db, link, ns), |
193 | Definition::SelfType(_) | 217 | Definition::SelfType(_) |
194 | | Definition::Local(_) | 218 | | Definition::Local(_) |
195 | | Definition::TypeParam(_) | 219 | | Definition::GenericParam(_) |
196 | | Definition::ConstParam(_) | ||
197 | | Definition::LifetimeParam(_) | ||
198 | | Definition::Label(_) => return None, | 220 | | Definition::Label(_) => return None, |
199 | }?; | 221 | }?; |
200 | let krate = resolved.module(db)?.krate(); | 222 | let krate = resolved.module(db)?.krate(); |
diff --git a/crates/ide/src/goto_definition.rs b/crates/ide/src/goto_definition.rs index 95b4cb9e3..c20185b16 100644 --- a/crates/ide/src/goto_definition.rs +++ b/crates/ide/src/goto_definition.rs | |||
@@ -1,14 +1,20 @@ | |||
1 | use either::Either; | 1 | use either::Either; |
2 | use hir::Semantics; | 2 | use hir::{HasAttrs, ModuleDef, Semantics}; |
3 | use ide_db::{ | 3 | use ide_db::{ |
4 | base_db::FileId, | 4 | base_db::FileId, |
5 | defs::{NameClass, NameRefClass}, | 5 | defs::{Definition, NameClass, NameRefClass}, |
6 | symbol_index, RootDatabase, | 6 | symbol_index, RootDatabase, |
7 | }; | 7 | }; |
8 | use syntax::{ast, match_ast, AstNode, SyntaxKind::*, SyntaxToken, TokenAtOffset, T}; | 8 | use syntax::{ |
9 | ast::{self, NameOwner}, | ||
10 | match_ast, AstNode, AstToken, | ||
11 | SyntaxKind::*, | ||
12 | SyntaxToken, TextSize, TokenAtOffset, T, | ||
13 | }; | ||
9 | 14 | ||
10 | use crate::{ | 15 | use crate::{ |
11 | display::{ToNav, TryToNav}, | 16 | display::{ToNav, TryToNav}, |
17 | doc_links::extract_definitions_from_markdown, | ||
12 | FilePosition, NavigationTarget, RangeInfo, SymbolKind, | 18 | FilePosition, NavigationTarget, RangeInfo, SymbolKind, |
13 | }; | 19 | }; |
14 | 20 | ||
@@ -30,6 +36,10 @@ pub(crate) fn goto_definition( | |||
30 | let original_token = pick_best(file.token_at_offset(position.offset))?; | 36 | let original_token = pick_best(file.token_at_offset(position.offset))?; |
31 | let token = sema.descend_into_macros(original_token.clone()); | 37 | let token = sema.descend_into_macros(original_token.clone()); |
32 | let parent = token.parent(); | 38 | let parent = token.parent(); |
39 | if let Some(comment) = ast::Comment::cast(token.clone()) { | ||
40 | let nav = def_for_doc_comment(&sema, position, &comment)?.try_to_nav(db)?; | ||
41 | return Some(RangeInfo::new(original_token.text_range(), vec![nav])); | ||
42 | } | ||
33 | 43 | ||
34 | let nav_targets = match_ast! { | 44 | let nav_targets = match_ast! { |
35 | match parent { | 45 | match parent { |
@@ -68,11 +78,66 @@ pub(crate) fn goto_definition( | |||
68 | Some(RangeInfo::new(original_token.text_range(), nav_targets)) | 78 | Some(RangeInfo::new(original_token.text_range(), nav_targets)) |
69 | } | 79 | } |
70 | 80 | ||
81 | fn def_for_doc_comment( | ||
82 | sema: &Semantics<RootDatabase>, | ||
83 | position: FilePosition, | ||
84 | doc_comment: &ast::Comment, | ||
85 | ) -> Option<hir::ModuleDef> { | ||
86 | let parent = doc_comment.syntax().parent(); | ||
87 | let db = sema.db; | ||
88 | let (link, ns) = extract_positioned_link_from_comment(position, doc_comment)?; | ||
89 | let link = &link; | ||
90 | let name = match_ast! { | ||
91 | match parent { | ||
92 | ast::Name(name) => Some(name), | ||
93 | ast::Fn(func) => func.name(), | ||
94 | _ => None, | ||
95 | } | ||
96 | }?; | ||
97 | let definition = NameClass::classify(&sema, &name).and_then(|d| d.defined(sema.db))?; | ||
98 | match definition { | ||
99 | Definition::ModuleDef(def) => match def { | ||
100 | ModuleDef::Module(it) => it.resolve_doc_path(db, link, ns), | ||
101 | ModuleDef::Function(it) => it.resolve_doc_path(db, link, ns), | ||
102 | ModuleDef::Adt(it) => it.resolve_doc_path(db, link, ns), | ||
103 | ModuleDef::Variant(it) => it.resolve_doc_path(db, link, ns), | ||
104 | ModuleDef::Const(it) => it.resolve_doc_path(db, link, ns), | ||
105 | ModuleDef::Static(it) => it.resolve_doc_path(db, link, ns), | ||
106 | ModuleDef::Trait(it) => it.resolve_doc_path(db, link, ns), | ||
107 | ModuleDef::TypeAlias(it) => it.resolve_doc_path(db, link, ns), | ||
108 | ModuleDef::BuiltinType(_) => return None, | ||
109 | }, | ||
110 | Definition::Macro(it) => it.resolve_doc_path(db, link, ns), | ||
111 | Definition::Field(it) => it.resolve_doc_path(db, link, ns), | ||
112 | Definition::SelfType(_) | ||
113 | | Definition::Local(_) | ||
114 | | Definition::GenericParam(_) | ||
115 | | Definition::Label(_) => return None, | ||
116 | } | ||
117 | } | ||
118 | |||
119 | fn extract_positioned_link_from_comment( | ||
120 | position: FilePosition, | ||
121 | comment: &ast::Comment, | ||
122 | ) -> Option<(String, Option<hir::Namespace>)> { | ||
123 | let comment_range = comment.syntax().text_range(); | ||
124 | let doc_comment = comment.doc_comment()?; | ||
125 | let def_links = extract_definitions_from_markdown(doc_comment); | ||
126 | let (def_link, ns, _) = def_links.iter().min_by_key(|(_, _, def_link_range)| { | ||
127 | let matched_position = comment_range.start() + TextSize::from(def_link_range.start as u32); | ||
128 | match position.offset.checked_sub(matched_position) { | ||
129 | Some(distance) => distance, | ||
130 | None => comment_range.end(), | ||
131 | } | ||
132 | })?; | ||
133 | Some((def_link.to_string(), ns.clone())) | ||
134 | } | ||
135 | |||
71 | fn pick_best(tokens: TokenAtOffset<SyntaxToken>) -> Option<SyntaxToken> { | 136 | fn pick_best(tokens: TokenAtOffset<SyntaxToken>) -> Option<SyntaxToken> { |
72 | return tokens.max_by_key(priority); | 137 | return tokens.max_by_key(priority); |
73 | fn priority(n: &SyntaxToken) -> usize { | 138 | fn priority(n: &SyntaxToken) -> usize { |
74 | match n.kind() { | 139 | match n.kind() { |
75 | IDENT | INT_NUMBER | LIFETIME_IDENT | T![self] => 2, | 140 | IDENT | INT_NUMBER | LIFETIME_IDENT | T![self] | COMMENT => 2, |
76 | kind if kind.is_trivia() => 0, | 141 | kind if kind.is_trivia() => 0, |
77 | _ => 1, | 142 | _ => 1, |
78 | } | 143 | } |
@@ -1145,4 +1210,19 @@ fn foo<'foo>(_: &'foo ()) { | |||
1145 | }"#, | 1210 | }"#, |
1146 | ) | 1211 | ) |
1147 | } | 1212 | } |
1213 | |||
1214 | #[test] | ||
1215 | fn goto_def_for_intra_rustdoc_link_same_file() { | ||
1216 | check( | ||
1217 | r#" | ||
1218 | /// Blah, [`bar`](bar) .. [`foo`](foo)$0 has [`bar`](bar) | ||
1219 | pub fn bar() { } | ||
1220 | |||
1221 | /// You might want to see [`std::fs::read()`] too. | ||
1222 | pub fn foo() { } | ||
1223 | //^^^ | ||
1224 | |||
1225 | }"#, | ||
1226 | ) | ||
1227 | } | ||
1148 | } | 1228 | } |
diff --git a/crates/ide/src/hover.rs b/crates/ide/src/hover.rs index 165b32ef9..e892d5588 100644 --- a/crates/ide/src/hover.rs +++ b/crates/ide/src/hover.rs | |||
@@ -1,6 +1,6 @@ | |||
1 | use hir::{ | 1 | use hir::{ |
2 | Adt, AsAssocItem, AssocItemContainer, FieldSource, HasAttrs, HasSource, HirDisplay, Module, | 2 | Adt, AsAssocItem, AssocItemContainer, FieldSource, GenericParam, HasAttrs, HasSource, |
3 | ModuleDef, ModuleSource, Semantics, | 3 | HirDisplay, Module, ModuleDef, ModuleSource, Semantics, |
4 | }; | 4 | }; |
5 | use ide_db::base_db::SourceDatabase; | 5 | use ide_db::base_db::SourceDatabase; |
6 | use ide_db::{ | 6 | use ide_db::{ |
@@ -17,7 +17,7 @@ use crate::{ | |||
17 | doc_links::{remove_links, rewrite_links}, | 17 | doc_links::{remove_links, rewrite_links}, |
18 | markdown_remove::remove_markdown, | 18 | markdown_remove::remove_markdown, |
19 | markup::Markup, | 19 | markup::Markup, |
20 | runnables::{runnable, runnable_fn}, | 20 | runnables::{runnable_fn, runnable_mod}, |
21 | FileId, FilePosition, NavigationTarget, RangeInfo, Runnable, | 21 | FileId, FilePosition, NavigationTarget, RangeInfo, Runnable, |
22 | }; | 22 | }; |
23 | 23 | ||
@@ -192,7 +192,7 @@ fn runnable_action( | |||
192 | Definition::ModuleDef(it) => match it { | 192 | Definition::ModuleDef(it) => match it { |
193 | ModuleDef::Module(it) => match it.definition_source(sema.db).value { | 193 | ModuleDef::Module(it) => match it.definition_source(sema.db).value { |
194 | ModuleSource::Module(it) => { | 194 | ModuleSource::Module(it) => { |
195 | runnable(&sema, it.syntax().clone()).map(|it| HoverAction::Runnable(it)) | 195 | runnable_mod(&sema, it).map(|it| HoverAction::Runnable(it)) |
196 | } | 196 | } |
197 | _ => None, | 197 | _ => None, |
198 | }, | 198 | }, |
@@ -220,12 +220,12 @@ fn goto_type_action(db: &RootDatabase, def: Definition) -> Option<HoverAction> { | |||
220 | } | 220 | } |
221 | }; | 221 | }; |
222 | 222 | ||
223 | if let Definition::TypeParam(it) = def { | 223 | if let Definition::GenericParam(GenericParam::TypeParam(it)) = def { |
224 | it.trait_bounds(db).into_iter().for_each(|it| push_new_def(it.into())); | 224 | it.trait_bounds(db).into_iter().for_each(|it| push_new_def(it.into())); |
225 | } else { | 225 | } else { |
226 | let ty = match def { | 226 | let ty = match def { |
227 | Definition::Local(it) => it.ty(db), | 227 | Definition::Local(it) => it.ty(db), |
228 | Definition::ConstParam(it) => it.ty(db), | 228 | Definition::GenericParam(GenericParam::ConstParam(it)) => it.ty(db), |
229 | _ => return None, | 229 | _ => return None, |
230 | }; | 230 | }; |
231 | 231 | ||
@@ -357,9 +357,11 @@ fn hover_for_definition(db: &RootDatabase, def: Definition) -> Option<Markup> { | |||
357 | }) | 357 | }) |
358 | } | 358 | } |
359 | Definition::Label(it) => Some(Markup::fenced_block(&it.name(db))), | 359 | Definition::Label(it) => Some(Markup::fenced_block(&it.name(db))), |
360 | Definition::LifetimeParam(it) => Some(Markup::fenced_block(&it.name(db))), | 360 | Definition::GenericParam(it) => match it { |
361 | Definition::TypeParam(type_param) => Some(Markup::fenced_block(&type_param.display(db))), | 361 | GenericParam::TypeParam(it) => Some(Markup::fenced_block(&it.display(db))), |
362 | Definition::ConstParam(it) => from_def_source(db, it, None), | 362 | GenericParam::LifetimeParam(it) => Some(Markup::fenced_block(&it.name(db))), |
363 | GenericParam::ConstParam(it) => from_def_source(db, it, None), | ||
364 | }, | ||
363 | }; | 365 | }; |
364 | 366 | ||
365 | fn from_def_source<A, D>(db: &RootDatabase, def: D, mod_path: Option<String>) -> Option<Markup> | 367 | fn from_def_source<A, D>(db: &RootDatabase, def: D, mod_path: Option<String>) -> Option<Markup> |
diff --git a/crates/ide/src/inlay_hints.rs b/crates/ide/src/inlay_hints.rs index a74829cd0..3e9a65d9c 100644 --- a/crates/ide/src/inlay_hints.rs +++ b/crates/ide/src/inlay_hints.rs | |||
@@ -353,13 +353,25 @@ fn is_argument_similar_to_param_name( | |||
353 | } | 353 | } |
354 | match get_string_representation(argument) { | 354 | match get_string_representation(argument) { |
355 | None => false, | 355 | None => false, |
356 | Some(mut repr) => { | 356 | Some(argument_string) => { |
357 | let param_name = param_name.to_ascii_lowercase(); | 357 | let num_leading_underscores = |
358 | let argument_string = { | 358 | argument_string.bytes().take_while(|&c| c == b'_').count(); |
359 | repr.make_ascii_lowercase(); | 359 | |
360 | repr.trim_start_matches('_') | 360 | // Does the argument name begin with the parameter name? Ignore leading underscores. |
361 | }; | 361 | let mut arg_bytes = argument_string.bytes().skip(num_leading_underscores); |
362 | argument_string.starts_with(¶m_name) || argument_string.ends_with(¶m_name) | 362 | let starts_with_pattern = param_name.bytes().all( |
363 | |expected| matches!(arg_bytes.next(), Some(actual) if expected.eq_ignore_ascii_case(&actual)), | ||
364 | ); | ||
365 | |||
366 | if starts_with_pattern { | ||
367 | return true; | ||
368 | } | ||
369 | |||
370 | // Does the argument name end with the parameter name? | ||
371 | let mut arg_bytes = argument_string.bytes().skip(num_leading_underscores); | ||
372 | param_name.bytes().rev().all( | ||
373 | |expected| matches!(arg_bytes.next_back(), Some(actual) if expected.eq_ignore_ascii_case(&actual)), | ||
374 | ) | ||
363 | } | 375 | } |
364 | } | 376 | } |
365 | } | 377 | } |
diff --git a/crates/ide/src/lib.rs b/crates/ide/src/lib.rs index 409507bd0..1f368cbd0 100644 --- a/crates/ide/src/lib.rs +++ b/crates/ide/src/lib.rs | |||
@@ -76,7 +76,7 @@ pub use crate::{ | |||
76 | references::{rename::RenameError, Declaration, ReferenceSearchResult}, | 76 | references::{rename::RenameError, Declaration, ReferenceSearchResult}, |
77 | runnables::{Runnable, RunnableKind, TestId}, | 77 | runnables::{Runnable, RunnableKind, TestId}, |
78 | syntax_highlighting::{ | 78 | syntax_highlighting::{ |
79 | tags::{Highlight, HlMod, HlMods, HlTag}, | 79 | tags::{Highlight, HlMod, HlMods, HlPunct, HlTag}, |
80 | HlRange, | 80 | HlRange, |
81 | }, | 81 | }, |
82 | }; | 82 | }; |
diff --git a/crates/ide/src/references.rs b/crates/ide/src/references.rs index 37a95e1c5..b774a2be1 100644 --- a/crates/ide/src/references.rs +++ b/crates/ide/src/references.rs | |||
@@ -21,7 +21,7 @@ use ide_db::{ | |||
21 | use syntax::{ | 21 | use syntax::{ |
22 | algo::find_node_at_offset, | 22 | algo::find_node_at_offset, |
23 | ast::{self, NameOwner}, | 23 | ast::{self, NameOwner}, |
24 | match_ast, AstNode, SyntaxKind, SyntaxNode, TextRange, TokenAtOffset, | 24 | match_ast, AstNode, SyntaxNode, TextRange, TokenAtOffset, T, |
25 | }; | 25 | }; |
26 | 26 | ||
27 | use crate::{display::TryToNav, FilePosition, FileRange, NavigationTarget, RangeInfo, SymbolKind}; | 27 | use crate::{display::TryToNav, FilePosition, FileRange, NavigationTarget, RangeInfo, SymbolKind}; |
@@ -130,7 +130,10 @@ pub(crate) fn find_all_refs( | |||
130 | kind = ReferenceKind::FieldShorthandForLocal; | 130 | kind = ReferenceKind::FieldShorthandForLocal; |
131 | } | 131 | } |
132 | } | 132 | } |
133 | } else if matches!(def, Definition::LifetimeParam(_) | Definition::Label(_)) { | 133 | } else if matches!( |
134 | def, | ||
135 | Definition::GenericParam(hir::GenericParam::LifetimeParam(_)) | Definition::Label(_) | ||
136 | ) { | ||
134 | kind = ReferenceKind::Lifetime; | 137 | kind = ReferenceKind::Lifetime; |
135 | }; | 138 | }; |
136 | 139 | ||
@@ -200,7 +203,7 @@ fn get_struct_def_name_for_struct_literal_search( | |||
200 | position: FilePosition, | 203 | position: FilePosition, |
201 | ) -> Option<ast::Name> { | 204 | ) -> Option<ast::Name> { |
202 | if let TokenAtOffset::Between(ref left, ref right) = syntax.token_at_offset(position.offset) { | 205 | if let TokenAtOffset::Between(ref left, ref right) = syntax.token_at_offset(position.offset) { |
203 | if right.kind() != SyntaxKind::L_CURLY && right.kind() != SyntaxKind::L_PAREN { | 206 | if right.kind() != T!['{'] && right.kind() != T!['('] { |
204 | return None; | 207 | return None; |
205 | } | 208 | } |
206 | if let Some(name) = | 209 | if let Some(name) = |
@@ -227,7 +230,7 @@ fn get_enum_def_name_for_struct_literal_search( | |||
227 | position: FilePosition, | 230 | position: FilePosition, |
228 | ) -> Option<ast::Name> { | 231 | ) -> Option<ast::Name> { |
229 | if let TokenAtOffset::Between(ref left, ref right) = syntax.token_at_offset(position.offset) { | 232 | if let TokenAtOffset::Between(ref left, ref right) = syntax.token_at_offset(position.offset) { |
230 | if right.kind() != SyntaxKind::L_CURLY && right.kind() != SyntaxKind::L_PAREN { | 233 | if right.kind() != T!['{'] && right.kind() != T!['('] { |
231 | return None; | 234 | return None; |
232 | } | 235 | } |
233 | if let Some(name) = | 236 | if let Some(name) = |
@@ -252,8 +255,7 @@ fn try_find_self_references( | |||
252 | syntax: &SyntaxNode, | 255 | syntax: &SyntaxNode, |
253 | position: FilePosition, | 256 | position: FilePosition, |
254 | ) -> Option<RangeInfo<ReferenceSearchResult>> { | 257 | ) -> Option<RangeInfo<ReferenceSearchResult>> { |
255 | let self_token = | 258 | let self_token = syntax.token_at_offset(position.offset).find(|t| t.kind() == T![self])?; |
256 | syntax.token_at_offset(position.offset).find(|t| t.kind() == SyntaxKind::SELF_KW)?; | ||
257 | let parent = self_token.parent(); | 259 | let parent = self_token.parent(); |
258 | match_ast! { | 260 | match_ast! { |
259 | match parent { | 261 | match parent { |
diff --git a/crates/ide/src/runnables.rs b/crates/ide/src/runnables.rs index 557563d7e..3a1e204db 100644 --- a/crates/ide/src/runnables.rs +++ b/crates/ide/src/runnables.rs | |||
@@ -96,21 +96,23 @@ impl Runnable { | |||
96 | pub(crate) fn runnables(db: &RootDatabase, file_id: FileId) -> Vec<Runnable> { | 96 | pub(crate) fn runnables(db: &RootDatabase, file_id: FileId) -> Vec<Runnable> { |
97 | let sema = Semantics::new(db); | 97 | let sema = Semantics::new(db); |
98 | let source_file = sema.parse(file_id); | 98 | let source_file = sema.parse(file_id); |
99 | source_file.syntax().descendants().filter_map(|i| runnable(&sema, i)).collect() | 99 | source_file |
100 | } | 100 | .syntax() |
101 | 101 | .descendants() | |
102 | pub(crate) fn runnable(sema: &Semantics<RootDatabase>, item: SyntaxNode) -> Option<Runnable> { | 102 | .filter_map(|item| { |
103 | let runnable_item = match_ast! { | 103 | let runnable = match_ast! { |
104 | match (item.clone()) { | 104 | match item { |
105 | ast::Fn(func) => { | 105 | ast::Fn(func) => { |
106 | let def = sema.to_def(&func)?; | 106 | let def = sema.to_def(&func)?; |
107 | runnable_fn(sema, def) | 107 | runnable_fn(&sema, def) |
108 | }, | 108 | }, |
109 | ast::Module(it) => runnable_mod(sema, it), | 109 | ast::Module(it) => runnable_mod(&sema, it), |
110 | _ => None, | 110 | _ => None, |
111 | } | 111 | } |
112 | }; | 112 | }; |
113 | runnable_item.or_else(|| runnable_doctest(sema, item)) | 113 | runnable.or_else(|| runnable_doctest(&sema, item)) |
114 | }) | ||
115 | .collect() | ||
114 | } | 116 | } |
115 | 117 | ||
116 | pub(crate) fn runnable_fn(sema: &Semantics<RootDatabase>, def: hir::Function) -> Option<Runnable> { | 118 | pub(crate) fn runnable_fn(sema: &Semantics<RootDatabase>, def: hir::Function) -> Option<Runnable> { |
@@ -145,6 +147,29 @@ pub(crate) fn runnable_fn(sema: &Semantics<RootDatabase>, def: hir::Function) -> | |||
145 | Some(Runnable { nav, kind, cfg }) | 147 | Some(Runnable { nav, kind, cfg }) |
146 | } | 148 | } |
147 | 149 | ||
150 | pub(crate) fn runnable_mod( | ||
151 | sema: &Semantics<RootDatabase>, | ||
152 | module: ast::Module, | ||
153 | ) -> Option<Runnable> { | ||
154 | if !has_test_function_or_multiple_test_submodules(&module) { | ||
155 | return None; | ||
156 | } | ||
157 | let module_def = sema.to_def(&module)?; | ||
158 | |||
159 | let path = module_def | ||
160 | .path_to_root(sema.db) | ||
161 | .into_iter() | ||
162 | .rev() | ||
163 | .filter_map(|it| it.name(sema.db)) | ||
164 | .join("::"); | ||
165 | |||
166 | let def = sema.to_def(&module)?; | ||
167 | let attrs = def.attrs(sema.db); | ||
168 | let cfg = attrs.cfg(); | ||
169 | let nav = module_def.to_nav(sema.db); | ||
170 | Some(Runnable { nav, kind: RunnableKind::TestMod { path }, cfg }) | ||
171 | } | ||
172 | |||
148 | fn runnable_doctest(sema: &Semantics<RootDatabase>, item: SyntaxNode) -> Option<Runnable> { | 173 | fn runnable_doctest(sema: &Semantics<RootDatabase>, item: SyntaxNode) -> Option<Runnable> { |
149 | match_ast! { | 174 | match_ast! { |
150 | match item { | 175 | match item { |
@@ -253,26 +278,6 @@ fn has_runnable_doc_test(attrs: &hir::Attrs) -> bool { | |||
253 | }) | 278 | }) |
254 | } | 279 | } |
255 | 280 | ||
256 | fn runnable_mod(sema: &Semantics<RootDatabase>, module: ast::Module) -> Option<Runnable> { | ||
257 | if !has_test_function_or_multiple_test_submodules(&module) { | ||
258 | return None; | ||
259 | } | ||
260 | let module_def = sema.to_def(&module)?; | ||
261 | |||
262 | let path = module_def | ||
263 | .path_to_root(sema.db) | ||
264 | .into_iter() | ||
265 | .rev() | ||
266 | .filter_map(|it| it.name(sema.db)) | ||
267 | .join("::"); | ||
268 | |||
269 | let def = sema.to_def(&module)?; | ||
270 | let attrs = def.attrs(sema.db); | ||
271 | let cfg = attrs.cfg(); | ||
272 | let nav = module_def.to_nav(sema.db); | ||
273 | Some(Runnable { nav, kind: RunnableKind::TestMod { path }, cfg }) | ||
274 | } | ||
275 | |||
276 | // We could create runnables for modules with number_of_test_submodules > 0, | 281 | // We could create runnables for modules with number_of_test_submodules > 0, |
277 | // but that bloats the runnables for no real benefit, since all tests can be run by the submodule already | 282 | // but that bloats the runnables for no real benefit, since all tests can be run by the submodule already |
278 | fn has_test_function_or_multiple_test_submodules(module: &ast::Module) -> bool { | 283 | fn has_test_function_or_multiple_test_submodules(module: &ast::Module) -> bool { |
diff --git a/crates/ide/src/syntax_highlighting.rs b/crates/ide/src/syntax_highlighting.rs index ad456bc00..f2d4da78d 100644 --- a/crates/ide/src/syntax_highlighting.rs +++ b/crates/ide/src/syntax_highlighting.rs | |||
@@ -3,30 +3,29 @@ pub(crate) mod tags; | |||
3 | mod highlights; | 3 | mod highlights; |
4 | mod injector; | 4 | mod injector; |
5 | 5 | ||
6 | mod highlight; | ||
6 | mod format; | 7 | mod format; |
7 | mod injection; | ||
8 | mod macro_rules; | 8 | mod macro_rules; |
9 | mod inject; | ||
9 | 10 | ||
10 | mod html; | 11 | mod html; |
11 | #[cfg(test)] | 12 | #[cfg(test)] |
12 | mod tests; | 13 | mod tests; |
13 | 14 | ||
14 | use hir::{AsAssocItem, Local, Name, Semantics, VariantDef}; | 15 | use hir::{Name, Semantics}; |
15 | use ide_db::{ | 16 | use ide_db::RootDatabase; |
16 | defs::{Definition, NameClass, NameRefClass}, | ||
17 | RootDatabase, | ||
18 | }; | ||
19 | use rustc_hash::FxHashMap; | 17 | use rustc_hash::FxHashMap; |
20 | use syntax::{ | 18 | use syntax::{ |
21 | ast::{self, HasFormatSpecifier}, | 19 | ast::{self, HasFormatSpecifier}, |
22 | AstNode, AstToken, Direction, NodeOrToken, SyntaxElement, | 20 | AstNode, AstToken, Direction, NodeOrToken, |
23 | SyntaxKind::{self, *}, | 21 | SyntaxKind::*, |
24 | SyntaxNode, SyntaxToken, TextRange, WalkEvent, T, | 22 | SyntaxNode, TextRange, WalkEvent, T, |
25 | }; | 23 | }; |
26 | 24 | ||
27 | use crate::{ | 25 | use crate::{ |
28 | syntax_highlighting::{ | 26 | syntax_highlighting::{ |
29 | format::FormatStringHighlighter, macro_rules::MacroRulesHighlighter, tags::Highlight, | 27 | format::highlight_format_string, highlights::Highlights, |
28 | macro_rules::MacroRulesHighlighter, tags::Highlight, | ||
30 | }, | 29 | }, |
31 | FileId, HlMod, HlTag, SymbolKind, | 30 | FileId, HlMod, HlTag, SymbolKind, |
32 | }; | 31 | }; |
@@ -73,12 +72,22 @@ pub(crate) fn highlight( | |||
73 | } | 72 | } |
74 | }; | 73 | }; |
75 | 74 | ||
76 | let mut bindings_shadow_count: FxHashMap<Name, u32> = FxHashMap::default(); | ||
77 | let mut hl = highlights::Highlights::new(range_to_highlight); | 75 | let mut hl = highlights::Highlights::new(range_to_highlight); |
76 | traverse(&mut hl, &sema, &root, range_to_highlight, syntactic_name_ref_highlighting); | ||
77 | hl.to_vec() | ||
78 | } | ||
79 | |||
80 | fn traverse( | ||
81 | hl: &mut Highlights, | ||
82 | sema: &Semantics<RootDatabase>, | ||
83 | root: &SyntaxNode, | ||
84 | range_to_highlight: TextRange, | ||
85 | syntactic_name_ref_highlighting: bool, | ||
86 | ) { | ||
87 | let mut bindings_shadow_count: FxHashMap<Name, u32> = FxHashMap::default(); | ||
78 | 88 | ||
79 | let mut current_macro_call: Option<ast::MacroCall> = None; | 89 | let mut current_macro_call: Option<ast::MacroCall> = None; |
80 | let mut current_macro_rules: Option<ast::MacroRules> = None; | 90 | let mut current_macro_rules: Option<ast::MacroRules> = None; |
81 | let mut format_string_highlighter = FormatStringHighlighter::default(); | ||
82 | let mut macro_rules_highlighter = MacroRulesHighlighter::default(); | 91 | let mut macro_rules_highlighter = MacroRulesHighlighter::default(); |
83 | let mut inside_attribute = false; | 92 | let mut inside_attribute = false; |
84 | 93 | ||
@@ -110,7 +119,6 @@ pub(crate) fn highlight( | |||
110 | WalkEvent::Leave(Some(mc)) => { | 119 | WalkEvent::Leave(Some(mc)) => { |
111 | assert_eq!(current_macro_call, Some(mc)); | 120 | assert_eq!(current_macro_call, Some(mc)); |
112 | current_macro_call = None; | 121 | current_macro_call = None; |
113 | format_string_highlighter = FormatStringHighlighter::default(); | ||
114 | } | 122 | } |
115 | _ => (), | 123 | _ => (), |
116 | } | 124 | } |
@@ -128,26 +136,24 @@ pub(crate) fn highlight( | |||
128 | } | 136 | } |
129 | _ => (), | 137 | _ => (), |
130 | } | 138 | } |
131 | |||
132 | match &event { | 139 | match &event { |
133 | // Check for Rust code in documentation | ||
134 | WalkEvent::Leave(NodeOrToken::Node(node)) => { | ||
135 | if ast::Attr::can_cast(node.kind()) { | ||
136 | inside_attribute = false | ||
137 | } | ||
138 | if let Some((new_comments, inj)) = injection::extract_doc_comments(node) { | ||
139 | injection::highlight_doc_comment(new_comments, inj, &mut hl); | ||
140 | } | ||
141 | } | ||
142 | WalkEvent::Enter(NodeOrToken::Node(node)) if ast::Attr::can_cast(node.kind()) => { | 140 | WalkEvent::Enter(NodeOrToken::Node(node)) if ast::Attr::can_cast(node.kind()) => { |
143 | inside_attribute = true | 141 | inside_attribute = true |
144 | } | 142 | } |
143 | WalkEvent::Leave(NodeOrToken::Node(node)) if ast::Attr::can_cast(node.kind()) => { | ||
144 | inside_attribute = false | ||
145 | } | ||
145 | _ => (), | 146 | _ => (), |
146 | } | 147 | } |
147 | 148 | ||
148 | let element = match event { | 149 | let element = match event { |
149 | WalkEvent::Enter(it) => it, | 150 | WalkEvent::Enter(it) => it, |
150 | WalkEvent::Leave(_) => continue, | 151 | WalkEvent::Leave(it) => { |
152 | if let Some(node) = it.as_node() { | ||
153 | inject::doc_comment(hl, node); | ||
154 | } | ||
155 | continue; | ||
156 | } | ||
151 | }; | 157 | }; |
152 | 158 | ||
153 | let range = element.text_range(); | 159 | let range = element.text_range(); |
@@ -167,8 +173,6 @@ pub(crate) fn highlight( | |||
167 | let token = sema.descend_into_macros(token.clone()); | 173 | let token = sema.descend_into_macros(token.clone()); |
168 | let parent = token.parent(); | 174 | let parent = token.parent(); |
169 | 175 | ||
170 | format_string_highlighter.check_for_format_string(&parent); | ||
171 | |||
172 | // We only care Name and Name_ref | 176 | // We only care Name and Name_ref |
173 | match (token.kind(), parent.kind()) { | 177 | match (token.kind(), parent.kind()) { |
174 | (IDENT, NAME) | (IDENT, NAME_REF) => parent.into(), | 178 | (IDENT, NAME) | (IDENT, NAME_REF) => parent.into(), |
@@ -181,13 +185,17 @@ pub(crate) fn highlight( | |||
181 | if let Some(token) = element.as_token().cloned().and_then(ast::String::cast) { | 185 | if let Some(token) = element.as_token().cloned().and_then(ast::String::cast) { |
182 | if token.is_raw() { | 186 | if token.is_raw() { |
183 | let expanded = element_to_highlight.as_token().unwrap().clone(); | 187 | let expanded = element_to_highlight.as_token().unwrap().clone(); |
184 | if injection::highlight_injection(&mut hl, &sema, token, expanded).is_some() { | 188 | if inject::ra_fixture(hl, &sema, token, expanded).is_some() { |
185 | continue; | 189 | continue; |
186 | } | 190 | } |
187 | } | 191 | } |
188 | } | 192 | } |
189 | 193 | ||
190 | if let Some((mut highlight, binding_hash)) = highlight_element( | 194 | if let Some(_) = macro_rules_highlighter.highlight(element_to_highlight.clone()) { |
195 | continue; | ||
196 | } | ||
197 | |||
198 | if let Some((mut highlight, binding_hash)) = highlight::element( | ||
191 | &sema, | 199 | &sema, |
192 | &mut bindings_shadow_count, | 200 | &mut bindings_shadow_count, |
193 | syntactic_name_ref_highlighting, | 201 | syntactic_name_ref_highlighting, |
@@ -197,31 +205,25 @@ pub(crate) fn highlight( | |||
197 | highlight = highlight | HlMod::Attribute; | 205 | highlight = highlight | HlMod::Attribute; |
198 | } | 206 | } |
199 | 207 | ||
200 | if macro_rules_highlighter.highlight(element_to_highlight.clone()).is_none() { | 208 | hl.add(HlRange { range, highlight, binding_hash }); |
201 | hl.add(HlRange { range, highlight, binding_hash }); | 209 | } |
202 | } | ||
203 | 210 | ||
204 | if let Some(string) = | 211 | if let Some(string) = element_to_highlight.as_token().cloned().and_then(ast::String::cast) { |
205 | element_to_highlight.as_token().cloned().and_then(ast::String::cast) | 212 | highlight_format_string(hl, &string, range); |
206 | { | 213 | // Highlight escape sequences |
207 | format_string_highlighter.highlight_format_string(&mut hl, &string, range); | 214 | if let Some(char_ranges) = string.char_ranges() { |
208 | // Highlight escape sequences | 215 | for (piece_range, _) in char_ranges.iter().filter(|(_, char)| char.is_ok()) { |
209 | if let Some(char_ranges) = string.char_ranges() { | 216 | if string.text()[piece_range.start().into()..].starts_with('\\') { |
210 | for (piece_range, _) in char_ranges.iter().filter(|(_, char)| char.is_ok()) { | 217 | hl.add(HlRange { |
211 | if string.text()[piece_range.start().into()..].starts_with('\\') { | 218 | range: piece_range + range.start(), |
212 | hl.add(HlRange { | 219 | highlight: HlTag::EscapeSequence.into(), |
213 | range: piece_range + range.start(), | 220 | binding_hash: None, |
214 | highlight: HlTag::EscapeSequence.into(), | 221 | }); |
215 | binding_hash: None, | ||
216 | }); | ||
217 | } | ||
218 | } | 222 | } |
219 | } | 223 | } |
220 | } | 224 | } |
221 | } | 225 | } |
222 | } | 226 | } |
223 | |||
224 | hl.to_vec() | ||
225 | } | 227 | } |
226 | 228 | ||
227 | fn macro_call_range(macro_call: &ast::MacroCall) -> Option<TextRange> { | 229 | fn macro_call_range(macro_call: &ast::MacroCall) -> Option<TextRange> { |
@@ -239,505 +241,3 @@ fn macro_call_range(macro_call: &ast::MacroCall) -> Option<TextRange> { | |||
239 | 241 | ||
240 | Some(TextRange::new(range_start, range_end)) | 242 | Some(TextRange::new(range_start, range_end)) |
241 | } | 243 | } |
242 | |||
243 | /// Returns true if the parent nodes of `node` all match the `SyntaxKind`s in `kinds` exactly. | ||
244 | fn parents_match(mut node: NodeOrToken<SyntaxNode, SyntaxToken>, mut kinds: &[SyntaxKind]) -> bool { | ||
245 | while let (Some(parent), [kind, rest @ ..]) = (&node.parent(), kinds) { | ||
246 | if parent.kind() != *kind { | ||
247 | return false; | ||
248 | } | ||
249 | |||
250 | // FIXME: Would be nice to get parent out of the match, but binding by-move and by-value | ||
251 | // in the same pattern is unstable: rust-lang/rust#68354. | ||
252 | node = node.parent().unwrap().into(); | ||
253 | kinds = rest; | ||
254 | } | ||
255 | |||
256 | // Only true if we matched all expected kinds | ||
257 | kinds.len() == 0 | ||
258 | } | ||
259 | |||
260 | fn is_consumed_lvalue( | ||
261 | node: NodeOrToken<SyntaxNode, SyntaxToken>, | ||
262 | local: &Local, | ||
263 | db: &RootDatabase, | ||
264 | ) -> bool { | ||
265 | // When lvalues are passed as arguments and they're not Copy, then mark them as Consuming. | ||
266 | parents_match(node, &[PATH_SEGMENT, PATH, PATH_EXPR, ARG_LIST]) && !local.ty(db).is_copy(db) | ||
267 | } | ||
268 | |||
269 | fn highlight_element( | ||
270 | sema: &Semantics<RootDatabase>, | ||
271 | bindings_shadow_count: &mut FxHashMap<Name, u32>, | ||
272 | syntactic_name_ref_highlighting: bool, | ||
273 | element: SyntaxElement, | ||
274 | ) -> Option<(Highlight, Option<u64>)> { | ||
275 | let db = sema.db; | ||
276 | let mut binding_hash = None; | ||
277 | let highlight: Highlight = match element.kind() { | ||
278 | FN => { | ||
279 | bindings_shadow_count.clear(); | ||
280 | return None; | ||
281 | } | ||
282 | |||
283 | // Highlight definitions depending on the "type" of the definition. | ||
284 | NAME => { | ||
285 | let name = element.into_node().and_then(ast::Name::cast).unwrap(); | ||
286 | let name_kind = NameClass::classify(sema, &name); | ||
287 | |||
288 | if let Some(NameClass::Definition(Definition::Local(local))) = &name_kind { | ||
289 | if let Some(name) = local.name(db) { | ||
290 | let shadow_count = bindings_shadow_count.entry(name.clone()).or_default(); | ||
291 | *shadow_count += 1; | ||
292 | binding_hash = Some(calc_binding_hash(&name, *shadow_count)) | ||
293 | } | ||
294 | }; | ||
295 | |||
296 | match name_kind { | ||
297 | Some(NameClass::ExternCrate(_)) => HlTag::Symbol(SymbolKind::Module).into(), | ||
298 | Some(NameClass::Definition(def)) => highlight_def(db, def) | HlMod::Definition, | ||
299 | Some(NameClass::ConstReference(def)) => highlight_def(db, def), | ||
300 | Some(NameClass::PatFieldShorthand { field_ref, .. }) => { | ||
301 | let mut h = HlTag::Symbol(SymbolKind::Field).into(); | ||
302 | if let Definition::Field(field) = field_ref { | ||
303 | if let VariantDef::Union(_) = field.parent_def(db) { | ||
304 | h |= HlMod::Unsafe; | ||
305 | } | ||
306 | } | ||
307 | |||
308 | h | ||
309 | } | ||
310 | None => highlight_name_by_syntax(name) | HlMod::Definition, | ||
311 | } | ||
312 | } | ||
313 | |||
314 | // Highlight references like the definitions they resolve to | ||
315 | NAME_REF if element.ancestors().any(|it| it.kind() == ATTR) => { | ||
316 | // even though we track whether we are in an attribute or not we still need this special case | ||
317 | // as otherwise we would emit unresolved references for name refs inside attributes | ||
318 | Highlight::from(HlTag::Symbol(SymbolKind::Function)) | ||
319 | } | ||
320 | NAME_REF => { | ||
321 | let name_ref = element.into_node().and_then(ast::NameRef::cast).unwrap(); | ||
322 | highlight_func_by_name_ref(sema, &name_ref).unwrap_or_else(|| { | ||
323 | match NameRefClass::classify(sema, &name_ref) { | ||
324 | Some(name_kind) => match name_kind { | ||
325 | NameRefClass::ExternCrate(_) => HlTag::Symbol(SymbolKind::Module).into(), | ||
326 | NameRefClass::Definition(def) => { | ||
327 | if let Definition::Local(local) = &def { | ||
328 | if let Some(name) = local.name(db) { | ||
329 | let shadow_count = | ||
330 | bindings_shadow_count.entry(name.clone()).or_default(); | ||
331 | binding_hash = Some(calc_binding_hash(&name, *shadow_count)) | ||
332 | } | ||
333 | }; | ||
334 | |||
335 | let mut h = highlight_def(db, def); | ||
336 | |||
337 | if let Definition::Local(local) = &def { | ||
338 | if is_consumed_lvalue(name_ref.syntax().clone().into(), local, db) { | ||
339 | h |= HlMod::Consuming; | ||
340 | } | ||
341 | } | ||
342 | |||
343 | if let Some(parent) = name_ref.syntax().parent() { | ||
344 | if matches!(parent.kind(), FIELD_EXPR | RECORD_PAT_FIELD) { | ||
345 | if let Definition::Field(field) = def { | ||
346 | if let VariantDef::Union(_) = field.parent_def(db) { | ||
347 | h |= HlMod::Unsafe; | ||
348 | } | ||
349 | } | ||
350 | } | ||
351 | } | ||
352 | |||
353 | h | ||
354 | } | ||
355 | NameRefClass::FieldShorthand { .. } => { | ||
356 | HlTag::Symbol(SymbolKind::Field).into() | ||
357 | } | ||
358 | }, | ||
359 | None if syntactic_name_ref_highlighting => { | ||
360 | highlight_name_ref_by_syntax(name_ref, sema) | ||
361 | } | ||
362 | None => HlTag::UnresolvedReference.into(), | ||
363 | } | ||
364 | }) | ||
365 | } | ||
366 | |||
367 | // Simple token-based highlighting | ||
368 | COMMENT => { | ||
369 | let comment = element.into_token().and_then(ast::Comment::cast)?; | ||
370 | let h = HlTag::Comment; | ||
371 | match comment.kind().doc { | ||
372 | Some(_) => h | HlMod::Documentation, | ||
373 | None => h.into(), | ||
374 | } | ||
375 | } | ||
376 | STRING | BYTE_STRING => HlTag::StringLiteral.into(), | ||
377 | ATTR => HlTag::Attribute.into(), | ||
378 | INT_NUMBER | FLOAT_NUMBER => HlTag::NumericLiteral.into(), | ||
379 | BYTE => HlTag::ByteLiteral.into(), | ||
380 | CHAR => HlTag::CharLiteral.into(), | ||
381 | QUESTION => Highlight::new(HlTag::Operator) | HlMod::ControlFlow, | ||
382 | LIFETIME => { | ||
383 | let lifetime = element.into_node().and_then(ast::Lifetime::cast).unwrap(); | ||
384 | |||
385 | match NameClass::classify_lifetime(sema, &lifetime) { | ||
386 | Some(NameClass::Definition(def)) => highlight_def(db, def) | HlMod::Definition, | ||
387 | None => match NameRefClass::classify_lifetime(sema, &lifetime) { | ||
388 | Some(NameRefClass::Definition(def)) => highlight_def(db, def), | ||
389 | _ => Highlight::new(HlTag::Symbol(SymbolKind::LifetimeParam)), | ||
390 | }, | ||
391 | _ => Highlight::new(HlTag::Symbol(SymbolKind::LifetimeParam)) | HlMod::Definition, | ||
392 | } | ||
393 | } | ||
394 | p if p.is_punct() => match p { | ||
395 | T![&] => { | ||
396 | let h = HlTag::Operator.into(); | ||
397 | let is_unsafe = element | ||
398 | .parent() | ||
399 | .and_then(ast::RefExpr::cast) | ||
400 | .map(|ref_expr| sema.is_unsafe_ref_expr(&ref_expr)) | ||
401 | .unwrap_or(false); | ||
402 | if is_unsafe { | ||
403 | h | HlMod::Unsafe | ||
404 | } else { | ||
405 | h | ||
406 | } | ||
407 | } | ||
408 | T![::] | T![->] | T![=>] | T![..] | T![=] | T![@] | T![.] => HlTag::Operator.into(), | ||
409 | T![!] if element.parent().and_then(ast::MacroCall::cast).is_some() => { | ||
410 | HlTag::Symbol(SymbolKind::Macro).into() | ||
411 | } | ||
412 | T![!] if element.parent().and_then(ast::NeverType::cast).is_some() => { | ||
413 | HlTag::BuiltinType.into() | ||
414 | } | ||
415 | T![*] if element.parent().and_then(ast::PtrType::cast).is_some() => { | ||
416 | HlTag::Keyword.into() | ||
417 | } | ||
418 | T![*] if element.parent().and_then(ast::PrefixExpr::cast).is_some() => { | ||
419 | let prefix_expr = element.parent().and_then(ast::PrefixExpr::cast)?; | ||
420 | |||
421 | let expr = prefix_expr.expr()?; | ||
422 | let ty = sema.type_of_expr(&expr)?; | ||
423 | if ty.is_raw_ptr() { | ||
424 | HlTag::Operator | HlMod::Unsafe | ||
425 | } else if let Some(ast::PrefixOp::Deref) = prefix_expr.op_kind() { | ||
426 | HlTag::Operator.into() | ||
427 | } else { | ||
428 | HlTag::Punctuation.into() | ||
429 | } | ||
430 | } | ||
431 | T![-] if element.parent().and_then(ast::PrefixExpr::cast).is_some() => { | ||
432 | let prefix_expr = element.parent().and_then(ast::PrefixExpr::cast)?; | ||
433 | |||
434 | let expr = prefix_expr.expr()?; | ||
435 | match expr { | ||
436 | ast::Expr::Literal(_) => HlTag::NumericLiteral, | ||
437 | _ => HlTag::Operator, | ||
438 | } | ||
439 | .into() | ||
440 | } | ||
441 | _ if element.parent().and_then(ast::PrefixExpr::cast).is_some() => { | ||
442 | HlTag::Operator.into() | ||
443 | } | ||
444 | _ if element.parent().and_then(ast::BinExpr::cast).is_some() => HlTag::Operator.into(), | ||
445 | _ if element.parent().and_then(ast::RangeExpr::cast).is_some() => { | ||
446 | HlTag::Operator.into() | ||
447 | } | ||
448 | _ if element.parent().and_then(ast::RangePat::cast).is_some() => HlTag::Operator.into(), | ||
449 | _ if element.parent().and_then(ast::RestPat::cast).is_some() => HlTag::Operator.into(), | ||
450 | _ if element.parent().and_then(ast::Attr::cast).is_some() => HlTag::Attribute.into(), | ||
451 | _ => HlTag::Punctuation.into(), | ||
452 | }, | ||
453 | |||
454 | k if k.is_keyword() => { | ||
455 | let h = Highlight::new(HlTag::Keyword); | ||
456 | match k { | ||
457 | T![break] | ||
458 | | T![continue] | ||
459 | | T![else] | ||
460 | | T![if] | ||
461 | | T![loop] | ||
462 | | T![match] | ||
463 | | T![return] | ||
464 | | T![while] | ||
465 | | T![in] => h | HlMod::ControlFlow, | ||
466 | T![for] if !is_child_of_impl(&element) => h | HlMod::ControlFlow, | ||
467 | T![unsafe] => h | HlMod::Unsafe, | ||
468 | T![true] | T![false] => HlTag::BoolLiteral.into(), | ||
469 | T![self] => { | ||
470 | let self_param_is_mut = element | ||
471 | .parent() | ||
472 | .and_then(ast::SelfParam::cast) | ||
473 | .and_then(|p| p.mut_token()) | ||
474 | .is_some(); | ||
475 | let self_path = &element | ||
476 | .parent() | ||
477 | .as_ref() | ||
478 | .and_then(SyntaxNode::parent) | ||
479 | .and_then(ast::Path::cast) | ||
480 | .and_then(|p| sema.resolve_path(&p)); | ||
481 | let mut h = HlTag::Symbol(SymbolKind::SelfParam).into(); | ||
482 | if self_param_is_mut | ||
483 | || matches!(self_path, | ||
484 | Some(hir::PathResolution::Local(local)) | ||
485 | if local.is_self(db) | ||
486 | && (local.is_mut(db) || local.ty(db).is_mutable_reference()) | ||
487 | ) | ||
488 | { | ||
489 | h |= HlMod::Mutable | ||
490 | } | ||
491 | |||
492 | if let Some(hir::PathResolution::Local(local)) = self_path { | ||
493 | if is_consumed_lvalue(element, &local, db) { | ||
494 | h |= HlMod::Consuming; | ||
495 | } | ||
496 | } | ||
497 | |||
498 | h | ||
499 | } | ||
500 | T![ref] => element | ||
501 | .parent() | ||
502 | .and_then(ast::IdentPat::cast) | ||
503 | .and_then(|ident_pat| { | ||
504 | if sema.is_unsafe_ident_pat(&ident_pat) { | ||
505 | Some(HlMod::Unsafe) | ||
506 | } else { | ||
507 | None | ||
508 | } | ||
509 | }) | ||
510 | .map(|modifier| h | modifier) | ||
511 | .unwrap_or(h), | ||
512 | _ => h, | ||
513 | } | ||
514 | } | ||
515 | |||
516 | _ => return None, | ||
517 | }; | ||
518 | |||
519 | return Some((highlight, binding_hash)); | ||
520 | |||
521 | fn calc_binding_hash(name: &Name, shadow_count: u32) -> u64 { | ||
522 | fn hash<T: std::hash::Hash + std::fmt::Debug>(x: T) -> u64 { | ||
523 | use std::{collections::hash_map::DefaultHasher, hash::Hasher}; | ||
524 | |||
525 | let mut hasher = DefaultHasher::new(); | ||
526 | x.hash(&mut hasher); | ||
527 | hasher.finish() | ||
528 | } | ||
529 | |||
530 | hash((name, shadow_count)) | ||
531 | } | ||
532 | } | ||
533 | |||
534 | fn is_child_of_impl(element: &SyntaxElement) -> bool { | ||
535 | match element.parent() { | ||
536 | Some(e) => e.kind() == IMPL, | ||
537 | _ => false, | ||
538 | } | ||
539 | } | ||
540 | |||
541 | fn highlight_func_by_name_ref( | ||
542 | sema: &Semantics<RootDatabase>, | ||
543 | name_ref: &ast::NameRef, | ||
544 | ) -> Option<Highlight> { | ||
545 | let method_call = name_ref.syntax().parent().and_then(ast::MethodCallExpr::cast)?; | ||
546 | highlight_method_call(sema, &method_call) | ||
547 | } | ||
548 | |||
549 | fn highlight_method_call( | ||
550 | sema: &Semantics<RootDatabase>, | ||
551 | method_call: &ast::MethodCallExpr, | ||
552 | ) -> Option<Highlight> { | ||
553 | let func = sema.resolve_method_call(&method_call)?; | ||
554 | let mut h = HlTag::Symbol(SymbolKind::Function).into(); | ||
555 | h |= HlMod::Associated; | ||
556 | if func.is_unsafe(sema.db) || sema.is_unsafe_method_call(&method_call) { | ||
557 | h |= HlMod::Unsafe; | ||
558 | } | ||
559 | if let Some(self_param) = func.self_param(sema.db) { | ||
560 | match self_param.access(sema.db) { | ||
561 | hir::Access::Shared => (), | ||
562 | hir::Access::Exclusive => h |= HlMod::Mutable, | ||
563 | hir::Access::Owned => { | ||
564 | if let Some(receiver_ty) = | ||
565 | method_call.receiver().and_then(|it| sema.type_of_expr(&it)) | ||
566 | { | ||
567 | if !receiver_ty.is_copy(sema.db) { | ||
568 | h |= HlMod::Consuming | ||
569 | } | ||
570 | } | ||
571 | } | ||
572 | } | ||
573 | } | ||
574 | Some(h) | ||
575 | } | ||
576 | |||
577 | fn highlight_def(db: &RootDatabase, def: Definition) -> Highlight { | ||
578 | match def { | ||
579 | Definition::Macro(_) => HlTag::Symbol(SymbolKind::Macro), | ||
580 | Definition::Field(_) => HlTag::Symbol(SymbolKind::Field), | ||
581 | Definition::ModuleDef(def) => match def { | ||
582 | hir::ModuleDef::Module(_) => HlTag::Symbol(SymbolKind::Module), | ||
583 | hir::ModuleDef::Function(func) => { | ||
584 | let mut h = Highlight::new(HlTag::Symbol(SymbolKind::Function)); | ||
585 | if func.as_assoc_item(db).is_some() { | ||
586 | h |= HlMod::Associated; | ||
587 | if func.self_param(db).is_none() { | ||
588 | h |= HlMod::Static | ||
589 | } | ||
590 | } | ||
591 | if func.is_unsafe(db) { | ||
592 | h |= HlMod::Unsafe; | ||
593 | } | ||
594 | return h; | ||
595 | } | ||
596 | hir::ModuleDef::Adt(hir::Adt::Struct(_)) => HlTag::Symbol(SymbolKind::Struct), | ||
597 | hir::ModuleDef::Adt(hir::Adt::Enum(_)) => HlTag::Symbol(SymbolKind::Enum), | ||
598 | hir::ModuleDef::Adt(hir::Adt::Union(_)) => HlTag::Symbol(SymbolKind::Union), | ||
599 | hir::ModuleDef::Variant(_) => HlTag::Symbol(SymbolKind::Variant), | ||
600 | hir::ModuleDef::Const(konst) => { | ||
601 | let mut h = Highlight::new(HlTag::Symbol(SymbolKind::Const)); | ||
602 | if konst.as_assoc_item(db).is_some() { | ||
603 | h |= HlMod::Associated | ||
604 | } | ||
605 | return h; | ||
606 | } | ||
607 | hir::ModuleDef::Trait(_) => HlTag::Symbol(SymbolKind::Trait), | ||
608 | hir::ModuleDef::TypeAlias(type_) => { | ||
609 | let mut h = Highlight::new(HlTag::Symbol(SymbolKind::TypeAlias)); | ||
610 | if type_.as_assoc_item(db).is_some() { | ||
611 | h |= HlMod::Associated | ||
612 | } | ||
613 | return h; | ||
614 | } | ||
615 | hir::ModuleDef::BuiltinType(_) => HlTag::BuiltinType, | ||
616 | hir::ModuleDef::Static(s) => { | ||
617 | let mut h = Highlight::new(HlTag::Symbol(SymbolKind::Static)); | ||
618 | if s.is_mut(db) { | ||
619 | h |= HlMod::Mutable; | ||
620 | h |= HlMod::Unsafe; | ||
621 | } | ||
622 | return h; | ||
623 | } | ||
624 | }, | ||
625 | Definition::SelfType(_) => HlTag::Symbol(SymbolKind::Impl), | ||
626 | Definition::TypeParam(_) => HlTag::Symbol(SymbolKind::TypeParam), | ||
627 | Definition::ConstParam(_) => HlTag::Symbol(SymbolKind::ConstParam), | ||
628 | Definition::Local(local) => { | ||
629 | let tag = if local.is_param(db) { | ||
630 | HlTag::Symbol(SymbolKind::ValueParam) | ||
631 | } else { | ||
632 | HlTag::Symbol(SymbolKind::Local) | ||
633 | }; | ||
634 | let mut h = Highlight::new(tag); | ||
635 | if local.is_mut(db) || local.ty(db).is_mutable_reference() { | ||
636 | h |= HlMod::Mutable; | ||
637 | } | ||
638 | if local.ty(db).as_callable(db).is_some() || local.ty(db).impls_fnonce(db) { | ||
639 | h |= HlMod::Callable; | ||
640 | } | ||
641 | return h; | ||
642 | } | ||
643 | Definition::LifetimeParam(_) => HlTag::Symbol(SymbolKind::LifetimeParam), | ||
644 | Definition::Label(_) => HlTag::Symbol(SymbolKind::Label), | ||
645 | } | ||
646 | .into() | ||
647 | } | ||
648 | |||
649 | fn highlight_name_by_syntax(name: ast::Name) -> Highlight { | ||
650 | let default = HlTag::UnresolvedReference; | ||
651 | |||
652 | let parent = match name.syntax().parent() { | ||
653 | Some(it) => it, | ||
654 | _ => return default.into(), | ||
655 | }; | ||
656 | |||
657 | let tag = match parent.kind() { | ||
658 | STRUCT => HlTag::Symbol(SymbolKind::Struct), | ||
659 | ENUM => HlTag::Symbol(SymbolKind::Enum), | ||
660 | VARIANT => HlTag::Symbol(SymbolKind::Variant), | ||
661 | UNION => HlTag::Symbol(SymbolKind::Union), | ||
662 | TRAIT => HlTag::Symbol(SymbolKind::Trait), | ||
663 | TYPE_ALIAS => HlTag::Symbol(SymbolKind::TypeAlias), | ||
664 | TYPE_PARAM => HlTag::Symbol(SymbolKind::TypeParam), | ||
665 | RECORD_FIELD => HlTag::Symbol(SymbolKind::Field), | ||
666 | MODULE => HlTag::Symbol(SymbolKind::Module), | ||
667 | FN => HlTag::Symbol(SymbolKind::Function), | ||
668 | CONST => HlTag::Symbol(SymbolKind::Const), | ||
669 | STATIC => HlTag::Symbol(SymbolKind::Static), | ||
670 | IDENT_PAT => HlTag::Symbol(SymbolKind::Local), | ||
671 | _ => default, | ||
672 | }; | ||
673 | |||
674 | tag.into() | ||
675 | } | ||
676 | |||
677 | fn highlight_name_ref_by_syntax(name: ast::NameRef, sema: &Semantics<RootDatabase>) -> Highlight { | ||
678 | let default = HlTag::UnresolvedReference; | ||
679 | |||
680 | let parent = match name.syntax().parent() { | ||
681 | Some(it) => it, | ||
682 | _ => return default.into(), | ||
683 | }; | ||
684 | |||
685 | match parent.kind() { | ||
686 | METHOD_CALL_EXPR => { | ||
687 | return ast::MethodCallExpr::cast(parent) | ||
688 | .and_then(|method_call| highlight_method_call(sema, &method_call)) | ||
689 | .unwrap_or_else(|| HlTag::Symbol(SymbolKind::Function).into()); | ||
690 | } | ||
691 | FIELD_EXPR => { | ||
692 | let h = HlTag::Symbol(SymbolKind::Field); | ||
693 | let is_union = ast::FieldExpr::cast(parent) | ||
694 | .and_then(|field_expr| { | ||
695 | let field = sema.resolve_field(&field_expr)?; | ||
696 | Some(if let VariantDef::Union(_) = field.parent_def(sema.db) { | ||
697 | true | ||
698 | } else { | ||
699 | false | ||
700 | }) | ||
701 | }) | ||
702 | .unwrap_or(false); | ||
703 | if is_union { | ||
704 | h | HlMod::Unsafe | ||
705 | } else { | ||
706 | h.into() | ||
707 | } | ||
708 | } | ||
709 | PATH_SEGMENT => { | ||
710 | let path = match parent.parent().and_then(ast::Path::cast) { | ||
711 | Some(it) => it, | ||
712 | _ => return default.into(), | ||
713 | }; | ||
714 | let expr = match path.syntax().parent().and_then(ast::PathExpr::cast) { | ||
715 | Some(it) => it, | ||
716 | _ => { | ||
717 | // within path, decide whether it is module or adt by checking for uppercase name | ||
718 | return if name.text().chars().next().unwrap_or_default().is_uppercase() { | ||
719 | HlTag::Symbol(SymbolKind::Struct) | ||
720 | } else { | ||
721 | HlTag::Symbol(SymbolKind::Module) | ||
722 | } | ||
723 | .into(); | ||
724 | } | ||
725 | }; | ||
726 | let parent = match expr.syntax().parent() { | ||
727 | Some(it) => it, | ||
728 | None => return default.into(), | ||
729 | }; | ||
730 | |||
731 | match parent.kind() { | ||
732 | CALL_EXPR => HlTag::Symbol(SymbolKind::Function).into(), | ||
733 | _ => if name.text().chars().next().unwrap_or_default().is_uppercase() { | ||
734 | HlTag::Symbol(SymbolKind::Struct) | ||
735 | } else { | ||
736 | HlTag::Symbol(SymbolKind::Const) | ||
737 | } | ||
738 | .into(), | ||
739 | } | ||
740 | } | ||
741 | _ => default.into(), | ||
742 | } | ||
743 | } | ||
diff --git a/crates/ide/src/syntax_highlighting/format.rs b/crates/ide/src/syntax_highlighting/format.rs index d807ad0ad..a74ca844b 100644 --- a/crates/ide/src/syntax_highlighting/format.rs +++ b/crates/ide/src/syntax_highlighting/format.rs | |||
@@ -1,60 +1,48 @@ | |||
1 | //! Syntax highlighting for format macro strings. | 1 | //! Syntax highlighting for format macro strings. |
2 | use syntax::{ | 2 | use syntax::{ |
3 | ast::{self, FormatSpecifier, HasFormatSpecifier}, | 3 | ast::{self, FormatSpecifier, HasFormatSpecifier}, |
4 | AstNode, AstToken, SyntaxElement, SyntaxKind, SyntaxNode, TextRange, | 4 | AstNode, AstToken, TextRange, |
5 | }; | 5 | }; |
6 | 6 | ||
7 | use crate::{HlRange, HlTag, SymbolKind}; | 7 | use crate::{syntax_highlighting::highlights::Highlights, HlRange, HlTag, SymbolKind}; |
8 | 8 | ||
9 | use super::highlights::Highlights; | 9 | pub(super) fn highlight_format_string( |
10 | stack: &mut Highlights, | ||
11 | string: &ast::String, | ||
12 | range: TextRange, | ||
13 | ) { | ||
14 | if is_format_string(string).is_none() { | ||
15 | return; | ||
16 | } | ||
10 | 17 | ||
11 | #[derive(Default)] | 18 | string.lex_format_specifier(|piece_range, kind| { |
12 | pub(super) struct FormatStringHighlighter { | 19 | if let Some(highlight) = highlight_format_specifier(kind) { |
13 | format_string: Option<SyntaxElement>, | 20 | stack.add(HlRange { |
21 | range: piece_range + range.start(), | ||
22 | highlight: highlight.into(), | ||
23 | binding_hash: None, | ||
24 | }); | ||
25 | } | ||
26 | }); | ||
14 | } | 27 | } |
15 | 28 | ||
16 | impl FormatStringHighlighter { | 29 | fn is_format_string(string: &ast::String) -> Option<()> { |
17 | pub(super) fn check_for_format_string(&mut self, parent: &SyntaxNode) { | 30 | let parent = string.syntax().parent(); |
18 | // Check if macro takes a format string and remember it for highlighting later. | 31 | |
19 | // The macros that accept a format string expand to a compiler builtin macros | 32 | let name = parent.parent().and_then(ast::MacroCall::cast)?.path()?.segment()?.name_ref()?; |
20 | // `format_args` and `format_args_nl`. | 33 | if !matches!(name.text().as_str(), "format_args" | "format_args_nl") { |
21 | if let Some(name) = parent | 34 | return None; |
22 | .parent() | ||
23 | .and_then(ast::MacroCall::cast) | ||
24 | .and_then(|mc| mc.path()) | ||
25 | .and_then(|p| p.segment()) | ||
26 | .and_then(|s| s.name_ref()) | ||
27 | { | ||
28 | match name.text().as_str() { | ||
29 | "format_args" | "format_args_nl" => { | ||
30 | self.format_string = parent | ||
31 | .children_with_tokens() | ||
32 | .filter(|t| t.kind() != SyntaxKind::WHITESPACE) | ||
33 | .nth(1) | ||
34 | .filter(|e| ast::String::can_cast(e.kind())) | ||
35 | } | ||
36 | _ => {} | ||
37 | } | ||
38 | } | ||
39 | } | 35 | } |
40 | pub(super) fn highlight_format_string( | 36 | |
41 | &self, | 37 | let first_literal = parent |
42 | stack: &mut Highlights, | 38 | .children_with_tokens() |
43 | string: &impl HasFormatSpecifier, | 39 | .filter_map(|it| it.as_token().cloned().and_then(ast::String::cast)) |
44 | range: TextRange, | 40 | .next()?; |
45 | ) { | 41 | if &first_literal != string { |
46 | if self.format_string.as_ref() == Some(&SyntaxElement::from(string.syntax().clone())) { | 42 | return None; |
47 | string.lex_format_specifier(|piece_range, kind| { | ||
48 | if let Some(highlight) = highlight_format_specifier(kind) { | ||
49 | stack.add(HlRange { | ||
50 | range: piece_range + range.start(), | ||
51 | highlight: highlight.into(), | ||
52 | binding_hash: None, | ||
53 | }); | ||
54 | } | ||
55 | }); | ||
56 | } | ||
57 | } | 43 | } |
44 | |||
45 | Some(()) | ||
58 | } | 46 | } |
59 | 47 | ||
60 | fn highlight_format_specifier(kind: FormatSpecifier) -> Option<HlTag> { | 48 | fn highlight_format_specifier(kind: FormatSpecifier) -> Option<HlTag> { |
@@ -70,7 +58,9 @@ fn highlight_format_specifier(kind: FormatSpecifier) -> Option<HlTag> { | |||
70 | | FormatSpecifier::Dot | 58 | | FormatSpecifier::Dot |
71 | | FormatSpecifier::Asterisk | 59 | | FormatSpecifier::Asterisk |
72 | | FormatSpecifier::QuestionMark => HlTag::FormatSpecifier, | 60 | | FormatSpecifier::QuestionMark => HlTag::FormatSpecifier, |
61 | |||
73 | FormatSpecifier::Integer | FormatSpecifier::Zero => HlTag::NumericLiteral, | 62 | FormatSpecifier::Integer | FormatSpecifier::Zero => HlTag::NumericLiteral, |
63 | |||
74 | FormatSpecifier::Identifier => HlTag::Symbol(SymbolKind::Local), | 64 | FormatSpecifier::Identifier => HlTag::Symbol(SymbolKind::Local), |
75 | }) | 65 | }) |
76 | } | 66 | } |
diff --git a/crates/ide/src/syntax_highlighting/highlight.rs b/crates/ide/src/syntax_highlighting/highlight.rs new file mode 100644 index 000000000..34bae49a8 --- /dev/null +++ b/crates/ide/src/syntax_highlighting/highlight.rs | |||
@@ -0,0 +1,530 @@ | |||
1 | //! Computes color for a single element. | ||
2 | |||
3 | use hir::{AsAssocItem, Semantics, VariantDef}; | ||
4 | use ide_db::{ | ||
5 | defs::{Definition, NameClass, NameRefClass}, | ||
6 | RootDatabase, | ||
7 | }; | ||
8 | use rustc_hash::FxHashMap; | ||
9 | use syntax::{ | ||
10 | ast, AstNode, AstToken, NodeOrToken, SyntaxElement, | ||
11 | SyntaxKind::{self, *}, | ||
12 | SyntaxNode, SyntaxToken, T, | ||
13 | }; | ||
14 | |||
15 | use crate::{syntax_highlighting::tags::HlPunct, Highlight, HlMod, HlTag, SymbolKind}; | ||
16 | |||
17 | pub(super) fn element( | ||
18 | sema: &Semantics<RootDatabase>, | ||
19 | bindings_shadow_count: &mut FxHashMap<hir::Name, u32>, | ||
20 | syntactic_name_ref_highlighting: bool, | ||
21 | element: SyntaxElement, | ||
22 | ) -> Option<(Highlight, Option<u64>)> { | ||
23 | let db = sema.db; | ||
24 | let mut binding_hash = None; | ||
25 | let highlight: Highlight = match element.kind() { | ||
26 | FN => { | ||
27 | bindings_shadow_count.clear(); | ||
28 | return None; | ||
29 | } | ||
30 | |||
31 | // Highlight definitions depending on the "type" of the definition. | ||
32 | NAME => { | ||
33 | let name = element.into_node().and_then(ast::Name::cast).unwrap(); | ||
34 | let name_kind = NameClass::classify(sema, &name); | ||
35 | |||
36 | if let Some(NameClass::Definition(Definition::Local(local))) = &name_kind { | ||
37 | if let Some(name) = local.name(db) { | ||
38 | let shadow_count = bindings_shadow_count.entry(name.clone()).or_default(); | ||
39 | *shadow_count += 1; | ||
40 | binding_hash = Some(calc_binding_hash(&name, *shadow_count)) | ||
41 | } | ||
42 | }; | ||
43 | |||
44 | match name_kind { | ||
45 | Some(NameClass::ExternCrate(_)) => HlTag::Symbol(SymbolKind::Module).into(), | ||
46 | Some(NameClass::Definition(def)) => highlight_def(db, def) | HlMod::Definition, | ||
47 | Some(NameClass::ConstReference(def)) => highlight_def(db, def), | ||
48 | Some(NameClass::PatFieldShorthand { field_ref, .. }) => { | ||
49 | let mut h = HlTag::Symbol(SymbolKind::Field).into(); | ||
50 | if let Definition::Field(field) = field_ref { | ||
51 | if let VariantDef::Union(_) = field.parent_def(db) { | ||
52 | h |= HlMod::Unsafe; | ||
53 | } | ||
54 | } | ||
55 | |||
56 | h | ||
57 | } | ||
58 | None => highlight_name_by_syntax(name) | HlMod::Definition, | ||
59 | } | ||
60 | } | ||
61 | |||
62 | // Highlight references like the definitions they resolve to | ||
63 | NAME_REF if element.ancestors().any(|it| it.kind() == ATTR) => { | ||
64 | // even though we track whether we are in an attribute or not we still need this special case | ||
65 | // as otherwise we would emit unresolved references for name refs inside attributes | ||
66 | Highlight::from(HlTag::Symbol(SymbolKind::Function)) | ||
67 | } | ||
68 | NAME_REF => { | ||
69 | let name_ref = element.into_node().and_then(ast::NameRef::cast).unwrap(); | ||
70 | highlight_func_by_name_ref(sema, &name_ref).unwrap_or_else(|| { | ||
71 | match NameRefClass::classify(sema, &name_ref) { | ||
72 | Some(name_kind) => match name_kind { | ||
73 | NameRefClass::ExternCrate(_) => HlTag::Symbol(SymbolKind::Module).into(), | ||
74 | NameRefClass::Definition(def) => { | ||
75 | if let Definition::Local(local) = &def { | ||
76 | if let Some(name) = local.name(db) { | ||
77 | let shadow_count = | ||
78 | bindings_shadow_count.entry(name.clone()).or_default(); | ||
79 | binding_hash = Some(calc_binding_hash(&name, *shadow_count)) | ||
80 | } | ||
81 | }; | ||
82 | |||
83 | let mut h = highlight_def(db, def); | ||
84 | |||
85 | if let Definition::Local(local) = &def { | ||
86 | if is_consumed_lvalue(name_ref.syntax().clone().into(), local, db) { | ||
87 | h |= HlMod::Consuming; | ||
88 | } | ||
89 | } | ||
90 | |||
91 | if let Some(parent) = name_ref.syntax().parent() { | ||
92 | if matches!(parent.kind(), FIELD_EXPR | RECORD_PAT_FIELD) { | ||
93 | if let Definition::Field(field) = def { | ||
94 | if let VariantDef::Union(_) = field.parent_def(db) { | ||
95 | h |= HlMod::Unsafe; | ||
96 | } | ||
97 | } | ||
98 | } | ||
99 | } | ||
100 | |||
101 | h | ||
102 | } | ||
103 | NameRefClass::FieldShorthand { .. } => { | ||
104 | HlTag::Symbol(SymbolKind::Field).into() | ||
105 | } | ||
106 | }, | ||
107 | None if syntactic_name_ref_highlighting => { | ||
108 | highlight_name_ref_by_syntax(name_ref, sema) | ||
109 | } | ||
110 | None => HlTag::UnresolvedReference.into(), | ||
111 | } | ||
112 | }) | ||
113 | } | ||
114 | |||
115 | // Simple token-based highlighting | ||
116 | COMMENT => { | ||
117 | let comment = element.into_token().and_then(ast::Comment::cast)?; | ||
118 | let h = HlTag::Comment; | ||
119 | match comment.kind().doc { | ||
120 | Some(_) => h | HlMod::Documentation, | ||
121 | None => h.into(), | ||
122 | } | ||
123 | } | ||
124 | STRING | BYTE_STRING => HlTag::StringLiteral.into(), | ||
125 | ATTR => HlTag::Attribute.into(), | ||
126 | INT_NUMBER | FLOAT_NUMBER => HlTag::NumericLiteral.into(), | ||
127 | BYTE => HlTag::ByteLiteral.into(), | ||
128 | CHAR => HlTag::CharLiteral.into(), | ||
129 | QUESTION => Highlight::new(HlTag::Operator) | HlMod::ControlFlow, | ||
130 | LIFETIME => { | ||
131 | let lifetime = element.into_node().and_then(ast::Lifetime::cast).unwrap(); | ||
132 | |||
133 | match NameClass::classify_lifetime(sema, &lifetime) { | ||
134 | Some(NameClass::Definition(def)) => highlight_def(db, def) | HlMod::Definition, | ||
135 | None => match NameRefClass::classify_lifetime(sema, &lifetime) { | ||
136 | Some(NameRefClass::Definition(def)) => highlight_def(db, def), | ||
137 | _ => Highlight::new(HlTag::Symbol(SymbolKind::LifetimeParam)), | ||
138 | }, | ||
139 | _ => Highlight::new(HlTag::Symbol(SymbolKind::LifetimeParam)) | HlMod::Definition, | ||
140 | } | ||
141 | } | ||
142 | p if p.is_punct() => match p { | ||
143 | T![&] => { | ||
144 | let h = HlTag::Operator.into(); | ||
145 | let is_unsafe = element | ||
146 | .parent() | ||
147 | .and_then(ast::RefExpr::cast) | ||
148 | .map(|ref_expr| sema.is_unsafe_ref_expr(&ref_expr)) | ||
149 | .unwrap_or(false); | ||
150 | if is_unsafe { | ||
151 | h | HlMod::Unsafe | ||
152 | } else { | ||
153 | h | ||
154 | } | ||
155 | } | ||
156 | T![::] | T![->] | T![=>] | T![..] | T![=] | T![@] | T![.] => HlTag::Operator.into(), | ||
157 | T![!] if element.parent().and_then(ast::MacroCall::cast).is_some() => { | ||
158 | HlTag::Symbol(SymbolKind::Macro).into() | ||
159 | } | ||
160 | T![!] if element.parent().and_then(ast::NeverType::cast).is_some() => { | ||
161 | HlTag::BuiltinType.into() | ||
162 | } | ||
163 | T![*] if element.parent().and_then(ast::PtrType::cast).is_some() => { | ||
164 | HlTag::Keyword.into() | ||
165 | } | ||
166 | T![*] if element.parent().and_then(ast::PrefixExpr::cast).is_some() => { | ||
167 | let prefix_expr = element.parent().and_then(ast::PrefixExpr::cast)?; | ||
168 | |||
169 | let expr = prefix_expr.expr()?; | ||
170 | let ty = sema.type_of_expr(&expr)?; | ||
171 | if ty.is_raw_ptr() { | ||
172 | HlTag::Operator | HlMod::Unsafe | ||
173 | } else if let Some(ast::PrefixOp::Deref) = prefix_expr.op_kind() { | ||
174 | HlTag::Operator.into() | ||
175 | } else { | ||
176 | HlTag::Punctuation(HlPunct::Other).into() | ||
177 | } | ||
178 | } | ||
179 | T![-] if element.parent().and_then(ast::PrefixExpr::cast).is_some() => { | ||
180 | let prefix_expr = element.parent().and_then(ast::PrefixExpr::cast)?; | ||
181 | |||
182 | let expr = prefix_expr.expr()?; | ||
183 | match expr { | ||
184 | ast::Expr::Literal(_) => HlTag::NumericLiteral, | ||
185 | _ => HlTag::Operator, | ||
186 | } | ||
187 | .into() | ||
188 | } | ||
189 | _ if element.parent().and_then(ast::PrefixExpr::cast).is_some() => { | ||
190 | HlTag::Operator.into() | ||
191 | } | ||
192 | _ if element.parent().and_then(ast::BinExpr::cast).is_some() => HlTag::Operator.into(), | ||
193 | _ if element.parent().and_then(ast::RangeExpr::cast).is_some() => { | ||
194 | HlTag::Operator.into() | ||
195 | } | ||
196 | _ if element.parent().and_then(ast::RangePat::cast).is_some() => HlTag::Operator.into(), | ||
197 | _ if element.parent().and_then(ast::RestPat::cast).is_some() => HlTag::Operator.into(), | ||
198 | _ if element.parent().and_then(ast::Attr::cast).is_some() => HlTag::Attribute.into(), | ||
199 | kind => HlTag::Punctuation(match kind { | ||
200 | T!['['] | T![']'] => HlPunct::Bracket, | ||
201 | T!['{'] | T!['}'] => HlPunct::Brace, | ||
202 | T!['('] | T![')'] => HlPunct::Parenthesis, | ||
203 | T![<] | T![>] => HlPunct::Angle, | ||
204 | T![,] => HlPunct::Comma, | ||
205 | T![:] => HlPunct::Colon, | ||
206 | T![;] => HlPunct::Semi, | ||
207 | T![.] => HlPunct::Dot, | ||
208 | _ => HlPunct::Other, | ||
209 | }) | ||
210 | .into(), | ||
211 | }, | ||
212 | |||
213 | k if k.is_keyword() => { | ||
214 | let h = Highlight::new(HlTag::Keyword); | ||
215 | match k { | ||
216 | T![break] | ||
217 | | T![continue] | ||
218 | | T![else] | ||
219 | | T![if] | ||
220 | | T![loop] | ||
221 | | T![match] | ||
222 | | T![return] | ||
223 | | T![while] | ||
224 | | T![in] => h | HlMod::ControlFlow, | ||
225 | T![for] if !is_child_of_impl(&element) => h | HlMod::ControlFlow, | ||
226 | T![unsafe] => h | HlMod::Unsafe, | ||
227 | T![true] | T![false] => HlTag::BoolLiteral.into(), | ||
228 | T![self] => { | ||
229 | let self_param_is_mut = element | ||
230 | .parent() | ||
231 | .and_then(ast::SelfParam::cast) | ||
232 | .and_then(|p| p.mut_token()) | ||
233 | .is_some(); | ||
234 | let self_path = &element | ||
235 | .parent() | ||
236 | .as_ref() | ||
237 | .and_then(SyntaxNode::parent) | ||
238 | .and_then(ast::Path::cast) | ||
239 | .and_then(|p| sema.resolve_path(&p)); | ||
240 | let mut h = HlTag::Symbol(SymbolKind::SelfParam).into(); | ||
241 | if self_param_is_mut | ||
242 | || matches!(self_path, | ||
243 | Some(hir::PathResolution::Local(local)) | ||
244 | if local.is_self(db) | ||
245 | && (local.is_mut(db) || local.ty(db).is_mutable_reference()) | ||
246 | ) | ||
247 | { | ||
248 | h |= HlMod::Mutable | ||
249 | } | ||
250 | |||
251 | if let Some(hir::PathResolution::Local(local)) = self_path { | ||
252 | if is_consumed_lvalue(element, &local, db) { | ||
253 | h |= HlMod::Consuming; | ||
254 | } | ||
255 | } | ||
256 | |||
257 | h | ||
258 | } | ||
259 | T![ref] => element | ||
260 | .parent() | ||
261 | .and_then(ast::IdentPat::cast) | ||
262 | .and_then(|ident_pat| { | ||
263 | if sema.is_unsafe_ident_pat(&ident_pat) { | ||
264 | Some(HlMod::Unsafe) | ||
265 | } else { | ||
266 | None | ||
267 | } | ||
268 | }) | ||
269 | .map(|modifier| h | modifier) | ||
270 | .unwrap_or(h), | ||
271 | _ => h, | ||
272 | } | ||
273 | } | ||
274 | |||
275 | _ => return None, | ||
276 | }; | ||
277 | |||
278 | return Some((highlight, binding_hash)); | ||
279 | |||
280 | fn calc_binding_hash(name: &hir::Name, shadow_count: u32) -> u64 { | ||
281 | fn hash<T: std::hash::Hash + std::fmt::Debug>(x: T) -> u64 { | ||
282 | use std::{collections::hash_map::DefaultHasher, hash::Hasher}; | ||
283 | |||
284 | let mut hasher = DefaultHasher::new(); | ||
285 | x.hash(&mut hasher); | ||
286 | hasher.finish() | ||
287 | } | ||
288 | |||
289 | hash((name, shadow_count)) | ||
290 | } | ||
291 | } | ||
292 | |||
293 | fn highlight_def(db: &RootDatabase, def: Definition) -> Highlight { | ||
294 | match def { | ||
295 | Definition::Macro(_) => HlTag::Symbol(SymbolKind::Macro), | ||
296 | Definition::Field(_) => HlTag::Symbol(SymbolKind::Field), | ||
297 | Definition::ModuleDef(def) => match def { | ||
298 | hir::ModuleDef::Module(_) => HlTag::Symbol(SymbolKind::Module), | ||
299 | hir::ModuleDef::Function(func) => { | ||
300 | let mut h = Highlight::new(HlTag::Symbol(SymbolKind::Function)); | ||
301 | if func.as_assoc_item(db).is_some() { | ||
302 | h |= HlMod::Associated; | ||
303 | if func.self_param(db).is_none() { | ||
304 | h |= HlMod::Static | ||
305 | } | ||
306 | } | ||
307 | if func.is_unsafe(db) { | ||
308 | h |= HlMod::Unsafe; | ||
309 | } | ||
310 | return h; | ||
311 | } | ||
312 | hir::ModuleDef::Adt(hir::Adt::Struct(_)) => HlTag::Symbol(SymbolKind::Struct), | ||
313 | hir::ModuleDef::Adt(hir::Adt::Enum(_)) => HlTag::Symbol(SymbolKind::Enum), | ||
314 | hir::ModuleDef::Adt(hir::Adt::Union(_)) => HlTag::Symbol(SymbolKind::Union), | ||
315 | hir::ModuleDef::Variant(_) => HlTag::Symbol(SymbolKind::Variant), | ||
316 | hir::ModuleDef::Const(konst) => { | ||
317 | let mut h = Highlight::new(HlTag::Symbol(SymbolKind::Const)); | ||
318 | if konst.as_assoc_item(db).is_some() { | ||
319 | h |= HlMod::Associated | ||
320 | } | ||
321 | return h; | ||
322 | } | ||
323 | hir::ModuleDef::Trait(_) => HlTag::Symbol(SymbolKind::Trait), | ||
324 | hir::ModuleDef::TypeAlias(type_) => { | ||
325 | let mut h = Highlight::new(HlTag::Symbol(SymbolKind::TypeAlias)); | ||
326 | if type_.as_assoc_item(db).is_some() { | ||
327 | h |= HlMod::Associated | ||
328 | } | ||
329 | return h; | ||
330 | } | ||
331 | hir::ModuleDef::BuiltinType(_) => HlTag::BuiltinType, | ||
332 | hir::ModuleDef::Static(s) => { | ||
333 | let mut h = Highlight::new(HlTag::Symbol(SymbolKind::Static)); | ||
334 | if s.is_mut(db) { | ||
335 | h |= HlMod::Mutable; | ||
336 | h |= HlMod::Unsafe; | ||
337 | } | ||
338 | return h; | ||
339 | } | ||
340 | }, | ||
341 | Definition::SelfType(_) => HlTag::Symbol(SymbolKind::Impl), | ||
342 | Definition::GenericParam(it) => match it { | ||
343 | hir::GenericParam::TypeParam(_) => HlTag::Symbol(SymbolKind::TypeParam), | ||
344 | hir::GenericParam::ConstParam(_) => HlTag::Symbol(SymbolKind::ConstParam), | ||
345 | hir::GenericParam::LifetimeParam(_) => HlTag::Symbol(SymbolKind::LifetimeParam), | ||
346 | }, | ||
347 | Definition::Local(local) => { | ||
348 | let tag = if local.is_param(db) { | ||
349 | HlTag::Symbol(SymbolKind::ValueParam) | ||
350 | } else { | ||
351 | HlTag::Symbol(SymbolKind::Local) | ||
352 | }; | ||
353 | let mut h = Highlight::new(tag); | ||
354 | if local.is_mut(db) || local.ty(db).is_mutable_reference() { | ||
355 | h |= HlMod::Mutable; | ||
356 | } | ||
357 | if local.ty(db).as_callable(db).is_some() || local.ty(db).impls_fnonce(db) { | ||
358 | h |= HlMod::Callable; | ||
359 | } | ||
360 | return h; | ||
361 | } | ||
362 | Definition::Label(_) => HlTag::Symbol(SymbolKind::Label), | ||
363 | } | ||
364 | .into() | ||
365 | } | ||
366 | |||
367 | fn highlight_func_by_name_ref( | ||
368 | sema: &Semantics<RootDatabase>, | ||
369 | name_ref: &ast::NameRef, | ||
370 | ) -> Option<Highlight> { | ||
371 | let mc = name_ref.syntax().parent().and_then(ast::MethodCallExpr::cast)?; | ||
372 | highlight_method_call(sema, &mc) | ||
373 | } | ||
374 | |||
375 | fn highlight_method_call( | ||
376 | sema: &Semantics<RootDatabase>, | ||
377 | method_call: &ast::MethodCallExpr, | ||
378 | ) -> Option<Highlight> { | ||
379 | let func = sema.resolve_method_call(&method_call)?; | ||
380 | let mut h = HlTag::Symbol(SymbolKind::Function).into(); | ||
381 | h |= HlMod::Associated; | ||
382 | if func.is_unsafe(sema.db) || sema.is_unsafe_method_call(&method_call) { | ||
383 | h |= HlMod::Unsafe; | ||
384 | } | ||
385 | if let Some(self_param) = func.self_param(sema.db) { | ||
386 | match self_param.access(sema.db) { | ||
387 | hir::Access::Shared => (), | ||
388 | hir::Access::Exclusive => h |= HlMod::Mutable, | ||
389 | hir::Access::Owned => { | ||
390 | if let Some(receiver_ty) = | ||
391 | method_call.receiver().and_then(|it| sema.type_of_expr(&it)) | ||
392 | { | ||
393 | if !receiver_ty.is_copy(sema.db) { | ||
394 | h |= HlMod::Consuming | ||
395 | } | ||
396 | } | ||
397 | } | ||
398 | } | ||
399 | } | ||
400 | Some(h) | ||
401 | } | ||
402 | |||
403 | fn highlight_name_by_syntax(name: ast::Name) -> Highlight { | ||
404 | let default = HlTag::UnresolvedReference; | ||
405 | |||
406 | let parent = match name.syntax().parent() { | ||
407 | Some(it) => it, | ||
408 | _ => return default.into(), | ||
409 | }; | ||
410 | |||
411 | let tag = match parent.kind() { | ||
412 | STRUCT => HlTag::Symbol(SymbolKind::Struct), | ||
413 | ENUM => HlTag::Symbol(SymbolKind::Enum), | ||
414 | VARIANT => HlTag::Symbol(SymbolKind::Variant), | ||
415 | UNION => HlTag::Symbol(SymbolKind::Union), | ||
416 | TRAIT => HlTag::Symbol(SymbolKind::Trait), | ||
417 | TYPE_ALIAS => HlTag::Symbol(SymbolKind::TypeAlias), | ||
418 | TYPE_PARAM => HlTag::Symbol(SymbolKind::TypeParam), | ||
419 | RECORD_FIELD => HlTag::Symbol(SymbolKind::Field), | ||
420 | MODULE => HlTag::Symbol(SymbolKind::Module), | ||
421 | FN => HlTag::Symbol(SymbolKind::Function), | ||
422 | CONST => HlTag::Symbol(SymbolKind::Const), | ||
423 | STATIC => HlTag::Symbol(SymbolKind::Static), | ||
424 | IDENT_PAT => HlTag::Symbol(SymbolKind::Local), | ||
425 | _ => default, | ||
426 | }; | ||
427 | |||
428 | tag.into() | ||
429 | } | ||
430 | |||
431 | fn highlight_name_ref_by_syntax(name: ast::NameRef, sema: &Semantics<RootDatabase>) -> Highlight { | ||
432 | let default = HlTag::UnresolvedReference; | ||
433 | |||
434 | let parent = match name.syntax().parent() { | ||
435 | Some(it) => it, | ||
436 | _ => return default.into(), | ||
437 | }; | ||
438 | |||
439 | match parent.kind() { | ||
440 | METHOD_CALL_EXPR => { | ||
441 | return ast::MethodCallExpr::cast(parent) | ||
442 | .and_then(|it| highlight_method_call(sema, &it)) | ||
443 | .unwrap_or_else(|| HlTag::Symbol(SymbolKind::Function).into()); | ||
444 | } | ||
445 | FIELD_EXPR => { | ||
446 | let h = HlTag::Symbol(SymbolKind::Field); | ||
447 | let is_union = ast::FieldExpr::cast(parent) | ||
448 | .and_then(|field_expr| { | ||
449 | let field = sema.resolve_field(&field_expr)?; | ||
450 | Some(if let VariantDef::Union(_) = field.parent_def(sema.db) { | ||
451 | true | ||
452 | } else { | ||
453 | false | ||
454 | }) | ||
455 | }) | ||
456 | .unwrap_or(false); | ||
457 | if is_union { | ||
458 | h | HlMod::Unsafe | ||
459 | } else { | ||
460 | h.into() | ||
461 | } | ||
462 | } | ||
463 | PATH_SEGMENT => { | ||
464 | let path = match parent.parent().and_then(ast::Path::cast) { | ||
465 | Some(it) => it, | ||
466 | _ => return default.into(), | ||
467 | }; | ||
468 | let expr = match path.syntax().parent().and_then(ast::PathExpr::cast) { | ||
469 | Some(it) => it, | ||
470 | _ => { | ||
471 | // within path, decide whether it is module or adt by checking for uppercase name | ||
472 | return if name.text().chars().next().unwrap_or_default().is_uppercase() { | ||
473 | HlTag::Symbol(SymbolKind::Struct) | ||
474 | } else { | ||
475 | HlTag::Symbol(SymbolKind::Module) | ||
476 | } | ||
477 | .into(); | ||
478 | } | ||
479 | }; | ||
480 | let parent = match expr.syntax().parent() { | ||
481 | Some(it) => it, | ||
482 | None => return default.into(), | ||
483 | }; | ||
484 | |||
485 | match parent.kind() { | ||
486 | CALL_EXPR => HlTag::Symbol(SymbolKind::Function).into(), | ||
487 | _ => if name.text().chars().next().unwrap_or_default().is_uppercase() { | ||
488 | HlTag::Symbol(SymbolKind::Struct) | ||
489 | } else { | ||
490 | HlTag::Symbol(SymbolKind::Const) | ||
491 | } | ||
492 | .into(), | ||
493 | } | ||
494 | } | ||
495 | _ => default.into(), | ||
496 | } | ||
497 | } | ||
498 | |||
499 | fn is_consumed_lvalue( | ||
500 | node: NodeOrToken<SyntaxNode, SyntaxToken>, | ||
501 | local: &hir::Local, | ||
502 | db: &RootDatabase, | ||
503 | ) -> bool { | ||
504 | // When lvalues are passed as arguments and they're not Copy, then mark them as Consuming. | ||
505 | parents_match(node, &[PATH_SEGMENT, PATH, PATH_EXPR, ARG_LIST]) && !local.ty(db).is_copy(db) | ||
506 | } | ||
507 | |||
508 | /// Returns true if the parent nodes of `node` all match the `SyntaxKind`s in `kinds` exactly. | ||
509 | fn parents_match(mut node: NodeOrToken<SyntaxNode, SyntaxToken>, mut kinds: &[SyntaxKind]) -> bool { | ||
510 | while let (Some(parent), [kind, rest @ ..]) = (&node.parent(), kinds) { | ||
511 | if parent.kind() != *kind { | ||
512 | return false; | ||
513 | } | ||
514 | |||
515 | // FIXME: Would be nice to get parent out of the match, but binding by-move and by-value | ||
516 | // in the same pattern is unstable: rust-lang/rust#68354. | ||
517 | node = node.parent().unwrap().into(); | ||
518 | kinds = rest; | ||
519 | } | ||
520 | |||
521 | // Only true if we matched all expected kinds | ||
522 | kinds.len() == 0 | ||
523 | } | ||
524 | |||
525 | fn is_child_of_impl(element: &SyntaxElement) -> bool { | ||
526 | match element.parent() { | ||
527 | Some(e) => e.kind() == IMPL, | ||
528 | _ => false, | ||
529 | } | ||
530 | } | ||
diff --git a/crates/ide/src/syntax_highlighting/highlights.rs b/crates/ide/src/syntax_highlighting/highlights.rs index 11c11ed28..c6f0417ec 100644 --- a/crates/ide/src/syntax_highlighting/highlights.rs +++ b/crates/ide/src/syntax_highlighting/highlights.rs | |||
@@ -51,18 +51,20 @@ impl Node { | |||
51 | } | 51 | } |
52 | } | 52 | } |
53 | 53 | ||
54 | let (start, len) = | 54 | let overlapping = |
55 | equal_range_by(&self.nested, |n| ordering(n.hl_range.range, hl_range.range)); | 55 | equal_range_by(&self.nested, |n| ordering(n.hl_range.range, hl_range.range)); |
56 | 56 | ||
57 | if len == 1 && self.nested[start].hl_range.range.contains_range(hl_range.range) { | 57 | if overlapping.len() == 1 |
58 | return self.nested[start].add(hl_range); | 58 | && self.nested[overlapping.start].hl_range.range.contains_range(hl_range.range) |
59 | { | ||
60 | return self.nested[overlapping.start].add(hl_range); | ||
59 | } | 61 | } |
60 | 62 | ||
61 | let nested = self | 63 | let nested = self |
62 | .nested | 64 | .nested |
63 | .splice(start..start + len, iter::once(Node::new(hl_range))) | 65 | .splice(overlapping.clone(), iter::once(Node::new(hl_range))) |
64 | .collect::<Vec<_>>(); | 66 | .collect::<Vec<_>>(); |
65 | self.nested[start].nested = nested; | 67 | self.nested[overlapping.start].nested = nested; |
66 | } | 68 | } |
67 | 69 | ||
68 | fn flatten(&self, acc: &mut Vec<HlRange>) { | 70 | fn flatten(&self, acc: &mut Vec<HlRange>) { |
diff --git a/crates/ide/src/syntax_highlighting/injection.rs b/crates/ide/src/syntax_highlighting/inject.rs index 008d5ce24..281461493 100644 --- a/crates/ide/src/syntax_highlighting/injection.rs +++ b/crates/ide/src/syntax_highlighting/inject.rs | |||
@@ -1,17 +1,14 @@ | |||
1 | //! Syntax highlighting injections such as highlighting of documentation tests. | 1 | //! "Recursive" Syntax highlighting for code in doctests and fixtures. |
2 | |||
3 | use std::convert::TryFrom; | ||
4 | 2 | ||
5 | use hir::Semantics; | 3 | use hir::Semantics; |
6 | use ide_db::call_info::ActiveParameter; | 4 | use ide_db::call_info::ActiveParameter; |
7 | use itertools::Itertools; | ||
8 | use syntax::{ast, AstToken, SyntaxNode, SyntaxToken, TextRange, TextSize}; | 5 | use syntax::{ast, AstToken, SyntaxNode, SyntaxToken, TextRange, TextSize}; |
9 | 6 | ||
10 | use crate::{Analysis, HlMod, HlRange, HlTag, RootDatabase}; | 7 | use crate::{Analysis, HlMod, HlRange, HlTag, RootDatabase}; |
11 | 8 | ||
12 | use super::{highlights::Highlights, injector::Injector}; | 9 | use super::{highlights::Highlights, injector::Injector}; |
13 | 10 | ||
14 | pub(super) fn highlight_injection( | 11 | pub(super) fn ra_fixture( |
15 | hl: &mut Highlights, | 12 | hl: &mut Highlights, |
16 | sema: &Semantics<RootDatabase>, | 13 | sema: &Semantics<RootDatabase>, |
17 | literal: ast::String, | 14 | literal: ast::String, |
@@ -84,107 +81,78 @@ const RUSTDOC_FENCE_TOKENS: &[&'static str] = &[ | |||
84 | "edition2021", | 81 | "edition2021", |
85 | ]; | 82 | ]; |
86 | 83 | ||
87 | /// Extracts Rust code from documentation comments as well as a mapping from | 84 | /// Injection of syntax highlighting of doctests. |
88 | /// the extracted source code back to the original source ranges. | 85 | pub(super) fn doc_comment(hl: &mut Highlights, node: &SyntaxNode) { |
89 | /// Lastly, a vector of new comment highlight ranges (spanning only the | 86 | let doc_comments = node |
90 | /// comment prefix) is returned which is used in the syntax highlighting | 87 | .children_with_tokens() |
91 | /// injection to replace the previous (line-spanning) comment ranges. | 88 | .filter_map(|it| it.into_token().and_then(ast::Comment::cast)) |
92 | pub(super) fn extract_doc_comments(node: &SyntaxNode) -> Option<(Vec<HlRange>, Injector)> { | 89 | .filter(|it| it.kind().doc.is_some()); |
90 | |||
91 | if !doc_comments.clone().any(|it| it.text().contains(RUSTDOC_FENCE)) { | ||
92 | return; | ||
93 | } | ||
94 | |||
93 | let mut inj = Injector::default(); | 95 | let mut inj = Injector::default(); |
94 | // wrap the doctest into function body to get correct syntax highlighting | 96 | inj.add_unmapped("fn doctest() {\n"); |
95 | let prefix = "fn doctest() {\n"; | ||
96 | let suffix = "}\n"; | ||
97 | 97 | ||
98 | let mut line_start = TextSize::of(prefix); | ||
99 | let mut is_codeblock = false; | 98 | let mut is_codeblock = false; |
100 | let mut is_doctest = false; | 99 | let mut is_doctest = false; |
100 | |||
101 | // Replace the original, line-spanning comment ranges by new, only comment-prefix | 101 | // Replace the original, line-spanning comment ranges by new, only comment-prefix |
102 | // spanning comment ranges. | 102 | // spanning comment ranges. |
103 | let mut new_comments = Vec::new(); | 103 | let mut new_comments = Vec::new(); |
104 | 104 | for comment in doc_comments { | |
105 | inj.add_unmapped(prefix); | 105 | match comment.text().find(RUSTDOC_FENCE) { |
106 | let doctest = node | 106 | Some(idx) => { |
107 | .children_with_tokens() | ||
108 | .filter_map(|el| el.into_token().and_then(ast::Comment::cast)) | ||
109 | .filter(|comment| comment.kind().doc.is_some()) | ||
110 | .filter(|comment| { | ||
111 | if let Some(idx) = comment.text().find(RUSTDOC_FENCE) { | ||
112 | is_codeblock = !is_codeblock; | 107 | is_codeblock = !is_codeblock; |
113 | // Check whether code is rust by inspecting fence guards | 108 | // Check whether code is rust by inspecting fence guards |
114 | let guards = &comment.text()[idx + RUSTDOC_FENCE.len()..]; | 109 | let guards = &comment.text()[idx + RUSTDOC_FENCE.len()..]; |
115 | let is_rust = | 110 | let is_rust = |
116 | guards.split(',').all(|sub| RUSTDOC_FENCE_TOKENS.contains(&sub.trim())); | 111 | guards.split(',').all(|sub| RUSTDOC_FENCE_TOKENS.contains(&sub.trim())); |
117 | is_doctest = is_codeblock && is_rust; | 112 | is_doctest = is_codeblock && is_rust; |
118 | false | 113 | continue; |
119 | } else { | ||
120 | is_doctest | ||
121 | } | 114 | } |
122 | }) | 115 | None if !is_doctest => continue, |
123 | .map(|comment| { | 116 | None => (), |
124 | let prefix_len = comment.prefix().len(); | 117 | } |
125 | let line: &str = comment.text().as_str(); | ||
126 | let range = comment.syntax().text_range(); | ||
127 | |||
128 | // whitespace after comment is ignored | ||
129 | let pos = if let Some(ws) = line.chars().nth(prefix_len).filter(|c| c.is_whitespace()) { | ||
130 | prefix_len + ws.len_utf8() | ||
131 | } else { | ||
132 | prefix_len | ||
133 | }; | ||
134 | |||
135 | // lines marked with `#` should be ignored in output, we skip the `#` char | ||
136 | let pos = if let Some(ws) = line.chars().nth(pos).filter(|&c| c == '#') { | ||
137 | pos + ws.len_utf8() | ||
138 | } else { | ||
139 | pos | ||
140 | }; | ||
141 | |||
142 | new_comments.push(HlRange { | ||
143 | range: TextRange::new( | ||
144 | range.start(), | ||
145 | range.start() + TextSize::try_from(pos).unwrap(), | ||
146 | ), | ||
147 | highlight: HlTag::Comment | HlMod::Documentation, | ||
148 | binding_hash: None, | ||
149 | }); | ||
150 | line_start += range.len() - TextSize::try_from(pos).unwrap(); | ||
151 | line_start += TextSize::of("\n"); | ||
152 | |||
153 | inj.add( | ||
154 | &line[pos..], | ||
155 | TextRange::new(range.start() + TextSize::try_from(pos).unwrap(), range.end()), | ||
156 | ); | ||
157 | inj.add_unmapped("\n"); | ||
158 | line[pos..].to_owned() | ||
159 | }) | ||
160 | .join("\n"); | ||
161 | inj.add_unmapped(suffix); | ||
162 | |||
163 | if doctest.is_empty() { | ||
164 | return None; | ||
165 | } | ||
166 | 118 | ||
167 | Some((new_comments, inj)) | 119 | let line: &str = comment.text().as_str(); |
168 | } | 120 | let range = comment.syntax().text_range(); |
169 | 121 | ||
170 | /// Injection of syntax highlighting of doctests. | 122 | let mut pos = TextSize::of(comment.prefix()); |
171 | pub(super) fn highlight_doc_comment( | 123 | // whitespace after comment is ignored |
172 | new_comments: Vec<HlRange>, | 124 | if let Some(ws) = line[pos.into()..].chars().next().filter(|c| c.is_whitespace()) { |
173 | inj: Injector, | 125 | pos += TextSize::of(ws); |
174 | stack: &mut Highlights, | 126 | } |
175 | ) { | 127 | // lines marked with `#` should be ignored in output, we skip the `#` char |
176 | let (analysis, tmp_file_id) = Analysis::from_single_file(inj.text().to_string()); | 128 | if let Some(ws) = line[pos.into()..].chars().next().filter(|&c| c == '#') { |
177 | for comment in new_comments { | 129 | pos += TextSize::of(ws); |
178 | stack.add(comment); | 130 | } |
131 | |||
132 | new_comments.push(TextRange::at(range.start(), pos)); | ||
133 | |||
134 | inj.add(&line[pos.into()..], TextRange::new(range.start() + pos, range.end())); | ||
135 | inj.add_unmapped("\n"); | ||
179 | } | 136 | } |
137 | inj.add_unmapped("\n}"); | ||
138 | |||
139 | let (analysis, tmp_file_id) = Analysis::from_single_file(inj.text().to_string()); | ||
180 | 140 | ||
181 | for h in analysis.with_db(|db| super::highlight(db, tmp_file_id, None, true)).unwrap() { | 141 | for h in analysis.with_db(|db| super::highlight(db, tmp_file_id, None, true)).unwrap() { |
182 | for r in inj.map_range_up(h.range) { | 142 | for r in inj.map_range_up(h.range) { |
183 | stack.add(HlRange { | 143 | hl.add(HlRange { |
184 | range: r, | 144 | range: r, |
185 | highlight: h.highlight | HlMod::Injected, | 145 | highlight: h.highlight | HlMod::Injected, |
186 | binding_hash: h.binding_hash, | 146 | binding_hash: h.binding_hash, |
187 | }); | 147 | }); |
188 | } | 148 | } |
189 | } | 149 | } |
150 | |||
151 | for range in new_comments { | ||
152 | hl.add(HlRange { | ||
153 | range, | ||
154 | highlight: HlTag::Comment | HlMod::Documentation, | ||
155 | binding_hash: None, | ||
156 | }); | ||
157 | } | ||
190 | } | 158 | } |
diff --git a/crates/ide/src/syntax_highlighting/injector.rs b/crates/ide/src/syntax_highlighting/injector.rs index e8f17eb69..fd4025694 100644 --- a/crates/ide/src/syntax_highlighting/injector.rs +++ b/crates/ide/src/syntax_highlighting/injector.rs | |||
@@ -33,8 +33,7 @@ impl Injector { | |||
33 | &self.buf | 33 | &self.buf |
34 | } | 34 | } |
35 | pub(super) fn map_range_up(&self, range: TextRange) -> impl Iterator<Item = TextRange> + '_ { | 35 | pub(super) fn map_range_up(&self, range: TextRange) -> impl Iterator<Item = TextRange> + '_ { |
36 | let (start, len) = equal_range_by(&self.ranges, |&(r, _)| ordering(r, range)); | 36 | equal_range_by(&self.ranges, |&(r, _)| ordering(r, range)).filter_map(move |i| { |
37 | (start..start + len).filter_map(move |i| { | ||
38 | let (target_range, delta) = self.ranges[i]; | 37 | let (target_range, delta) = self.ranges[i]; |
39 | let intersection = target_range.intersect(range).unwrap(); | 38 | let intersection = target_range.intersect(range).unwrap(); |
40 | Some(intersection + delta?) | 39 | Some(intersection + delta?) |
diff --git a/crates/ide/src/syntax_highlighting/macro_rules.rs b/crates/ide/src/syntax_highlighting/macro_rules.rs index 21d8a9835..44620e912 100644 --- a/crates/ide/src/syntax_highlighting/macro_rules.rs +++ b/crates/ide/src/syntax_highlighting/macro_rules.rs | |||
@@ -119,7 +119,7 @@ fn is_metavariable(element: SyntaxElement) -> Option<TextRange> { | |||
119 | let tok = element.as_token()?; | 119 | let tok = element.as_token()?; |
120 | match tok.kind() { | 120 | match tok.kind() { |
121 | kind if kind == SyntaxKind::IDENT || kind.is_keyword() => { | 121 | kind if kind == SyntaxKind::IDENT || kind.is_keyword() => { |
122 | if let Some(_dollar) = tok.prev_token().filter(|t| t.kind() == SyntaxKind::DOLLAR) { | 122 | if let Some(_dollar) = tok.prev_token().filter(|t| t.kind() == T![$]) { |
123 | return Some(tok.text_range()); | 123 | return Some(tok.text_range()); |
124 | } | 124 | } |
125 | } | 125 | } |
diff --git a/crates/ide/src/syntax_highlighting/tags.rs b/crates/ide/src/syntax_highlighting/tags.rs index 2f39bcc8e..8dd05ac52 100644 --- a/crates/ide/src/syntax_highlighting/tags.rs +++ b/crates/ide/src/syntax_highlighting/tags.rs | |||
@@ -29,7 +29,7 @@ pub enum HlTag { | |||
29 | EscapeSequence, | 29 | EscapeSequence, |
30 | FormatSpecifier, | 30 | FormatSpecifier, |
31 | Keyword, | 31 | Keyword, |
32 | Punctuation, | 32 | Punctuation(HlPunct), |
33 | Operator, | 33 | Operator, |
34 | UnresolvedReference, | 34 | UnresolvedReference, |
35 | 35 | ||
@@ -61,6 +61,28 @@ pub enum HlMod { | |||
61 | Unsafe, | 61 | Unsafe, |
62 | } | 62 | } |
63 | 63 | ||
64 | #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)] | ||
65 | pub enum HlPunct { | ||
66 | /// [] | ||
67 | Bracket, | ||
68 | /// {} | ||
69 | Brace, | ||
70 | /// () | ||
71 | Parenthesis, | ||
72 | /// <> | ||
73 | Angle, | ||
74 | /// , | ||
75 | Comma, | ||
76 | /// . | ||
77 | Dot, | ||
78 | /// : | ||
79 | Colon, | ||
80 | /// ; | ||
81 | Semi, | ||
82 | /// | ||
83 | Other, | ||
84 | } | ||
85 | |||
64 | impl HlTag { | 86 | impl HlTag { |
65 | fn as_str(self) -> &'static str { | 87 | fn as_str(self) -> &'static str { |
66 | match self { | 88 | match self { |
@@ -95,7 +117,17 @@ impl HlTag { | |||
95 | HlTag::EscapeSequence => "escape_sequence", | 117 | HlTag::EscapeSequence => "escape_sequence", |
96 | HlTag::FormatSpecifier => "format_specifier", | 118 | HlTag::FormatSpecifier => "format_specifier", |
97 | HlTag::Keyword => "keyword", | 119 | HlTag::Keyword => "keyword", |
98 | HlTag::Punctuation => "punctuation", | 120 | HlTag::Punctuation(punct) => match punct { |
121 | HlPunct::Bracket => "bracket", | ||
122 | HlPunct::Brace => "brace", | ||
123 | HlPunct::Parenthesis => "parenthesis", | ||
124 | HlPunct::Angle => "angle", | ||
125 | HlPunct::Comma => "comma", | ||
126 | HlPunct::Dot => "dot", | ||
127 | HlPunct::Colon => "colon", | ||
128 | HlPunct::Semi => "semicolon", | ||
129 | HlPunct::Other => "punctuation", | ||
130 | }, | ||
99 | HlTag::NumericLiteral => "numeric_literal", | 131 | HlTag::NumericLiteral => "numeric_literal", |
100 | HlTag::Operator => "operator", | 132 | HlTag::Operator => "operator", |
101 | HlTag::StringLiteral => "string_literal", | 133 | HlTag::StringLiteral => "string_literal", |
diff --git a/crates/ide/src/syntax_highlighting/test_data/highlight_assoc_functions.html b/crates/ide/src/syntax_highlighting/test_data/highlight_assoc_functions.html index 506ebe60e..e36e6fc3f 100644 --- a/crates/ide/src/syntax_highlighting/test_data/highlight_assoc_functions.html +++ b/crates/ide/src/syntax_highlighting/test_data/highlight_assoc_functions.html | |||
@@ -36,22 +36,22 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd | |||
36 | 36 | ||
37 | .unresolved_reference { color: #FC5555; text-decoration: wavy underline; } | 37 | .unresolved_reference { color: #FC5555; text-decoration: wavy underline; } |
38 | </style> | 38 | </style> |
39 | <pre><code><span class="keyword">fn</span> <span class="function declaration">not_static</span><span class="punctuation">(</span><span class="punctuation">)</span> <span class="punctuation">{</span><span class="punctuation">}</span> | 39 | <pre><code><span class="keyword">fn</span> <span class="function declaration">not_static</span><span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="brace">{</span><span class="brace">}</span> |
40 | 40 | ||
41 | <span class="keyword">struct</span> <span class="struct declaration">foo</span> <span class="punctuation">{</span><span class="punctuation">}</span> | 41 | <span class="keyword">struct</span> <span class="struct declaration">foo</span> <span class="brace">{</span><span class="brace">}</span> |
42 | 42 | ||
43 | <span class="keyword">impl</span> <span class="struct">foo</span> <span class="punctuation">{</span> | 43 | <span class="keyword">impl</span> <span class="struct">foo</span> <span class="brace">{</span> |
44 | <span class="keyword">pub</span> <span class="keyword">fn</span> <span class="function declaration static associated">is_static</span><span class="punctuation">(</span><span class="punctuation">)</span> <span class="punctuation">{</span><span class="punctuation">}</span> | 44 | <span class="keyword">pub</span> <span class="keyword">fn</span> <span class="function declaration static associated">is_static</span><span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="brace">{</span><span class="brace">}</span> |
45 | <span class="keyword">pub</span> <span class="keyword">fn</span> <span class="function declaration associated">is_not_static</span><span class="punctuation">(</span><span class="operator">&</span><span class="self_keyword">self</span><span class="punctuation">)</span> <span class="punctuation">{</span><span class="punctuation">}</span> | 45 | <span class="keyword">pub</span> <span class="keyword">fn</span> <span class="function declaration associated">is_not_static</span><span class="parenthesis">(</span><span class="operator">&</span><span class="self_keyword">self</span><span class="parenthesis">)</span> <span class="brace">{</span><span class="brace">}</span> |
46 | <span class="punctuation">}</span> | 46 | <span class="brace">}</span> |
47 | 47 | ||
48 | <span class="keyword">trait</span> <span class="trait declaration">t</span> <span class="punctuation">{</span> | 48 | <span class="keyword">trait</span> <span class="trait declaration">t</span> <span class="brace">{</span> |
49 | <span class="keyword">fn</span> <span class="function declaration static associated">t_is_static</span><span class="punctuation">(</span><span class="punctuation">)</span> <span class="punctuation">{</span><span class="punctuation">}</span> | 49 | <span class="keyword">fn</span> <span class="function declaration static associated">t_is_static</span><span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="brace">{</span><span class="brace">}</span> |
50 | <span class="keyword">fn</span> <span class="function declaration associated">t_is_not_static</span><span class="punctuation">(</span><span class="operator">&</span><span class="self_keyword">self</span><span class="punctuation">)</span> <span class="punctuation">{</span><span class="punctuation">}</span> | 50 | <span class="keyword">fn</span> <span class="function declaration associated">t_is_not_static</span><span class="parenthesis">(</span><span class="operator">&</span><span class="self_keyword">self</span><span class="parenthesis">)</span> <span class="brace">{</span><span class="brace">}</span> |
51 | <span class="punctuation">}</span> | 51 | <span class="brace">}</span> |
52 | 52 | ||
53 | <span class="keyword">impl</span> <span class="trait">t</span> <span class="keyword">for</span> <span class="struct">foo</span> <span class="punctuation">{</span> | 53 | <span class="keyword">impl</span> <span class="trait">t</span> <span class="keyword">for</span> <span class="struct">foo</span> <span class="brace">{</span> |
54 | <span class="keyword">pub</span> <span class="keyword">fn</span> <span class="function declaration static associated">is_static</span><span class="punctuation">(</span><span class="punctuation">)</span> <span class="punctuation">{</span><span class="punctuation">}</span> | 54 | <span class="keyword">pub</span> <span class="keyword">fn</span> <span class="function declaration static associated">is_static</span><span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="brace">{</span><span class="brace">}</span> |
55 | <span class="keyword">pub</span> <span class="keyword">fn</span> <span class="function declaration associated">is_not_static</span><span class="punctuation">(</span><span class="operator">&</span><span class="self_keyword">self</span><span class="punctuation">)</span> <span class="punctuation">{</span><span class="punctuation">}</span> | 55 | <span class="keyword">pub</span> <span class="keyword">fn</span> <span class="function declaration associated">is_not_static</span><span class="parenthesis">(</span><span class="operator">&</span><span class="self_keyword">self</span><span class="parenthesis">)</span> <span class="brace">{</span><span class="brace">}</span> |
56 | <span class="punctuation">}</span> | 56 | <span class="brace">}</span> |
57 | </code></pre> \ No newline at end of file | 57 | </code></pre> \ No newline at end of file |
diff --git a/crates/ide/src/syntax_highlighting/test_data/highlight_doctest.html b/crates/ide/src/syntax_highlighting/test_data/highlight_doctest.html index 7d1d2a839..6dadda1c1 100644 --- a/crates/ide/src/syntax_highlighting/test_data/highlight_doctest.html +++ b/crates/ide/src/syntax_highlighting/test_data/highlight_doctest.html | |||
@@ -37,72 +37,72 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd | |||
37 | .unresolved_reference { color: #FC5555; text-decoration: wavy underline; } | 37 | .unresolved_reference { color: #FC5555; text-decoration: wavy underline; } |
38 | </style> | 38 | </style> |
39 | <pre><code><span class="comment documentation">/// ```</span> | 39 | <pre><code><span class="comment documentation">/// ```</span> |
40 | <span class="comment documentation">/// </span><span class="keyword injected">let</span><span class="none injected"> </span><span class="punctuation injected">_</span><span class="none injected"> </span><span class="operator injected">=</span><span class="none injected"> </span><span class="string_literal injected">"early doctests should not go boom"</span><span class="punctuation injected">;</span> | 40 | <span class="comment documentation">/// </span><span class="keyword injected">let</span><span class="none injected"> </span><span class="punctuation injected">_</span><span class="none injected"> </span><span class="operator injected">=</span><span class="none injected"> </span><span class="string_literal injected">"early doctests should not go boom"</span><span class="semicolon injected">;</span> |
41 | <span class="comment documentation">/// ```</span> | 41 | <span class="comment documentation">/// ```</span> |
42 | <span class="keyword">struct</span> <span class="struct declaration">Foo</span> <span class="punctuation">{</span> | 42 | <span class="keyword">struct</span> <span class="struct declaration">Foo</span> <span class="brace">{</span> |
43 | <span class="field declaration">bar</span><span class="punctuation">:</span> <span class="builtin_type">bool</span><span class="punctuation">,</span> | 43 | <span class="field declaration">bar</span><span class="colon">:</span> <span class="builtin_type">bool</span><span class="comma">,</span> |
44 | <span class="punctuation">}</span> | 44 | <span class="brace">}</span> |
45 | 45 | ||
46 | <span class="keyword">impl</span> <span class="struct">Foo</span> <span class="punctuation">{</span> | 46 | <span class="keyword">impl</span> <span class="struct">Foo</span> <span class="brace">{</span> |
47 | <span class="comment documentation">/// ```</span> | 47 | <span class="comment documentation">/// ```</span> |
48 | <span class="comment documentation">/// </span><span class="keyword injected">let</span><span class="none injected"> </span><span class="punctuation injected">_</span><span class="none injected"> </span><span class="operator injected">=</span><span class="none injected"> </span><span class="string_literal injected">"Call me</span> | 48 | <span class="comment documentation">/// </span><span class="keyword injected">let</span><span class="none injected"> </span><span class="punctuation injected">_</span><span class="none injected"> </span><span class="operator injected">=</span><span class="none injected"> </span><span class="string_literal injected">"Call me</span> |
49 | <span class="comment">// KILLER WHALE</span> | 49 | <span class="comment">// KILLER WHALE</span> |
50 | <span class="comment documentation">/// </span><span class="string_literal injected"> Ishmael."</span><span class="punctuation injected">;</span> | 50 | <span class="comment documentation">/// </span><span class="string_literal injected"> Ishmael."</span><span class="semicolon injected">;</span> |
51 | <span class="comment documentation">/// ```</span> | 51 | <span class="comment documentation">/// ```</span> |
52 | <span class="keyword">pub</span> <span class="keyword">const</span> <span class="constant declaration associated">bar</span><span class="punctuation">:</span> <span class="builtin_type">bool</span> <span class="operator">=</span> <span class="bool_literal">true</span><span class="punctuation">;</span> | 52 | <span class="keyword">pub</span> <span class="keyword">const</span> <span class="constant declaration associated">bar</span><span class="colon">:</span> <span class="builtin_type">bool</span> <span class="operator">=</span> <span class="bool_literal">true</span><span class="semicolon">;</span> |
53 | 53 | ||
54 | <span class="comment documentation">/// Constructs a new `Foo`.</span> | 54 | <span class="comment documentation">/// Constructs a new `Foo`.</span> |
55 | <span class="comment documentation">///</span> | 55 | <span class="comment documentation">///</span> |
56 | <span class="comment documentation">/// # Examples</span> | 56 | <span class="comment documentation">/// # Examples</span> |
57 | <span class="comment documentation">///</span> | 57 | <span class="comment documentation">///</span> |
58 | <span class="comment documentation">/// ```</span> | 58 | <span class="comment documentation">/// ```</span> |
59 | <span class="comment documentation">/// #</span><span class="none injected"> </span><span class="attribute attribute injected">#</span><span class="attribute attribute injected">!</span><span class="attribute attribute injected">[</span><span class="function attribute injected">allow</span><span class="punctuation attribute injected">(</span><span class="attribute attribute injected">unused_mut</span><span class="punctuation attribute injected">)</span><span class="attribute attribute injected">]</span> | 59 | <span class="comment documentation">/// #</span><span class="none injected"> </span><span class="attribute attribute injected">#</span><span class="attribute attribute injected">!</span><span class="attribute attribute injected">[</span><span class="function attribute injected">allow</span><span class="parenthesis attribute injected">(</span><span class="attribute attribute injected">unused_mut</span><span class="parenthesis attribute injected">)</span><span class="attribute attribute injected">]</span> |
60 | <span class="comment documentation">/// </span><span class="keyword injected">let</span><span class="none injected"> </span><span class="keyword injected">mut</span><span class="none injected"> </span><span class="variable declaration injected mutable">foo</span><span class="punctuation injected">:</span><span class="none injected"> </span><span class="struct injected">Foo</span><span class="none injected"> </span><span class="operator injected">=</span><span class="none injected"> </span><span class="struct injected">Foo</span><span class="operator injected">::</span><span class="function injected">new</span><span class="punctuation injected">(</span><span class="punctuation injected">)</span><span class="punctuation injected">;</span> | 60 | <span class="comment documentation">/// </span><span class="keyword injected">let</span><span class="none injected"> </span><span class="keyword injected">mut</span><span class="none injected"> </span><span class="variable declaration injected mutable">foo</span><span class="colon injected">:</span><span class="none injected"> </span><span class="struct injected">Foo</span><span class="none injected"> </span><span class="operator injected">=</span><span class="none injected"> </span><span class="struct injected">Foo</span><span class="operator injected">::</span><span class="function injected">new</span><span class="parenthesis injected">(</span><span class="parenthesis injected">)</span><span class="semicolon injected">;</span> |
61 | <span class="comment documentation">/// ```</span> | 61 | <span class="comment documentation">/// ```</span> |
62 | <span class="keyword">pub</span> <span class="keyword">const</span> <span class="keyword">fn</span> <span class="function declaration static associated">new</span><span class="punctuation">(</span><span class="punctuation">)</span> <span class="operator">-></span> <span class="struct">Foo</span> <span class="punctuation">{</span> | 62 | <span class="keyword">pub</span> <span class="keyword">const</span> <span class="keyword">fn</span> <span class="function declaration static associated">new</span><span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="operator">-></span> <span class="struct">Foo</span> <span class="brace">{</span> |
63 | <span class="struct">Foo</span> <span class="punctuation">{</span> <span class="field">bar</span><span class="punctuation">:</span> <span class="bool_literal">true</span> <span class="punctuation">}</span> | 63 | <span class="struct">Foo</span> <span class="brace">{</span> <span class="field">bar</span><span class="colon">:</span> <span class="bool_literal">true</span> <span class="brace">}</span> |
64 | <span class="punctuation">}</span> | 64 | <span class="brace">}</span> |
65 | 65 | ||
66 | <span class="comment documentation">/// `bar` method on `Foo`.</span> | 66 | <span class="comment documentation">/// `bar` method on `Foo`.</span> |
67 | <span class="comment documentation">///</span> | 67 | <span class="comment documentation">///</span> |
68 | <span class="comment documentation">/// # Examples</span> | 68 | <span class="comment documentation">/// # Examples</span> |
69 | <span class="comment documentation">///</span> | 69 | <span class="comment documentation">///</span> |
70 | <span class="comment documentation">/// ```</span> | 70 | <span class="comment documentation">/// ```</span> |
71 | <span class="comment documentation">/// </span><span class="keyword injected">use</span><span class="none injected"> </span><span class="module injected">x</span><span class="operator injected">::</span><span class="module injected">y</span><span class="punctuation injected">;</span> | 71 | <span class="comment documentation">/// </span><span class="keyword injected">use</span><span class="none injected"> </span><span class="module injected">x</span><span class="operator injected">::</span><span class="module injected">y</span><span class="semicolon injected">;</span> |
72 | <span class="comment documentation">///</span> | 72 | <span class="comment documentation">///</span> |
73 | <span class="comment documentation">/// </span><span class="keyword injected">let</span><span class="none injected"> </span><span class="variable declaration injected">foo</span><span class="none injected"> </span><span class="operator injected">=</span><span class="none injected"> </span><span class="struct injected">Foo</span><span class="operator injected">::</span><span class="function injected">new</span><span class="punctuation injected">(</span><span class="punctuation injected">)</span><span class="punctuation injected">;</span> | 73 | <span class="comment documentation">/// </span><span class="keyword injected">let</span><span class="none injected"> </span><span class="variable declaration injected">foo</span><span class="none injected"> </span><span class="operator injected">=</span><span class="none injected"> </span><span class="struct injected">Foo</span><span class="operator injected">::</span><span class="function injected">new</span><span class="parenthesis injected">(</span><span class="parenthesis injected">)</span><span class="semicolon injected">;</span> |
74 | <span class="comment documentation">///</span> | 74 | <span class="comment documentation">///</span> |
75 | <span class="comment documentation">/// </span><span class="comment injected">// calls bar on foo</span> | 75 | <span class="comment documentation">/// </span><span class="comment injected">// calls bar on foo</span> |
76 | <span class="comment documentation">/// </span><span class="macro injected">assert!</span><span class="punctuation injected">(</span><span class="none injected">foo</span><span class="operator injected">.</span><span class="none injected">bar</span><span class="punctuation injected">(</span><span class="punctuation injected">)</span><span class="punctuation injected">)</span><span class="punctuation injected">;</span> | 76 | <span class="comment documentation">/// </span><span class="macro injected">assert!</span><span class="parenthesis injected">(</span><span class="none injected">foo</span><span class="operator injected">.</span><span class="none injected">bar</span><span class="parenthesis injected">(</span><span class="parenthesis injected">)</span><span class="parenthesis injected">)</span><span class="semicolon injected">;</span> |
77 | <span class="comment documentation">///</span> | 77 | <span class="comment documentation">///</span> |
78 | <span class="comment documentation">/// </span><span class="keyword injected">let</span><span class="none injected"> </span><span class="variable declaration injected">bar</span><span class="none injected"> </span><span class="operator injected">=</span><span class="none injected"> </span><span class="variable injected">foo</span><span class="operator injected">.</span><span class="field injected">bar</span><span class="none injected"> </span><span class="operator injected">||</span><span class="none injected"> </span><span class="struct injected">Foo</span><span class="operator injected">::</span><span class="constant injected">bar</span><span class="punctuation injected">;</span> | 78 | <span class="comment documentation">/// </span><span class="keyword injected">let</span><span class="none injected"> </span><span class="variable declaration injected">bar</span><span class="none injected"> </span><span class="operator injected">=</span><span class="none injected"> </span><span class="variable injected">foo</span><span class="operator injected">.</span><span class="field injected">bar</span><span class="none injected"> </span><span class="operator injected">||</span><span class="none injected"> </span><span class="struct injected">Foo</span><span class="operator injected">::</span><span class="constant injected">bar</span><span class="semicolon injected">;</span> |
79 | <span class="comment documentation">///</span> | 79 | <span class="comment documentation">///</span> |
80 | <span class="comment documentation">/// </span><span class="comment injected">/* multi-line</span> | 80 | <span class="comment documentation">/// </span><span class="comment injected">/* multi-line</span> |
81 | <span class="comment documentation">/// </span><span class="comment injected"> comment */</span> | 81 | <span class="comment documentation">/// </span><span class="comment injected"> comment */</span> |
82 | <span class="comment documentation">///</span> | 82 | <span class="comment documentation">///</span> |
83 | <span class="comment documentation">/// </span><span class="keyword injected">let</span><span class="none injected"> </span><span class="variable declaration injected">multi_line_string</span><span class="none injected"> </span><span class="operator injected">=</span><span class="none injected"> </span><span class="string_literal injected">"Foo</span> | 83 | <span class="comment documentation">/// </span><span class="keyword injected">let</span><span class="none injected"> </span><span class="variable declaration injected">multi_line_string</span><span class="none injected"> </span><span class="operator injected">=</span><span class="none injected"> </span><span class="string_literal injected">"Foo</span> |
84 | <span class="comment documentation">/// </span><span class="string_literal injected"> bar</span> | 84 | <span class="comment documentation">/// </span><span class="string_literal injected"> bar</span> |
85 | <span class="comment documentation">/// </span><span class="string_literal injected"> "</span><span class="punctuation injected">;</span> | 85 | <span class="comment documentation">/// </span><span class="string_literal injected"> "</span><span class="semicolon injected">;</span> |
86 | <span class="comment documentation">///</span> | 86 | <span class="comment documentation">///</span> |
87 | <span class="comment documentation">/// ```</span> | 87 | <span class="comment documentation">/// ```</span> |
88 | <span class="comment documentation">///</span> | 88 | <span class="comment documentation">///</span> |
89 | <span class="comment documentation">/// ```rust,no_run</span> | 89 | <span class="comment documentation">/// ```rust,no_run</span> |
90 | <span class="comment documentation">/// </span><span class="keyword injected">let</span><span class="none injected"> </span><span class="variable declaration injected">foobar</span><span class="none injected"> </span><span class="operator injected">=</span><span class="none injected"> </span><span class="struct injected">Foo</span><span class="operator injected">::</span><span class="function injected">new</span><span class="punctuation injected">(</span><span class="punctuation injected">)</span><span class="operator injected">.</span><span class="function injected">bar</span><span class="punctuation injected">(</span><span class="punctuation injected">)</span><span class="punctuation injected">;</span> | 90 | <span class="comment documentation">/// </span><span class="keyword injected">let</span><span class="none injected"> </span><span class="variable declaration injected">foobar</span><span class="none injected"> </span><span class="operator injected">=</span><span class="none injected"> </span><span class="struct injected">Foo</span><span class="operator injected">::</span><span class="function injected">new</span><span class="parenthesis injected">(</span><span class="parenthesis injected">)</span><span class="operator injected">.</span><span class="function injected">bar</span><span class="parenthesis injected">(</span><span class="parenthesis injected">)</span><span class="semicolon injected">;</span> |
91 | <span class="comment documentation">/// ```</span> | 91 | <span class="comment documentation">/// ```</span> |
92 | <span class="comment documentation">///</span> | 92 | <span class="comment documentation">///</span> |
93 | <span class="comment documentation">/// ```sh</span> | 93 | <span class="comment documentation">/// ```sh</span> |
94 | <span class="comment documentation">/// echo 1</span> | 94 | <span class="comment documentation">/// echo 1</span> |
95 | <span class="comment documentation">/// ```</span> | 95 | <span class="comment documentation">/// ```</span> |
96 | <span class="keyword">pub</span> <span class="keyword">fn</span> <span class="function declaration associated">foo</span><span class="punctuation">(</span><span class="operator">&</span><span class="self_keyword">self</span><span class="punctuation">)</span> <span class="operator">-></span> <span class="builtin_type">bool</span> <span class="punctuation">{</span> | 96 | <span class="keyword">pub</span> <span class="keyword">fn</span> <span class="function declaration associated">foo</span><span class="parenthesis">(</span><span class="operator">&</span><span class="self_keyword">self</span><span class="parenthesis">)</span> <span class="operator">-></span> <span class="builtin_type">bool</span> <span class="brace">{</span> |
97 | <span class="bool_literal">true</span> | 97 | <span class="bool_literal">true</span> |
98 | <span class="punctuation">}</span> | 98 | <span class="brace">}</span> |
99 | <span class="punctuation">}</span> | 99 | <span class="brace">}</span> |
100 | 100 | ||
101 | <span class="comment documentation">/// ```</span> | 101 | <span class="comment documentation">/// ```</span> |
102 | <span class="comment documentation">/// </span><span class="macro injected">noop!</span><span class="punctuation injected">(</span><span class="numeric_literal injected">1</span><span class="punctuation injected">)</span><span class="punctuation injected">;</span> | 102 | <span class="comment documentation">/// </span><span class="macro injected">noop!</span><span class="parenthesis injected">(</span><span class="numeric_literal injected">1</span><span class="parenthesis injected">)</span><span class="semicolon injected">;</span> |
103 | <span class="comment documentation">/// ```</span> | 103 | <span class="comment documentation">/// ```</span> |
104 | <span class="keyword">macro_rules</span><span class="punctuation">!</span> <span class="macro declaration">noop</span> <span class="punctuation">{</span> | 104 | <span class="keyword">macro_rules</span><span class="punctuation">!</span> <span class="macro declaration">noop</span> <span class="brace">{</span> |
105 | <span class="punctuation">(</span><span class="punctuation">$</span>expr<span class="punctuation">:</span>expr<span class="punctuation">)</span> <span class="operator">=</span><span class="punctuation">></span> <span class="punctuation">{</span> | 105 | <span class="parenthesis">(</span><span class="punctuation">$</span>expr<span class="colon">:</span>expr<span class="parenthesis">)</span> <span class="operator">=</span><span class="angle">></span> <span class="brace">{</span> |
106 | <span class="punctuation">$</span>expr | 106 | <span class="punctuation">$</span>expr |
107 | <span class="punctuation">}</span> | 107 | <span class="brace">}</span> |
108 | <span class="punctuation">}</span></code></pre> \ No newline at end of file | 108 | <span class="brace">}</span></code></pre> \ No newline at end of file |
diff --git a/crates/ide/src/syntax_highlighting/test_data/highlight_extern_crate.html b/crates/ide/src/syntax_highlighting/test_data/highlight_extern_crate.html index ed452586a..6f7a7ffff 100644 --- a/crates/ide/src/syntax_highlighting/test_data/highlight_extern_crate.html +++ b/crates/ide/src/syntax_highlighting/test_data/highlight_extern_crate.html | |||
@@ -36,6 +36,6 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd | |||
36 | 36 | ||
37 | .unresolved_reference { color: #FC5555; text-decoration: wavy underline; } | 37 | .unresolved_reference { color: #FC5555; text-decoration: wavy underline; } |
38 | </style> | 38 | </style> |
39 | <pre><code><span class="keyword">extern</span> <span class="keyword">crate</span> <span class="module">std</span><span class="punctuation">;</span> | 39 | <pre><code><span class="keyword">extern</span> <span class="keyword">crate</span> <span class="module">std</span><span class="semicolon">;</span> |
40 | <span class="keyword">extern</span> <span class="keyword">crate</span> <span class="module">alloc</span> <span class="keyword">as</span> <span class="module">abc</span><span class="punctuation">;</span> | 40 | <span class="keyword">extern</span> <span class="keyword">crate</span> <span class="module">alloc</span> <span class="keyword">as</span> <span class="module">abc</span><span class="semicolon">;</span> |
41 | </code></pre> \ No newline at end of file | 41 | </code></pre> \ No newline at end of file |
diff --git a/crates/ide/src/syntax_highlighting/test_data/highlight_injection.html b/crates/ide/src/syntax_highlighting/test_data/highlight_injection.html index 92e7dc3e4..753b535b5 100644 --- a/crates/ide/src/syntax_highlighting/test_data/highlight_injection.html +++ b/crates/ide/src/syntax_highlighting/test_data/highlight_injection.html | |||
@@ -36,14 +36,14 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd | |||
36 | 36 | ||
37 | .unresolved_reference { color: #FC5555; text-decoration: wavy underline; } | 37 | .unresolved_reference { color: #FC5555; text-decoration: wavy underline; } |
38 | </style> | 38 | </style> |
39 | <pre><code><span class="keyword">fn</span> <span class="function declaration">fixture</span><span class="punctuation">(</span><span class="value_param declaration">ra_fixture</span><span class="punctuation">:</span> <span class="operator">&</span><span class="builtin_type">str</span><span class="punctuation">)</span> <span class="punctuation">{</span><span class="punctuation">}</span> | 39 | <pre><code><span class="keyword">fn</span> <span class="function declaration">fixture</span><span class="parenthesis">(</span><span class="value_param declaration">ra_fixture</span><span class="colon">:</span> <span class="operator">&</span><span class="builtin_type">str</span><span class="parenthesis">)</span> <span class="brace">{</span><span class="brace">}</span> |
40 | 40 | ||
41 | <span class="keyword">fn</span> <span class="function declaration">main</span><span class="punctuation">(</span><span class="punctuation">)</span> <span class="punctuation">{</span> | 41 | <span class="keyword">fn</span> <span class="function declaration">main</span><span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="brace">{</span> |
42 | <span class="function">fixture</span><span class="punctuation">(</span><span class="string_literal">r#"</span> | 42 | <span class="function">fixture</span><span class="parenthesis">(</span><span class="string_literal">r#"</span> |
43 | <span class="keyword">trait</span> <span class="trait declaration">Foo</span> <span class="punctuation">{</span> | 43 | <span class="keyword">trait</span> <span class="trait declaration">Foo</span> <span class="brace">{</span> |
44 | <span class="keyword">fn</span> <span class="function declaration static associated">foo</span><span class="punctuation">(</span><span class="punctuation">)</span> <span class="punctuation">{</span> | 44 | <span class="keyword">fn</span> <span class="function declaration static associated">foo</span><span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="brace">{</span> |
45 | <span class="macro">println!</span><span class="punctuation">(</span><span class="string_literal">"2 + 2 = {}"</span><span class="punctuation">,</span> <span class="numeric_literal">4</span><span class="punctuation">)</span><span class="punctuation">;</span> | 45 | <span class="macro">println!</span><span class="parenthesis">(</span><span class="string_literal">"2 + 2 = {}"</span><span class="comma">,</span> <span class="numeric_literal">4</span><span class="parenthesis">)</span><span class="semicolon">;</span> |
46 | <span class="punctuation">}</span> | 46 | <span class="brace">}</span> |
47 | <span class="punctuation">}</span><span class="string_literal">"#</span> | 47 | <span class="brace">}</span><span class="string_literal">"#</span> |
48 | <span class="punctuation">)</span><span class="punctuation">;</span> | 48 | <span class="parenthesis">)</span><span class="semicolon">;</span> |
49 | <span class="punctuation">}</span></code></pre> \ No newline at end of file | 49 | <span class="brace">}</span></code></pre> \ No newline at end of file |
diff --git a/crates/ide/src/syntax_highlighting/test_data/highlight_strings.html b/crates/ide/src/syntax_highlighting/test_data/highlight_strings.html index 31dad5d42..66d80c4b6 100644 --- a/crates/ide/src/syntax_highlighting/test_data/highlight_strings.html +++ b/crates/ide/src/syntax_highlighting/test_data/highlight_strings.html | |||
@@ -36,64 +36,64 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd | |||
36 | 36 | ||
37 | .unresolved_reference { color: #FC5555; text-decoration: wavy underline; } | 37 | .unresolved_reference { color: #FC5555; text-decoration: wavy underline; } |
38 | </style> | 38 | </style> |
39 | <pre><code><span class="keyword">macro_rules</span><span class="punctuation">!</span> <span class="macro declaration">println</span> <span class="punctuation">{</span> | 39 | <pre><code><span class="keyword">macro_rules</span><span class="punctuation">!</span> <span class="macro declaration">println</span> <span class="brace">{</span> |
40 | <span class="punctuation">(</span><span class="punctuation">$</span><span class="punctuation">(</span><span class="punctuation">$</span>arg<span class="punctuation">:</span>tt<span class="punctuation">)</span><span class="punctuation">*</span><span class="punctuation">)</span> <span class="operator">=</span><span class="punctuation">></span> <span class="punctuation">(</span><span class="punctuation">{</span> | 40 | <span class="parenthesis">(</span><span class="punctuation">$</span><span class="parenthesis">(</span><span class="punctuation">$</span>arg<span class="colon">:</span>tt<span class="parenthesis">)</span><span class="punctuation">*</span><span class="parenthesis">)</span> <span class="operator">=</span><span class="angle">></span> <span class="parenthesis">(</span><span class="brace">{</span> |
41 | <span class="punctuation">$</span>crate<span class="punctuation">:</span><span class="punctuation">:</span>io<span class="punctuation">:</span><span class="punctuation">:</span>_print<span class="punctuation">(</span><span class="punctuation">$</span>crate<span class="punctuation">:</span><span class="punctuation">:</span>format_args_nl<span class="punctuation">!</span><span class="punctuation">(</span><span class="punctuation">$</span><span class="punctuation">(</span><span class="punctuation">$</span>arg<span class="punctuation">)</span><span class="punctuation">*</span><span class="punctuation">)</span><span class="punctuation">)</span><span class="punctuation">;</span> | 41 | <span class="punctuation">$</span>crate<span class="colon">:</span><span class="colon">:</span>io<span class="colon">:</span><span class="colon">:</span>_print<span class="parenthesis">(</span><span class="punctuation">$</span>crate<span class="colon">:</span><span class="colon">:</span>format_args_nl<span class="punctuation">!</span><span class="parenthesis">(</span><span class="punctuation">$</span><span class="parenthesis">(</span><span class="punctuation">$</span>arg<span class="parenthesis">)</span><span class="punctuation">*</span><span class="parenthesis">)</span><span class="parenthesis">)</span><span class="semicolon">;</span> |
42 | <span class="punctuation">}</span><span class="punctuation">)</span> | 42 | <span class="brace">}</span><span class="parenthesis">)</span> |
43 | <span class="punctuation">}</span> | 43 | <span class="brace">}</span> |
44 | <span class="attribute attribute">#</span><span class="attribute attribute">[</span><span class="function attribute">rustc_builtin_macro</span><span class="attribute attribute">]</span> | 44 | <span class="attribute attribute">#</span><span class="attribute attribute">[</span><span class="function attribute">rustc_builtin_macro</span><span class="attribute attribute">]</span> |
45 | <span class="keyword">macro_rules</span><span class="punctuation">!</span> <span class="macro declaration">format_args_nl</span> <span class="punctuation">{</span> | 45 | <span class="keyword">macro_rules</span><span class="punctuation">!</span> <span class="macro declaration">format_args_nl</span> <span class="brace">{</span> |
46 | <span class="punctuation">(</span><span class="punctuation">$</span>fmt<span class="punctuation">:</span>expr<span class="punctuation">)</span> <span class="operator">=</span><span class="punctuation">></span> <span class="punctuation">{</span><span class="punctuation">{</span> <span class="comment">/* compiler built-in */</span> <span class="punctuation">}</span><span class="punctuation">}</span><span class="punctuation">;</span> | 46 | <span class="parenthesis">(</span><span class="punctuation">$</span>fmt<span class="colon">:</span>expr<span class="parenthesis">)</span> <span class="operator">=</span><span class="angle">></span> <span class="brace">{</span><span class="brace">{</span> <span class="comment">/* compiler built-in */</span> <span class="brace">}</span><span class="brace">}</span><span class="semicolon">;</span> |
47 | <span class="punctuation">(</span><span class="punctuation">$</span>fmt<span class="punctuation">:</span>expr<span class="punctuation">,</span> <span class="punctuation">$</span><span class="punctuation">(</span><span class="punctuation">$</span>args<span class="punctuation">:</span>tt<span class="punctuation">)</span><span class="punctuation">*</span><span class="punctuation">)</span> <span class="operator">=</span><span class="punctuation">></span> <span class="punctuation">{</span><span class="punctuation">{</span> <span class="comment">/* compiler built-in */</span> <span class="punctuation">}</span><span class="punctuation">}</span><span class="punctuation">;</span> | 47 | <span class="parenthesis">(</span><span class="punctuation">$</span>fmt<span class="colon">:</span>expr<span class="comma">,</span> <span class="punctuation">$</span><span class="parenthesis">(</span><span class="punctuation">$</span>args<span class="colon">:</span>tt<span class="parenthesis">)</span><span class="punctuation">*</span><span class="parenthesis">)</span> <span class="operator">=</span><span class="angle">></span> <span class="brace">{</span><span class="brace">{</span> <span class="comment">/* compiler built-in */</span> <span class="brace">}</span><span class="brace">}</span><span class="semicolon">;</span> |
48 | <span class="punctuation">}</span> | 48 | <span class="brace">}</span> |
49 | 49 | ||
50 | <span class="keyword">fn</span> <span class="function declaration">main</span><span class="punctuation">(</span><span class="punctuation">)</span> <span class="punctuation">{</span> | 50 | <span class="keyword">fn</span> <span class="function declaration">main</span><span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="brace">{</span> |
51 | <span class="comment">// from https://doc.rust-lang.org/std/fmt/index.html</span> | 51 | <span class="comment">// from https://doc.rust-lang.org/std/fmt/index.html</span> |
52 | <span class="macro">println!</span><span class="punctuation">(</span><span class="string_literal">"Hello"</span><span class="punctuation">)</span><span class="punctuation">;</span> <span class="comment">// => "Hello"</span> | 52 | <span class="macro">println!</span><span class="parenthesis">(</span><span class="string_literal">"Hello"</span><span class="parenthesis">)</span><span class="semicolon">;</span> <span class="comment">// => "Hello"</span> |
53 | <span class="macro">println!</span><span class="punctuation">(</span><span class="string_literal">"Hello, </span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal">!"</span><span class="punctuation">,</span> <span class="string_literal">"world"</span><span class="punctuation">)</span><span class="punctuation">;</span> <span class="comment">// => "Hello, world!"</span> | 53 | <span class="macro">println!</span><span class="parenthesis">(</span><span class="string_literal">"Hello, </span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal">!"</span><span class="comma">,</span> <span class="string_literal">"world"</span><span class="parenthesis">)</span><span class="semicolon">;</span> <span class="comment">// => "Hello, world!"</span> |
54 | <span class="macro">println!</span><span class="punctuation">(</span><span class="string_literal">"The number is </span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal">"</span><span class="punctuation">,</span> <span class="numeric_literal">1</span><span class="punctuation">)</span><span class="punctuation">;</span> <span class="comment">// => "The number is 1"</span> | 54 | <span class="macro">println!</span><span class="parenthesis">(</span><span class="string_literal">"The number is </span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal">"</span><span class="comma">,</span> <span class="numeric_literal">1</span><span class="parenthesis">)</span><span class="semicolon">;</span> <span class="comment">// => "The number is 1"</span> |
55 | <span class="macro">println!</span><span class="punctuation">(</span><span class="string_literal">"</span><span class="format_specifier">{</span><span class="format_specifier">:</span><span class="format_specifier">?</span><span class="format_specifier">}</span><span class="string_literal">"</span><span class="punctuation">,</span> <span class="punctuation">(</span><span class="numeric_literal">3</span><span class="punctuation">,</span> <span class="numeric_literal">4</span><span class="punctuation">)</span><span class="punctuation">)</span><span class="punctuation">;</span> <span class="comment">// => "(3, 4)"</span> | 55 | <span class="macro">println!</span><span class="parenthesis">(</span><span class="string_literal">"</span><span class="format_specifier">{</span><span class="format_specifier">:</span><span class="format_specifier">?</span><span class="format_specifier">}</span><span class="string_literal">"</span><span class="comma">,</span> <span class="parenthesis">(</span><span class="numeric_literal">3</span><span class="comma">,</span> <span class="numeric_literal">4</span><span class="parenthesis">)</span><span class="parenthesis">)</span><span class="semicolon">;</span> <span class="comment">// => "(3, 4)"</span> |
56 | <span class="macro">println!</span><span class="punctuation">(</span><span class="string_literal">"</span><span class="format_specifier">{</span><span class="variable">value</span><span class="format_specifier">}</span><span class="string_literal">"</span><span class="punctuation">,</span> value<span class="operator">=</span><span class="numeric_literal">4</span><span class="punctuation">)</span><span class="punctuation">;</span> <span class="comment">// => "4"</span> | 56 | <span class="macro">println!</span><span class="parenthesis">(</span><span class="string_literal">"</span><span class="format_specifier">{</span><span class="variable">value</span><span class="format_specifier">}</span><span class="string_literal">"</span><span class="comma">,</span> value<span class="operator">=</span><span class="numeric_literal">4</span><span class="parenthesis">)</span><span class="semicolon">;</span> <span class="comment">// => "4"</span> |
57 | <span class="macro">println!</span><span class="punctuation">(</span><span class="string_literal">"</span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal"> </span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal">"</span><span class="punctuation">,</span> <span class="numeric_literal">1</span><span class="punctuation">,</span> <span class="numeric_literal">2</span><span class="punctuation">)</span><span class="punctuation">;</span> <span class="comment">// => "1 2"</span> | 57 | <span class="macro">println!</span><span class="parenthesis">(</span><span class="string_literal">"</span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal"> </span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal">"</span><span class="comma">,</span> <span class="numeric_literal">1</span><span class="comma">,</span> <span class="numeric_literal">2</span><span class="parenthesis">)</span><span class="semicolon">;</span> <span class="comment">// => "1 2"</span> |
58 | <span class="macro">println!</span><span class="punctuation">(</span><span class="string_literal">"</span><span class="format_specifier">{</span><span class="format_specifier">:</span><span class="numeric_literal">0</span><span class="numeric_literal">4</span><span class="format_specifier">}</span><span class="string_literal">"</span><span class="punctuation">,</span> <span class="numeric_literal">42</span><span class="punctuation">)</span><span class="punctuation">;</span> <span class="comment">// => "0042" with leading zerosV</span> | 58 | <span class="macro">println!</span><span class="parenthesis">(</span><span class="string_literal">"</span><span class="format_specifier">{</span><span class="format_specifier">:</span><span class="numeric_literal">0</span><span class="numeric_literal">4</span><span class="format_specifier">}</span><span class="string_literal">"</span><span class="comma">,</span> <span class="numeric_literal">42</span><span class="parenthesis">)</span><span class="semicolon">;</span> <span class="comment">// => "0042" with leading zerosV</span> |
59 | <span class="macro">println!</span><span class="punctuation">(</span><span class="string_literal">"</span><span class="format_specifier">{</span><span class="numeric_literal">1</span><span class="format_specifier">}</span><span class="string_literal"> </span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal"> </span><span class="format_specifier">{</span><span class="numeric_literal">0</span><span class="format_specifier">}</span><span class="string_literal"> </span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal">"</span><span class="punctuation">,</span> <span class="numeric_literal">1</span><span class="punctuation">,</span> <span class="numeric_literal">2</span><span class="punctuation">)</span><span class="punctuation">;</span> <span class="comment">// => "2 1 1 2"</span> | 59 | <span class="macro">println!</span><span class="parenthesis">(</span><span class="string_literal">"</span><span class="format_specifier">{</span><span class="numeric_literal">1</span><span class="format_specifier">}</span><span class="string_literal"> </span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal"> </span><span class="format_specifier">{</span><span class="numeric_literal">0</span><span class="format_specifier">}</span><span class="string_literal"> </span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal">"</span><span class="comma">,</span> <span class="numeric_literal">1</span><span class="comma">,</span> <span class="numeric_literal">2</span><span class="parenthesis">)</span><span class="semicolon">;</span> <span class="comment">// => "2 1 1 2"</span> |
60 | <span class="macro">println!</span><span class="punctuation">(</span><span class="string_literal">"</span><span class="format_specifier">{</span><span class="variable">argument</span><span class="format_specifier">}</span><span class="string_literal">"</span><span class="punctuation">,</span> argument <span class="operator">=</span> <span class="string_literal">"test"</span><span class="punctuation">)</span><span class="punctuation">;</span> <span class="comment">// => "test"</span> | 60 | <span class="macro">println!</span><span class="parenthesis">(</span><span class="string_literal">"</span><span class="format_specifier">{</span><span class="variable">argument</span><span class="format_specifier">}</span><span class="string_literal">"</span><span class="comma">,</span> argument <span class="operator">=</span> <span class="string_literal">"test"</span><span class="parenthesis">)</span><span class="semicolon">;</span> <span class="comment">// => "test"</span> |
61 | <span class="macro">println!</span><span class="punctuation">(</span><span class="string_literal">"</span><span class="format_specifier">{</span><span class="variable">name</span><span class="format_specifier">}</span><span class="string_literal"> </span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal">"</span><span class="punctuation">,</span> <span class="numeric_literal">1</span><span class="punctuation">,</span> name <span class="operator">=</span> <span class="numeric_literal">2</span><span class="punctuation">)</span><span class="punctuation">;</span> <span class="comment">// => "2 1"</span> | 61 | <span class="macro">println!</span><span class="parenthesis">(</span><span class="string_literal">"</span><span class="format_specifier">{</span><span class="variable">name</span><span class="format_specifier">}</span><span class="string_literal"> </span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal">"</span><span class="comma">,</span> <span class="numeric_literal">1</span><span class="comma">,</span> name <span class="operator">=</span> <span class="numeric_literal">2</span><span class="parenthesis">)</span><span class="semicolon">;</span> <span class="comment">// => "2 1"</span> |
62 | <span class="macro">println!</span><span class="punctuation">(</span><span class="string_literal">"</span><span class="format_specifier">{</span><span class="variable">a</span><span class="format_specifier">}</span><span class="string_literal"> </span><span class="format_specifier">{</span><span class="variable">c</span><span class="format_specifier">}</span><span class="string_literal"> </span><span class="format_specifier">{</span><span class="variable">b</span><span class="format_specifier">}</span><span class="string_literal">"</span><span class="punctuation">,</span> a<span class="operator">=</span><span class="string_literal">"a"</span><span class="punctuation">,</span> b<span class="operator">=</span><span class="char_literal">'b'</span><span class="punctuation">,</span> c<span class="operator">=</span><span class="numeric_literal">3</span><span class="punctuation">)</span><span class="punctuation">;</span> <span class="comment">// => "a 3 b"</span> | 62 | <span class="macro">println!</span><span class="parenthesis">(</span><span class="string_literal">"</span><span class="format_specifier">{</span><span class="variable">a</span><span class="format_specifier">}</span><span class="string_literal"> </span><span class="format_specifier">{</span><span class="variable">c</span><span class="format_specifier">}</span><span class="string_literal"> </span><span class="format_specifier">{</span><span class="variable">b</span><span class="format_specifier">}</span><span class="string_literal">"</span><span class="comma">,</span> a<span class="operator">=</span><span class="string_literal">"a"</span><span class="comma">,</span> b<span class="operator">=</span><span class="char_literal">'b'</span><span class="comma">,</span> c<span class="operator">=</span><span class="numeric_literal">3</span><span class="parenthesis">)</span><span class="semicolon">;</span> <span class="comment">// => "a 3 b"</span> |
63 | <span class="macro">println!</span><span class="punctuation">(</span><span class="string_literal">"{{</span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal">}}"</span><span class="punctuation">,</span> <span class="numeric_literal">2</span><span class="punctuation">)</span><span class="punctuation">;</span> <span class="comment">// => "{2}"</span> | 63 | <span class="macro">println!</span><span class="parenthesis">(</span><span class="string_literal">"{{</span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal">}}"</span><span class="comma">,</span> <span class="numeric_literal">2</span><span class="parenthesis">)</span><span class="semicolon">;</span> <span class="comment">// => "{2}"</span> |
64 | <span class="macro">println!</span><span class="punctuation">(</span><span class="string_literal">"Hello </span><span class="format_specifier">{</span><span class="format_specifier">:</span><span class="numeric_literal">5</span><span class="format_specifier">}</span><span class="string_literal">!"</span><span class="punctuation">,</span> <span class="string_literal">"x"</span><span class="punctuation">)</span><span class="punctuation">;</span> | 64 | <span class="macro">println!</span><span class="parenthesis">(</span><span class="string_literal">"Hello </span><span class="format_specifier">{</span><span class="format_specifier">:</span><span class="numeric_literal">5</span><span class="format_specifier">}</span><span class="string_literal">!"</span><span class="comma">,</span> <span class="string_literal">"x"</span><span class="parenthesis">)</span><span class="semicolon">;</span> |
65 | <span class="macro">println!</span><span class="punctuation">(</span><span class="string_literal">"Hello </span><span class="format_specifier">{</span><span class="format_specifier">:</span><span class="numeric_literal">1</span><span class="format_specifier">$</span><span class="format_specifier">}</span><span class="string_literal">!"</span><span class="punctuation">,</span> <span class="string_literal">"x"</span><span class="punctuation">,</span> <span class="numeric_literal">5</span><span class="punctuation">)</span><span class="punctuation">;</span> | 65 | <span class="macro">println!</span><span class="parenthesis">(</span><span class="string_literal">"Hello </span><span class="format_specifier">{</span><span class="format_specifier">:</span><span class="numeric_literal">1</span><span class="format_specifier">$</span><span class="format_specifier">}</span><span class="string_literal">!"</span><span class="comma">,</span> <span class="string_literal">"x"</span><span class="comma">,</span> <span class="numeric_literal">5</span><span class="parenthesis">)</span><span class="semicolon">;</span> |
66 | <span class="macro">println!</span><span class="punctuation">(</span><span class="string_literal">"Hello </span><span class="format_specifier">{</span><span class="numeric_literal">1</span><span class="format_specifier">:</span><span class="numeric_literal">0</span><span class="format_specifier">$</span><span class="format_specifier">}</span><span class="string_literal">!"</span><span class="punctuation">,</span> <span class="numeric_literal">5</span><span class="punctuation">,</span> <span class="string_literal">"x"</span><span class="punctuation">)</span><span class="punctuation">;</span> | 66 | <span class="macro">println!</span><span class="parenthesis">(</span><span class="string_literal">"Hello </span><span class="format_specifier">{</span><span class="numeric_literal">1</span><span class="format_specifier">:</span><span class="numeric_literal">0</span><span class="format_specifier">$</span><span class="format_specifier">}</span><span class="string_literal">!"</span><span class="comma">,</span> <span class="numeric_literal">5</span><span class="comma">,</span> <span class="string_literal">"x"</span><span class="parenthesis">)</span><span class="semicolon">;</span> |
67 | <span class="macro">println!</span><span class="punctuation">(</span><span class="string_literal">"Hello </span><span class="format_specifier">{</span><span class="format_specifier">:</span><span class="variable">width</span><span class="format_specifier">$</span><span class="format_specifier">}</span><span class="string_literal">!"</span><span class="punctuation">,</span> <span class="string_literal">"x"</span><span class="punctuation">,</span> width <span class="operator">=</span> <span class="numeric_literal">5</span><span class="punctuation">)</span><span class="punctuation">;</span> | 67 | <span class="macro">println!</span><span class="parenthesis">(</span><span class="string_literal">"Hello </span><span class="format_specifier">{</span><span class="format_specifier">:</span><span class="variable">width</span><span class="format_specifier">$</span><span class="format_specifier">}</span><span class="string_literal">!"</span><span class="comma">,</span> <span class="string_literal">"x"</span><span class="comma">,</span> width <span class="operator">=</span> <span class="numeric_literal">5</span><span class="parenthesis">)</span><span class="semicolon">;</span> |
68 | <span class="macro">println!</span><span class="punctuation">(</span><span class="string_literal">"Hello </span><span class="format_specifier">{</span><span class="format_specifier">:</span><span class="format_specifier"><</span><span class="numeric_literal">5</span><span class="format_specifier">}</span><span class="string_literal">!"</span><span class="punctuation">,</span> <span class="string_literal">"x"</span><span class="punctuation">)</span><span class="punctuation">;</span> | 68 | <span class="macro">println!</span><span class="parenthesis">(</span><span class="string_literal">"Hello </span><span class="format_specifier">{</span><span class="format_specifier">:</span><span class="format_specifier"><</span><span class="numeric_literal">5</span><span class="format_specifier">}</span><span class="string_literal">!"</span><span class="comma">,</span> <span class="string_literal">"x"</span><span class="parenthesis">)</span><span class="semicolon">;</span> |
69 | <span class="macro">println!</span><span class="punctuation">(</span><span class="string_literal">"Hello </span><span class="format_specifier">{</span><span class="format_specifier">:</span><span class="format_specifier">-</span><span class="format_specifier"><</span><span class="numeric_literal">5</span><span class="format_specifier">}</span><span class="string_literal">!"</span><span class="punctuation">,</span> <span class="string_literal">"x"</span><span class="punctuation">)</span><span class="punctuation">;</span> | 69 | <span class="macro">println!</span><span class="parenthesis">(</span><span class="string_literal">"Hello </span><span class="format_specifier">{</span><span class="format_specifier">:</span><span class="format_specifier">-</span><span class="format_specifier"><</span><span class="numeric_literal">5</span><span class="format_specifier">}</span><span class="string_literal">!"</span><span class="comma">,</span> <span class="string_literal">"x"</span><span class="parenthesis">)</span><span class="semicolon">;</span> |
70 | <span class="macro">println!</span><span class="punctuation">(</span><span class="string_literal">"Hello </span><span class="format_specifier">{</span><span class="format_specifier">:</span><span class="format_specifier">^</span><span class="numeric_literal">5</span><span class="format_specifier">}</span><span class="string_literal">!"</span><span class="punctuation">,</span> <span class="string_literal">"x"</span><span class="punctuation">)</span><span class="punctuation">;</span> | 70 | <span class="macro">println!</span><span class="parenthesis">(</span><span class="string_literal">"Hello </span><span class="format_specifier">{</span><span class="format_specifier">:</span><span class="format_specifier">^</span><span class="numeric_literal">5</span><span class="format_specifier">}</span><span class="string_literal">!"</span><span class="comma">,</span> <span class="string_literal">"x"</span><span class="parenthesis">)</span><span class="semicolon">;</span> |
71 | <span class="macro">println!</span><span class="punctuation">(</span><span class="string_literal">"Hello </span><span class="format_specifier">{</span><span class="format_specifier">:</span><span class="format_specifier">></span><span class="numeric_literal">5</span><span class="format_specifier">}</span><span class="string_literal">!"</span><span class="punctuation">,</span> <span class="string_literal">"x"</span><span class="punctuation">)</span><span class="punctuation">;</span> | 71 | <span class="macro">println!</span><span class="parenthesis">(</span><span class="string_literal">"Hello </span><span class="format_specifier">{</span><span class="format_specifier">:</span><span class="format_specifier">></span><span class="numeric_literal">5</span><span class="format_specifier">}</span><span class="string_literal">!"</span><span class="comma">,</span> <span class="string_literal">"x"</span><span class="parenthesis">)</span><span class="semicolon">;</span> |
72 | <span class="macro">println!</span><span class="punctuation">(</span><span class="string_literal">"Hello </span><span class="format_specifier">{</span><span class="format_specifier">:</span><span class="format_specifier">+</span><span class="format_specifier">}</span><span class="string_literal">!"</span><span class="punctuation">,</span> <span class="numeric_literal">5</span><span class="punctuation">)</span><span class="punctuation">;</span> | 72 | <span class="macro">println!</span><span class="parenthesis">(</span><span class="string_literal">"Hello </span><span class="format_specifier">{</span><span class="format_specifier">:</span><span class="format_specifier">+</span><span class="format_specifier">}</span><span class="string_literal">!"</span><span class="comma">,</span> <span class="numeric_literal">5</span><span class="parenthesis">)</span><span class="semicolon">;</span> |
73 | <span class="macro">println!</span><span class="punctuation">(</span><span class="string_literal">"</span><span class="format_specifier">{</span><span class="format_specifier">:</span><span class="format_specifier">#</span><span class="variable">x</span><span class="format_specifier">}</span><span class="string_literal">!"</span><span class="punctuation">,</span> <span class="numeric_literal">27</span><span class="punctuation">)</span><span class="punctuation">;</span> | 73 | <span class="macro">println!</span><span class="parenthesis">(</span><span class="string_literal">"</span><span class="format_specifier">{</span><span class="format_specifier">:</span><span class="format_specifier">#</span><span class="variable">x</span><span class="format_specifier">}</span><span class="string_literal">!"</span><span class="comma">,</span> <span class="numeric_literal">27</span><span class="parenthesis">)</span><span class="semicolon">;</span> |
74 | <span class="macro">println!</span><span class="punctuation">(</span><span class="string_literal">"Hello </span><span class="format_specifier">{</span><span class="format_specifier">:</span><span class="numeric_literal">0</span><span class="numeric_literal">5</span><span class="format_specifier">}</span><span class="string_literal">!"</span><span class="punctuation">,</span> <span class="numeric_literal">5</span><span class="punctuation">)</span><span class="punctuation">;</span> | 74 | <span class="macro">println!</span><span class="parenthesis">(</span><span class="string_literal">"Hello </span><span class="format_specifier">{</span><span class="format_specifier">:</span><span class="numeric_literal">0</span><span class="numeric_literal">5</span><span class="format_specifier">}</span><span class="string_literal">!"</span><span class="comma">,</span> <span class="numeric_literal">5</span><span class="parenthesis">)</span><span class="semicolon">;</span> |
75 | <span class="macro">println!</span><span class="punctuation">(</span><span class="string_literal">"Hello </span><span class="format_specifier">{</span><span class="format_specifier">:</span><span class="numeric_literal">0</span><span class="numeric_literal">5</span><span class="format_specifier">}</span><span class="string_literal">!"</span><span class="punctuation">,</span> <span class="punctuation">-</span><span class="numeric_literal">5</span><span class="punctuation">)</span><span class="punctuation">;</span> | 75 | <span class="macro">println!</span><span class="parenthesis">(</span><span class="string_literal">"Hello </span><span class="format_specifier">{</span><span class="format_specifier">:</span><span class="numeric_literal">0</span><span class="numeric_literal">5</span><span class="format_specifier">}</span><span class="string_literal">!"</span><span class="comma">,</span> <span class="punctuation">-</span><span class="numeric_literal">5</span><span class="parenthesis">)</span><span class="semicolon">;</span> |
76 | <span class="macro">println!</span><span class="punctuation">(</span><span class="string_literal">"</span><span class="format_specifier">{</span><span class="format_specifier">:</span><span class="format_specifier">#</span><span class="numeric_literal">0</span><span class="numeric_literal">10</span><span class="variable">x</span><span class="format_specifier">}</span><span class="string_literal">!"</span><span class="punctuation">,</span> <span class="numeric_literal">27</span><span class="punctuation">)</span><span class="punctuation">;</span> | 76 | <span class="macro">println!</span><span class="parenthesis">(</span><span class="string_literal">"</span><span class="format_specifier">{</span><span class="format_specifier">:</span><span class="format_specifier">#</span><span class="numeric_literal">0</span><span class="numeric_literal">10</span><span class="variable">x</span><span class="format_specifier">}</span><span class="string_literal">!"</span><span class="comma">,</span> <span class="numeric_literal">27</span><span class="parenthesis">)</span><span class="semicolon">;</span> |
77 | <span class="macro">println!</span><span class="punctuation">(</span><span class="string_literal">"Hello </span><span class="format_specifier">{</span><span class="numeric_literal">0</span><span class="format_specifier">}</span><span class="string_literal"> is </span><span class="format_specifier">{</span><span class="numeric_literal">1</span><span class="format_specifier">:</span><span class="format_specifier">.</span><span class="numeric_literal">5</span><span class="format_specifier">}</span><span class="string_literal">"</span><span class="punctuation">,</span> <span class="string_literal">"x"</span><span class="punctuation">,</span> <span class="numeric_literal">0.01</span><span class="punctuation">)</span><span class="punctuation">;</span> | 77 | <span class="macro">println!</span><span class="parenthesis">(</span><span class="string_literal">"Hello </span><span class="format_specifier">{</span><span class="numeric_literal">0</span><span class="format_specifier">}</span><span class="string_literal"> is </span><span class="format_specifier">{</span><span class="numeric_literal">1</span><span class="format_specifier">:</span><span class="format_specifier">.</span><span class="numeric_literal">5</span><span class="format_specifier">}</span><span class="string_literal">"</span><span class="comma">,</span> <span class="string_literal">"x"</span><span class="comma">,</span> <span class="numeric_literal">0.01</span><span class="parenthesis">)</span><span class="semicolon">;</span> |
78 | <span class="macro">println!</span><span class="punctuation">(</span><span class="string_literal">"Hello </span><span class="format_specifier">{</span><span class="numeric_literal">1</span><span class="format_specifier">}</span><span class="string_literal"> is </span><span class="format_specifier">{</span><span class="numeric_literal">2</span><span class="format_specifier">:</span><span class="format_specifier">.</span><span class="numeric_literal">0</span><span class="format_specifier">$</span><span class="format_specifier">}</span><span class="string_literal">"</span><span class="punctuation">,</span> <span class="numeric_literal">5</span><span class="punctuation">,</span> <span class="string_literal">"x"</span><span class="punctuation">,</span> <span class="numeric_literal">0.01</span><span class="punctuation">)</span><span class="punctuation">;</span> | 78 | <span class="macro">println!</span><span class="parenthesis">(</span><span class="string_literal">"Hello </span><span class="format_specifier">{</span><span class="numeric_literal">1</span><span class="format_specifier">}</span><span class="string_literal"> is </span><span class="format_specifier">{</span><span class="numeric_literal">2</span><span class="format_specifier">:</span><span class="format_specifier">.</span><span class="numeric_literal">0</span><span class="format_specifier">$</span><span class="format_specifier">}</span><span class="string_literal">"</span><span class="comma">,</span> <span class="numeric_literal">5</span><span class="comma">,</span> <span class="string_literal">"x"</span><span class="comma">,</span> <span class="numeric_literal">0.01</span><span class="parenthesis">)</span><span class="semicolon">;</span> |
79 | <span class="macro">println!</span><span class="punctuation">(</span><span class="string_literal">"Hello </span><span class="format_specifier">{</span><span class="numeric_literal">0</span><span class="format_specifier">}</span><span class="string_literal"> is </span><span class="format_specifier">{</span><span class="numeric_literal">2</span><span class="format_specifier">:</span><span class="format_specifier">.</span><span class="numeric_literal">1</span><span class="format_specifier">$</span><span class="format_specifier">}</span><span class="string_literal">"</span><span class="punctuation">,</span> <span class="string_literal">"x"</span><span class="punctuation">,</span> <span class="numeric_literal">5</span><span class="punctuation">,</span> <span class="numeric_literal">0.01</span><span class="punctuation">)</span><span class="punctuation">;</span> | 79 | <span class="macro">println!</span><span class="parenthesis">(</span><span class="string_literal">"Hello </span><span class="format_specifier">{</span><span class="numeric_literal">0</span><span class="format_specifier">}</span><span class="string_literal"> is </span><span class="format_specifier">{</span><span class="numeric_literal">2</span><span class="format_specifier">:</span><span class="format_specifier">.</span><span class="numeric_literal">1</span><span class="format_specifier">$</span><span class="format_specifier">}</span><span class="string_literal">"</span><span class="comma">,</span> <span class="string_literal">"x"</span><span class="comma">,</span> <span class="numeric_literal">5</span><span class="comma">,</span> <span class="numeric_literal">0.01</span><span class="parenthesis">)</span><span class="semicolon">;</span> |
80 | <span class="macro">println!</span><span class="punctuation">(</span><span class="string_literal">"Hello </span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal"> is </span><span class="format_specifier">{</span><span class="format_specifier">:</span><span class="format_specifier">.</span><span class="format_specifier">*</span><span class="format_specifier">}</span><span class="string_literal">"</span><span class="punctuation">,</span> <span class="string_literal">"x"</span><span class="punctuation">,</span> <span class="numeric_literal">5</span><span class="punctuation">,</span> <span class="numeric_literal">0.01</span><span class="punctuation">)</span><span class="punctuation">;</span> | 80 | <span class="macro">println!</span><span class="parenthesis">(</span><span class="string_literal">"Hello </span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal"> is </span><span class="format_specifier">{</span><span class="format_specifier">:</span><span class="format_specifier">.</span><span class="format_specifier">*</span><span class="format_specifier">}</span><span class="string_literal">"</span><span class="comma">,</span> <span class="string_literal">"x"</span><span class="comma">,</span> <span class="numeric_literal">5</span><span class="comma">,</span> <span class="numeric_literal">0.01</span><span class="parenthesis">)</span><span class="semicolon">;</span> |
81 | <span class="macro">println!</span><span class="punctuation">(</span><span class="string_literal">"Hello </span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal"> is </span><span class="format_specifier">{</span><span class="numeric_literal">2</span><span class="format_specifier">:</span><span class="format_specifier">.</span><span class="format_specifier">*</span><span class="format_specifier">}</span><span class="string_literal">"</span><span class="punctuation">,</span> <span class="string_literal">"x"</span><span class="punctuation">,</span> <span class="numeric_literal">5</span><span class="punctuation">,</span> <span class="numeric_literal">0.01</span><span class="punctuation">)</span><span class="punctuation">;</span> | 81 | <span class="macro">println!</span><span class="parenthesis">(</span><span class="string_literal">"Hello </span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal"> is </span><span class="format_specifier">{</span><span class="numeric_literal">2</span><span class="format_specifier">:</span><span class="format_specifier">.</span><span class="format_specifier">*</span><span class="format_specifier">}</span><span class="string_literal">"</span><span class="comma">,</span> <span class="string_literal">"x"</span><span class="comma">,</span> <span class="numeric_literal">5</span><span class="comma">,</span> <span class="numeric_literal">0.01</span><span class="parenthesis">)</span><span class="semicolon">;</span> |
82 | <span class="macro">println!</span><span class="punctuation">(</span><span class="string_literal">"Hello </span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal"> is </span><span class="format_specifier">{</span><span class="variable">number</span><span class="format_specifier">:</span><span class="format_specifier">.</span><span class="variable">prec</span><span class="format_specifier">$</span><span class="format_specifier">}</span><span class="string_literal">"</span><span class="punctuation">,</span> <span class="string_literal">"x"</span><span class="punctuation">,</span> prec <span class="operator">=</span> <span class="numeric_literal">5</span><span class="punctuation">,</span> number <span class="operator">=</span> <span class="numeric_literal">0.01</span><span class="punctuation">)</span><span class="punctuation">;</span> | 82 | <span class="macro">println!</span><span class="parenthesis">(</span><span class="string_literal">"Hello </span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal"> is </span><span class="format_specifier">{</span><span class="variable">number</span><span class="format_specifier">:</span><span class="format_specifier">.</span><span class="variable">prec</span><span class="format_specifier">$</span><span class="format_specifier">}</span><span class="string_literal">"</span><span class="comma">,</span> <span class="string_literal">"x"</span><span class="comma">,</span> prec <span class="operator">=</span> <span class="numeric_literal">5</span><span class="comma">,</span> number <span class="operator">=</span> <span class="numeric_literal">0.01</span><span class="parenthesis">)</span><span class="semicolon">;</span> |
83 | <span class="macro">println!</span><span class="punctuation">(</span><span class="string_literal">"</span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal">, `</span><span class="format_specifier">{</span><span class="variable">name</span><span class="format_specifier">:</span><span class="format_specifier">.</span><span class="format_specifier">*</span><span class="format_specifier">}</span><span class="string_literal">` has 3 fractional digits"</span><span class="punctuation">,</span> <span class="string_literal">"Hello"</span><span class="punctuation">,</span> <span class="numeric_literal">3</span><span class="punctuation">,</span> name<span class="operator">=</span><span class="numeric_literal">1234.56</span><span class="punctuation">)</span><span class="punctuation">;</span> | 83 | <span class="macro">println!</span><span class="parenthesis">(</span><span class="string_literal">"</span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal">, `</span><span class="format_specifier">{</span><span class="variable">name</span><span class="format_specifier">:</span><span class="format_specifier">.</span><span class="format_specifier">*</span><span class="format_specifier">}</span><span class="string_literal">` has 3 fractional digits"</span><span class="comma">,</span> <span class="string_literal">"Hello"</span><span class="comma">,</span> <span class="numeric_literal">3</span><span class="comma">,</span> name<span class="operator">=</span><span class="numeric_literal">1234.56</span><span class="parenthesis">)</span><span class="semicolon">;</span> |
84 | <span class="macro">println!</span><span class="punctuation">(</span><span class="string_literal">"</span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal">, `</span><span class="format_specifier">{</span><span class="variable">name</span><span class="format_specifier">:</span><span class="format_specifier">.</span><span class="format_specifier">*</span><span class="format_specifier">}</span><span class="string_literal">` has 3 characters"</span><span class="punctuation">,</span> <span class="string_literal">"Hello"</span><span class="punctuation">,</span> <span class="numeric_literal">3</span><span class="punctuation">,</span> name<span class="operator">=</span><span class="string_literal">"1234.56"</span><span class="punctuation">)</span><span class="punctuation">;</span> | 84 | <span class="macro">println!</span><span class="parenthesis">(</span><span class="string_literal">"</span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal">, `</span><span class="format_specifier">{</span><span class="variable">name</span><span class="format_specifier">:</span><span class="format_specifier">.</span><span class="format_specifier">*</span><span class="format_specifier">}</span><span class="string_literal">` has 3 characters"</span><span class="comma">,</span> <span class="string_literal">"Hello"</span><span class="comma">,</span> <span class="numeric_literal">3</span><span class="comma">,</span> name<span class="operator">=</span><span class="string_literal">"1234.56"</span><span class="parenthesis">)</span><span class="semicolon">;</span> |
85 | <span class="macro">println!</span><span class="punctuation">(</span><span class="string_literal">"</span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal">, `</span><span class="format_specifier">{</span><span class="variable">name</span><span class="format_specifier">:</span><span class="format_specifier">></span><span class="numeric_literal">8</span><span class="format_specifier">.</span><span class="format_specifier">*</span><span class="format_specifier">}</span><span class="string_literal">` has 3 right-aligned characters"</span><span class="punctuation">,</span> <span class="string_literal">"Hello"</span><span class="punctuation">,</span> <span class="numeric_literal">3</span><span class="punctuation">,</span> name<span class="operator">=</span><span class="string_literal">"1234.56"</span><span class="punctuation">)</span><span class="punctuation">;</span> | 85 | <span class="macro">println!</span><span class="parenthesis">(</span><span class="string_literal">"</span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal">, `</span><span class="format_specifier">{</span><span class="variable">name</span><span class="format_specifier">:</span><span class="format_specifier">></span><span class="numeric_literal">8</span><span class="format_specifier">.</span><span class="format_specifier">*</span><span class="format_specifier">}</span><span class="string_literal">` has 3 right-aligned characters"</span><span class="comma">,</span> <span class="string_literal">"Hello"</span><span class="comma">,</span> <span class="numeric_literal">3</span><span class="comma">,</span> name<span class="operator">=</span><span class="string_literal">"1234.56"</span><span class="parenthesis">)</span><span class="semicolon">;</span> |
86 | <span class="macro">println!</span><span class="punctuation">(</span><span class="string_literal">"Hello {{}}"</span><span class="punctuation">)</span><span class="punctuation">;</span> | 86 | <span class="macro">println!</span><span class="parenthesis">(</span><span class="string_literal">"Hello {{}}"</span><span class="parenthesis">)</span><span class="semicolon">;</span> |
87 | <span class="macro">println!</span><span class="punctuation">(</span><span class="string_literal">"{{ Hello"</span><span class="punctuation">)</span><span class="punctuation">;</span> | 87 | <span class="macro">println!</span><span class="parenthesis">(</span><span class="string_literal">"{{ Hello"</span><span class="parenthesis">)</span><span class="semicolon">;</span> |
88 | 88 | ||
89 | <span class="macro">println!</span><span class="punctuation">(</span><span class="string_literal">r"Hello, </span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal">!"</span><span class="punctuation">,</span> <span class="string_literal">"world"</span><span class="punctuation">)</span><span class="punctuation">;</span> | 89 | <span class="macro">println!</span><span class="parenthesis">(</span><span class="string_literal">r"Hello, </span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal">!"</span><span class="comma">,</span> <span class="string_literal">"world"</span><span class="parenthesis">)</span><span class="semicolon">;</span> |
90 | 90 | ||
91 | <span class="comment">// escape sequences</span> | 91 | <span class="comment">// escape sequences</span> |
92 | <span class="macro">println!</span><span class="punctuation">(</span><span class="string_literal">"Hello</span><span class="escape_sequence">\n</span><span class="string_literal">World"</span><span class="punctuation">)</span><span class="punctuation">;</span> | 92 | <span class="macro">println!</span><span class="parenthesis">(</span><span class="string_literal">"Hello</span><span class="escape_sequence">\n</span><span class="string_literal">World"</span><span class="parenthesis">)</span><span class="semicolon">;</span> |
93 | <span class="macro">println!</span><span class="punctuation">(</span><span class="string_literal">"</span><span class="escape_sequence">\u{48}</span><span class="escape_sequence">\x65</span><span class="escape_sequence">\x6C</span><span class="escape_sequence">\x6C</span><span class="escape_sequence">\x6F</span><span class="string_literal"> World"</span><span class="punctuation">)</span><span class="punctuation">;</span> | 93 | <span class="macro">println!</span><span class="parenthesis">(</span><span class="string_literal">"</span><span class="escape_sequence">\u{48}</span><span class="escape_sequence">\x65</span><span class="escape_sequence">\x6C</span><span class="escape_sequence">\x6C</span><span class="escape_sequence">\x6F</span><span class="string_literal"> World"</span><span class="parenthesis">)</span><span class="semicolon">;</span> |
94 | 94 | ||
95 | <span class="macro">println!</span><span class="punctuation">(</span><span class="string_literal">"</span><span class="format_specifier">{</span><span class="escape_sequence">\x41</span><span class="format_specifier">}</span><span class="string_literal">"</span><span class="punctuation">,</span> A <span class="operator">=</span> <span class="numeric_literal">92</span><span class="punctuation">)</span><span class="punctuation">;</span> | 95 | <span class="macro">println!</span><span class="parenthesis">(</span><span class="string_literal">"</span><span class="format_specifier">{</span><span class="escape_sequence">\x41</span><span class="format_specifier">}</span><span class="string_literal">"</span><span class="comma">,</span> A <span class="operator">=</span> <span class="numeric_literal">92</span><span class="parenthesis">)</span><span class="semicolon">;</span> |
96 | <span class="macro">println!</span><span class="punctuation">(</span><span class="string_literal">"</span><span class="format_specifier">{</span><span class="variable">ничоси</span><span class="format_specifier">}</span><span class="string_literal">"</span><span class="punctuation">,</span> ничоси <span class="operator">=</span> <span class="numeric_literal">92</span><span class="punctuation">)</span><span class="punctuation">;</span> | 96 | <span class="macro">println!</span><span class="parenthesis">(</span><span class="string_literal">"</span><span class="format_specifier">{</span><span class="variable">ничоси</span><span class="format_specifier">}</span><span class="string_literal">"</span><span class="comma">,</span> ничоси <span class="operator">=</span> <span class="numeric_literal">92</span><span class="parenthesis">)</span><span class="semicolon">;</span> |
97 | 97 | ||
98 | <span class="macro">println!</span><span class="punctuation">(</span><span class="string_literal">"</span><span class="format_specifier">{</span><span class="format_specifier">:</span><span class="variable">x</span><span class="format_specifier">?</span><span class="format_specifier">}</span><span class="string_literal"> </span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal"> "</span><span class="punctuation">,</span> thingy<span class="punctuation">,</span> n2<span class="punctuation">)</span><span class="punctuation">;</span> | 98 | <span class="macro">println!</span><span class="parenthesis">(</span><span class="string_literal">"</span><span class="format_specifier">{</span><span class="format_specifier">:</span><span class="variable">x</span><span class="format_specifier">?</span><span class="format_specifier">}</span><span class="string_literal"> </span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal"> "</span><span class="comma">,</span> thingy<span class="comma">,</span> n2<span class="parenthesis">)</span><span class="semicolon">;</span> |
99 | <span class="punctuation">}</span></code></pre> \ No newline at end of file | 99 | <span class="brace">}</span></code></pre> \ No newline at end of file |
diff --git a/crates/ide/src/syntax_highlighting/test_data/highlight_unsafe.html b/crates/ide/src/syntax_highlighting/test_data/highlight_unsafe.html index e3a0aa317..9d4d6d4a0 100644 --- a/crates/ide/src/syntax_highlighting/test_data/highlight_unsafe.html +++ b/crates/ide/src/syntax_highlighting/test_data/highlight_unsafe.html | |||
@@ -36,65 +36,65 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd | |||
36 | 36 | ||
37 | .unresolved_reference { color: #FC5555; text-decoration: wavy underline; } | 37 | .unresolved_reference { color: #FC5555; text-decoration: wavy underline; } |
38 | </style> | 38 | </style> |
39 | <pre><code><span class="keyword unsafe">unsafe</span> <span class="keyword">fn</span> <span class="function declaration unsafe">unsafe_fn</span><span class="punctuation">(</span><span class="punctuation">)</span> <span class="punctuation">{</span><span class="punctuation">}</span> | 39 | <pre><code><span class="keyword unsafe">unsafe</span> <span class="keyword">fn</span> <span class="function declaration unsafe">unsafe_fn</span><span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="brace">{</span><span class="brace">}</span> |
40 | 40 | ||
41 | <span class="keyword">union</span> <span class="union declaration">Union</span> <span class="punctuation">{</span> | 41 | <span class="keyword">union</span> <span class="union declaration">Union</span> <span class="brace">{</span> |
42 | <span class="field declaration">a</span><span class="punctuation">:</span> <span class="builtin_type">u32</span><span class="punctuation">,</span> | 42 | <span class="field declaration">a</span><span class="colon">:</span> <span class="builtin_type">u32</span><span class="comma">,</span> |
43 | <span class="field declaration">b</span><span class="punctuation">:</span> <span class="builtin_type">f32</span><span class="punctuation">,</span> | 43 | <span class="field declaration">b</span><span class="colon">:</span> <span class="builtin_type">f32</span><span class="comma">,</span> |
44 | <span class="punctuation">}</span> | 44 | <span class="brace">}</span> |
45 | 45 | ||
46 | <span class="keyword">struct</span> <span class="struct declaration">HasUnsafeFn</span><span class="punctuation">;</span> | 46 | <span class="keyword">struct</span> <span class="struct declaration">HasUnsafeFn</span><span class="semicolon">;</span> |
47 | 47 | ||
48 | <span class="keyword">impl</span> <span class="struct">HasUnsafeFn</span> <span class="punctuation">{</span> | 48 | <span class="keyword">impl</span> <span class="struct">HasUnsafeFn</span> <span class="brace">{</span> |
49 | <span class="keyword unsafe">unsafe</span> <span class="keyword">fn</span> <span class="function declaration associated unsafe">unsafe_method</span><span class="punctuation">(</span><span class="operator">&</span><span class="self_keyword">self</span><span class="punctuation">)</span> <span class="punctuation">{</span><span class="punctuation">}</span> | 49 | <span class="keyword unsafe">unsafe</span> <span class="keyword">fn</span> <span class="function declaration associated unsafe">unsafe_method</span><span class="parenthesis">(</span><span class="operator">&</span><span class="self_keyword">self</span><span class="parenthesis">)</span> <span class="brace">{</span><span class="brace">}</span> |
50 | <span class="punctuation">}</span> | 50 | <span class="brace">}</span> |
51 | 51 | ||
52 | <span class="keyword">struct</span> <span class="struct declaration">TypeForStaticMut</span> <span class="punctuation">{</span> | 52 | <span class="keyword">struct</span> <span class="struct declaration">TypeForStaticMut</span> <span class="brace">{</span> |
53 | <span class="field declaration">a</span><span class="punctuation">:</span> <span class="builtin_type">u8</span> | 53 | <span class="field declaration">a</span><span class="colon">:</span> <span class="builtin_type">u8</span> |
54 | <span class="punctuation">}</span> | 54 | <span class="brace">}</span> |
55 | 55 | ||
56 | <span class="keyword">static</span> <span class="keyword">mut</span> <span class="static declaration mutable unsafe">global_mut</span><span class="punctuation">:</span> <span class="struct">TypeForStaticMut</span> <span class="operator">=</span> <span class="struct">TypeForStaticMut</span> <span class="punctuation">{</span> <span class="field">a</span><span class="punctuation">:</span> <span class="numeric_literal">0</span> <span class="punctuation">}</span><span class="punctuation">;</span> | 56 | <span class="keyword">static</span> <span class="keyword">mut</span> <span class="static declaration mutable unsafe">global_mut</span><span class="colon">:</span> <span class="struct">TypeForStaticMut</span> <span class="operator">=</span> <span class="struct">TypeForStaticMut</span> <span class="brace">{</span> <span class="field">a</span><span class="colon">:</span> <span class="numeric_literal">0</span> <span class="brace">}</span><span class="semicolon">;</span> |
57 | 57 | ||
58 | <span class="attribute attribute">#</span><span class="attribute attribute">[</span><span class="function attribute">repr</span><span class="punctuation attribute">(</span><span class="attribute attribute">packed</span><span class="punctuation attribute">)</span><span class="attribute attribute">]</span> | 58 | <span class="attribute attribute">#</span><span class="attribute attribute">[</span><span class="function attribute">repr</span><span class="parenthesis attribute">(</span><span class="attribute attribute">packed</span><span class="parenthesis attribute">)</span><span class="attribute attribute">]</span> |
59 | <span class="keyword">struct</span> <span class="struct declaration">Packed</span> <span class="punctuation">{</span> | 59 | <span class="keyword">struct</span> <span class="struct declaration">Packed</span> <span class="brace">{</span> |
60 | <span class="field declaration">a</span><span class="punctuation">:</span> <span class="builtin_type">u16</span><span class="punctuation">,</span> | 60 | <span class="field declaration">a</span><span class="colon">:</span> <span class="builtin_type">u16</span><span class="comma">,</span> |
61 | <span class="punctuation">}</span> | 61 | <span class="brace">}</span> |
62 | 62 | ||
63 | <span class="keyword">trait</span> <span class="trait declaration">DoTheAutoref</span> <span class="punctuation">{</span> | 63 | <span class="keyword">trait</span> <span class="trait declaration">DoTheAutoref</span> <span class="brace">{</span> |
64 | <span class="keyword">fn</span> <span class="function declaration associated">calls_autoref</span><span class="punctuation">(</span><span class="operator">&</span><span class="self_keyword">self</span><span class="punctuation">)</span><span class="punctuation">;</span> | 64 | <span class="keyword">fn</span> <span class="function declaration associated">calls_autoref</span><span class="parenthesis">(</span><span class="operator">&</span><span class="self_keyword">self</span><span class="parenthesis">)</span><span class="semicolon">;</span> |
65 | <span class="punctuation">}</span> | 65 | <span class="brace">}</span> |
66 | 66 | ||
67 | <span class="keyword">impl</span> <span class="trait">DoTheAutoref</span> <span class="keyword">for</span> <span class="builtin_type">u16</span> <span class="punctuation">{</span> | 67 | <span class="keyword">impl</span> <span class="trait">DoTheAutoref</span> <span class="keyword">for</span> <span class="builtin_type">u16</span> <span class="brace">{</span> |
68 | <span class="keyword">fn</span> <span class="function declaration associated">calls_autoref</span><span class="punctuation">(</span><span class="operator">&</span><span class="self_keyword">self</span><span class="punctuation">)</span> <span class="punctuation">{</span><span class="punctuation">}</span> | 68 | <span class="keyword">fn</span> <span class="function declaration associated">calls_autoref</span><span class="parenthesis">(</span><span class="operator">&</span><span class="self_keyword">self</span><span class="parenthesis">)</span> <span class="brace">{</span><span class="brace">}</span> |
69 | <span class="punctuation">}</span> | 69 | <span class="brace">}</span> |
70 | 70 | ||
71 | <span class="keyword">fn</span> <span class="function declaration">main</span><span class="punctuation">(</span><span class="punctuation">)</span> <span class="punctuation">{</span> | 71 | <span class="keyword">fn</span> <span class="function declaration">main</span><span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="brace">{</span> |
72 | <span class="keyword">let</span> <span class="variable declaration">x</span> <span class="operator">=</span> <span class="operator">&</span><span class="numeric_literal">5</span> <span class="keyword">as</span> <span class="keyword">*</span><span class="keyword">const</span> <span class="punctuation">_</span> <span class="keyword">as</span> <span class="keyword">*</span><span class="keyword">const</span> <span class="builtin_type">usize</span><span class="punctuation">;</span> | 72 | <span class="keyword">let</span> <span class="variable declaration">x</span> <span class="operator">=</span> <span class="operator">&</span><span class="numeric_literal">5</span> <span class="keyword">as</span> <span class="keyword">*</span><span class="keyword">const</span> <span class="punctuation">_</span> <span class="keyword">as</span> <span class="keyword">*</span><span class="keyword">const</span> <span class="builtin_type">usize</span><span class="semicolon">;</span> |
73 | <span class="keyword">let</span> <span class="variable declaration">u</span> <span class="operator">=</span> <span class="union">Union</span> <span class="punctuation">{</span> <span class="field">b</span><span class="punctuation">:</span> <span class="numeric_literal">0</span> <span class="punctuation">}</span><span class="punctuation">;</span> | 73 | <span class="keyword">let</span> <span class="variable declaration">u</span> <span class="operator">=</span> <span class="union">Union</span> <span class="brace">{</span> <span class="field">b</span><span class="colon">:</span> <span class="numeric_literal">0</span> <span class="brace">}</span><span class="semicolon">;</span> |
74 | <span class="keyword unsafe">unsafe</span> <span class="punctuation">{</span> | 74 | <span class="keyword unsafe">unsafe</span> <span class="brace">{</span> |
75 | <span class="comment">// unsafe fn and method calls</span> | 75 | <span class="comment">// unsafe fn and method calls</span> |
76 | <span class="function unsafe">unsafe_fn</span><span class="punctuation">(</span><span class="punctuation">)</span><span class="punctuation">;</span> | 76 | <span class="function unsafe">unsafe_fn</span><span class="parenthesis">(</span><span class="parenthesis">)</span><span class="semicolon">;</span> |
77 | <span class="keyword">let</span> <span class="variable declaration">b</span> <span class="operator">=</span> <span class="variable">u</span><span class="operator">.</span><span class="field unsafe">b</span><span class="punctuation">;</span> | 77 | <span class="keyword">let</span> <span class="variable declaration">b</span> <span class="operator">=</span> <span class="variable">u</span><span class="operator">.</span><span class="field unsafe">b</span><span class="semicolon">;</span> |
78 | <span class="keyword control">match</span> <span class="variable">u</span> <span class="punctuation">{</span> | 78 | <span class="keyword control">match</span> <span class="variable">u</span> <span class="brace">{</span> |
79 | <span class="union">Union</span> <span class="punctuation">{</span> <span class="field unsafe">b</span><span class="punctuation">:</span> <span class="numeric_literal">0</span> <span class="punctuation">}</span> <span class="operator">=></span> <span class="punctuation">(</span><span class="punctuation">)</span><span class="punctuation">,</span> | 79 | <span class="union">Union</span> <span class="brace">{</span> <span class="field unsafe">b</span><span class="colon">:</span> <span class="numeric_literal">0</span> <span class="brace">}</span> <span class="operator">=></span> <span class="parenthesis">(</span><span class="parenthesis">)</span><span class="comma">,</span> |
80 | <span class="union">Union</span> <span class="punctuation">{</span> <span class="field unsafe">a</span> <span class="punctuation">}</span> <span class="operator">=></span> <span class="punctuation">(</span><span class="punctuation">)</span><span class="punctuation">,</span> | 80 | <span class="union">Union</span> <span class="brace">{</span> <span class="field unsafe">a</span> <span class="brace">}</span> <span class="operator">=></span> <span class="parenthesis">(</span><span class="parenthesis">)</span><span class="comma">,</span> |
81 | <span class="punctuation">}</span> | 81 | <span class="brace">}</span> |
82 | <span class="struct">HasUnsafeFn</span><span class="operator">.</span><span class="function associated unsafe">unsafe_method</span><span class="punctuation">(</span><span class="punctuation">)</span><span class="punctuation">;</span> | 82 | <span class="struct">HasUnsafeFn</span><span class="operator">.</span><span class="function associated unsafe">unsafe_method</span><span class="parenthesis">(</span><span class="parenthesis">)</span><span class="semicolon">;</span> |
83 | 83 | ||
84 | <span class="comment">// unsafe deref</span> | 84 | <span class="comment">// unsafe deref</span> |
85 | <span class="keyword">let</span> <span class="variable declaration">y</span> <span class="operator">=</span> <span class="operator unsafe">*</span><span class="variable">x</span><span class="punctuation">;</span> | 85 | <span class="keyword">let</span> <span class="variable declaration">y</span> <span class="operator">=</span> <span class="operator unsafe">*</span><span class="variable">x</span><span class="semicolon">;</span> |
86 | 86 | ||
87 | <span class="comment">// unsafe access to a static mut</span> | 87 | <span class="comment">// unsafe access to a static mut</span> |
88 | <span class="keyword">let</span> <span class="variable declaration">a</span> <span class="operator">=</span> <span class="static mutable unsafe">global_mut</span><span class="operator">.</span><span class="field">a</span><span class="punctuation">;</span> | 88 | <span class="keyword">let</span> <span class="variable declaration">a</span> <span class="operator">=</span> <span class="static mutable unsafe">global_mut</span><span class="operator">.</span><span class="field">a</span><span class="semicolon">;</span> |
89 | 89 | ||
90 | <span class="comment">// unsafe ref of packed fields</span> | 90 | <span class="comment">// unsafe ref of packed fields</span> |
91 | <span class="keyword">let</span> <span class="variable declaration">packed</span> <span class="operator">=</span> <span class="struct">Packed</span> <span class="punctuation">{</span> <span class="field">a</span><span class="punctuation">:</span> <span class="numeric_literal">0</span> <span class="punctuation">}</span><span class="punctuation">;</span> | 91 | <span class="keyword">let</span> <span class="variable declaration">packed</span> <span class="operator">=</span> <span class="struct">Packed</span> <span class="brace">{</span> <span class="field">a</span><span class="colon">:</span> <span class="numeric_literal">0</span> <span class="brace">}</span><span class="semicolon">;</span> |
92 | <span class="keyword">let</span> <span class="variable declaration">a</span> <span class="operator">=</span> <span class="operator unsafe">&</span><span class="variable">packed</span><span class="operator">.</span><span class="field">a</span><span class="punctuation">;</span> | 92 | <span class="keyword">let</span> <span class="variable declaration">a</span> <span class="operator">=</span> <span class="operator unsafe">&</span><span class="variable">packed</span><span class="operator">.</span><span class="field">a</span><span class="semicolon">;</span> |
93 | <span class="keyword">let</span> <span class="keyword unsafe">ref</span> <span class="variable declaration">a</span> <span class="operator">=</span> <span class="variable">packed</span><span class="operator">.</span><span class="field">a</span><span class="punctuation">;</span> | 93 | <span class="keyword">let</span> <span class="keyword unsafe">ref</span> <span class="variable declaration">a</span> <span class="operator">=</span> <span class="variable">packed</span><span class="operator">.</span><span class="field">a</span><span class="semicolon">;</span> |
94 | <span class="keyword">let</span> <span class="struct">Packed</span> <span class="punctuation">{</span> <span class="keyword unsafe">ref</span> <span class="field">a</span> <span class="punctuation">}</span> <span class="operator">=</span> <span class="variable">packed</span><span class="punctuation">;</span> | 94 | <span class="keyword">let</span> <span class="struct">Packed</span> <span class="brace">{</span> <span class="keyword unsafe">ref</span> <span class="field">a</span> <span class="brace">}</span> <span class="operator">=</span> <span class="variable">packed</span><span class="semicolon">;</span> |
95 | <span class="keyword">let</span> <span class="struct">Packed</span> <span class="punctuation">{</span> <span class="field">a</span><span class="punctuation">:</span> <span class="keyword unsafe">ref</span> <span class="variable declaration">_a</span> <span class="punctuation">}</span> <span class="operator">=</span> <span class="variable">packed</span><span class="punctuation">;</span> | 95 | <span class="keyword">let</span> <span class="struct">Packed</span> <span class="brace">{</span> <span class="field">a</span><span class="colon">:</span> <span class="keyword unsafe">ref</span> <span class="variable declaration">_a</span> <span class="brace">}</span> <span class="operator">=</span> <span class="variable">packed</span><span class="semicolon">;</span> |
96 | 96 | ||
97 | <span class="comment">// unsafe auto ref of packed field</span> | 97 | <span class="comment">// unsafe auto ref of packed field</span> |
98 | <span class="variable">packed</span><span class="operator">.</span><span class="field">a</span><span class="operator">.</span><span class="function associated unsafe">calls_autoref</span><span class="punctuation">(</span><span class="punctuation">)</span><span class="punctuation">;</span> | 98 | <span class="variable">packed</span><span class="operator">.</span><span class="field">a</span><span class="operator">.</span><span class="function associated unsafe">calls_autoref</span><span class="parenthesis">(</span><span class="parenthesis">)</span><span class="semicolon">;</span> |
99 | <span class="punctuation">}</span> | 99 | <span class="brace">}</span> |
100 | <span class="punctuation">}</span></code></pre> \ No newline at end of file | 100 | <span class="brace">}</span></code></pre> \ No newline at end of file |
diff --git a/crates/ide/src/syntax_highlighting/test_data/highlighting.html b/crates/ide/src/syntax_highlighting/test_data/highlighting.html index 02270b077..6b7447c46 100644 --- a/crates/ide/src/syntax_highlighting/test_data/highlighting.html +++ b/crates/ide/src/syntax_highlighting/test_data/highlighting.html | |||
@@ -36,187 +36,187 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd | |||
36 | 36 | ||
37 | .unresolved_reference { color: #FC5555; text-decoration: wavy underline; } | 37 | .unresolved_reference { color: #FC5555; text-decoration: wavy underline; } |
38 | </style> | 38 | </style> |
39 | <pre><code><span class="keyword">use</span> <span class="module">inner</span><span class="operator">::</span><span class="punctuation">{</span><span class="self_keyword">self</span> <span class="keyword">as</span> <span class="module declaration">inner_mod</span><span class="punctuation">}</span><span class="punctuation">;</span> | 39 | <pre><code><span class="keyword">use</span> <span class="module">inner</span><span class="operator">::</span><span class="brace">{</span><span class="self_keyword">self</span> <span class="keyword">as</span> <span class="module declaration">inner_mod</span><span class="brace">}</span><span class="semicolon">;</span> |
40 | <span class="keyword">mod</span> <span class="module declaration">inner</span> <span class="punctuation">{</span><span class="punctuation">}</span> | 40 | <span class="keyword">mod</span> <span class="module declaration">inner</span> <span class="brace">{</span><span class="brace">}</span> |
41 | 41 | ||
42 | <span class="attribute attribute">#</span><span class="attribute attribute">[</span><span class="function attribute">rustc_builtin_macro</span><span class="attribute attribute">]</span> | 42 | <span class="attribute attribute">#</span><span class="attribute attribute">[</span><span class="function attribute">rustc_builtin_macro</span><span class="attribute attribute">]</span> |
43 | <span class="keyword">macro</span> <span class="unresolved_reference declaration">Copy</span> <span class="punctuation">{</span><span class="punctuation">}</span> | 43 | <span class="keyword">macro</span> <span class="unresolved_reference declaration">Copy</span> <span class="brace">{</span><span class="brace">}</span> |
44 | 44 | ||
45 | <span class="comment">// Needed for function consuming vs normal</span> | 45 | <span class="comment">// Needed for function consuming vs normal</span> |
46 | <span class="keyword">pub</span> <span class="keyword">mod</span> <span class="module declaration">marker</span> <span class="punctuation">{</span> | 46 | <span class="keyword">pub</span> <span class="keyword">mod</span> <span class="module declaration">marker</span> <span class="brace">{</span> |
47 | <span class="attribute attribute">#</span><span class="attribute attribute">[</span><span class="function attribute">lang</span><span class="attribute attribute"> </span><span class="operator attribute">=</span><span class="attribute attribute"> </span><span class="string_literal attribute">"copy"</span><span class="attribute attribute">]</span> | 47 | <span class="attribute attribute">#</span><span class="attribute attribute">[</span><span class="function attribute">lang</span><span class="attribute attribute"> </span><span class="operator attribute">=</span><span class="attribute attribute"> </span><span class="string_literal attribute">"copy"</span><span class="attribute attribute">]</span> |
48 | <span class="keyword">pub</span> <span class="keyword">trait</span> <span class="trait declaration">Copy</span> <span class="punctuation">{</span><span class="punctuation">}</span> | 48 | <span class="keyword">pub</span> <span class="keyword">trait</span> <span class="trait declaration">Copy</span> <span class="brace">{</span><span class="brace">}</span> |
49 | <span class="punctuation">}</span> | 49 | <span class="brace">}</span> |
50 | 50 | ||
51 | <span class="keyword">pub</span> <span class="keyword">mod</span> <span class="module declaration">ops</span> <span class="punctuation">{</span> | 51 | <span class="keyword">pub</span> <span class="keyword">mod</span> <span class="module declaration">ops</span> <span class="brace">{</span> |
52 | <span class="attribute attribute">#</span><span class="attribute attribute">[</span><span class="function attribute">lang</span><span class="attribute attribute"> </span><span class="operator attribute">=</span><span class="attribute attribute"> </span><span class="string_literal attribute">"fn_once"</span><span class="attribute attribute">]</span> | 52 | <span class="attribute attribute">#</span><span class="attribute attribute">[</span><span class="function attribute">lang</span><span class="attribute attribute"> </span><span class="operator attribute">=</span><span class="attribute attribute"> </span><span class="string_literal attribute">"fn_once"</span><span class="attribute attribute">]</span> |
53 | <span class="keyword">pub</span> <span class="keyword">trait</span> <span class="trait declaration">FnOnce</span><span class="punctuation"><</span><span class="type_param declaration">Args</span><span class="punctuation">></span> <span class="punctuation">{</span><span class="punctuation">}</span> | 53 | <span class="keyword">pub</span> <span class="keyword">trait</span> <span class="trait declaration">FnOnce</span><span class="angle"><</span><span class="type_param declaration">Args</span><span class="angle">></span> <span class="brace">{</span><span class="brace">}</span> |
54 | 54 | ||
55 | <span class="attribute attribute">#</span><span class="attribute attribute">[</span><span class="function attribute">lang</span><span class="attribute attribute"> </span><span class="operator attribute">=</span><span class="attribute attribute"> </span><span class="string_literal attribute">"fn_mut"</span><span class="attribute attribute">]</span> | 55 | <span class="attribute attribute">#</span><span class="attribute attribute">[</span><span class="function attribute">lang</span><span class="attribute attribute"> </span><span class="operator attribute">=</span><span class="attribute attribute"> </span><span class="string_literal attribute">"fn_mut"</span><span class="attribute attribute">]</span> |
56 | <span class="keyword">pub</span> <span class="keyword">trait</span> <span class="trait declaration">FnMut</span><span class="punctuation"><</span><span class="type_param declaration">Args</span><span class="punctuation">></span><span class="punctuation">:</span> <span class="trait">FnOnce</span><span class="punctuation"><</span><span class="type_param">Args</span><span class="punctuation">></span> <span class="punctuation">{</span><span class="punctuation">}</span> | 56 | <span class="keyword">pub</span> <span class="keyword">trait</span> <span class="trait declaration">FnMut</span><span class="angle"><</span><span class="type_param declaration">Args</span><span class="angle">></span><span class="colon">:</span> <span class="trait">FnOnce</span><span class="angle"><</span><span class="type_param">Args</span><span class="angle">></span> <span class="brace">{</span><span class="brace">}</span> |
57 | 57 | ||
58 | <span class="attribute attribute">#</span><span class="attribute attribute">[</span><span class="function attribute">lang</span><span class="attribute attribute"> </span><span class="operator attribute">=</span><span class="attribute attribute"> </span><span class="string_literal attribute">"fn"</span><span class="attribute attribute">]</span> | 58 | <span class="attribute attribute">#</span><span class="attribute attribute">[</span><span class="function attribute">lang</span><span class="attribute attribute"> </span><span class="operator attribute">=</span><span class="attribute attribute"> </span><span class="string_literal attribute">"fn"</span><span class="attribute attribute">]</span> |
59 | <span class="keyword">pub</span> <span class="keyword">trait</span> <span class="trait declaration">Fn</span><span class="punctuation"><</span><span class="type_param declaration">Args</span><span class="punctuation">></span><span class="punctuation">:</span> <span class="trait">FnMut</span><span class="punctuation"><</span><span class="type_param">Args</span><span class="punctuation">></span> <span class="punctuation">{</span><span class="punctuation">}</span> | 59 | <span class="keyword">pub</span> <span class="keyword">trait</span> <span class="trait declaration">Fn</span><span class="angle"><</span><span class="type_param declaration">Args</span><span class="angle">></span><span class="colon">:</span> <span class="trait">FnMut</span><span class="angle"><</span><span class="type_param">Args</span><span class="angle">></span> <span class="brace">{</span><span class="brace">}</span> |
60 | <span class="punctuation">}</span> | 60 | <span class="brace">}</span> |
61 | 61 | ||
62 | 62 | ||
63 | <span class="keyword">struct</span> <span class="struct declaration">Foo</span> <span class="punctuation">{</span> | 63 | <span class="keyword">struct</span> <span class="struct declaration">Foo</span> <span class="brace">{</span> |
64 | <span class="keyword">pub</span> <span class="field declaration">x</span><span class="punctuation">:</span> <span class="builtin_type">i32</span><span class="punctuation">,</span> | 64 | <span class="keyword">pub</span> <span class="field declaration">x</span><span class="colon">:</span> <span class="builtin_type">i32</span><span class="comma">,</span> |
65 | <span class="keyword">pub</span> <span class="field declaration">y</span><span class="punctuation">:</span> <span class="builtin_type">i32</span><span class="punctuation">,</span> | 65 | <span class="keyword">pub</span> <span class="field declaration">y</span><span class="colon">:</span> <span class="builtin_type">i32</span><span class="comma">,</span> |
66 | <span class="punctuation">}</span> | 66 | <span class="brace">}</span> |
67 | 67 | ||
68 | <span class="keyword">trait</span> <span class="trait declaration">Bar</span> <span class="punctuation">{</span> | 68 | <span class="keyword">trait</span> <span class="trait declaration">Bar</span> <span class="brace">{</span> |
69 | <span class="keyword">fn</span> <span class="function declaration associated">bar</span><span class="punctuation">(</span><span class="operator">&</span><span class="self_keyword">self</span><span class="punctuation">)</span> <span class="operator">-></span> <span class="builtin_type">i32</span><span class="punctuation">;</span> | 69 | <span class="keyword">fn</span> <span class="function declaration associated">bar</span><span class="parenthesis">(</span><span class="operator">&</span><span class="self_keyword">self</span><span class="parenthesis">)</span> <span class="operator">-></span> <span class="builtin_type">i32</span><span class="semicolon">;</span> |
70 | <span class="punctuation">}</span> | 70 | <span class="brace">}</span> |
71 | 71 | ||
72 | <span class="keyword">impl</span> <span class="trait">Bar</span> <span class="keyword">for</span> <span class="struct">Foo</span> <span class="punctuation">{</span> | 72 | <span class="keyword">impl</span> <span class="trait">Bar</span> <span class="keyword">for</span> <span class="struct">Foo</span> <span class="brace">{</span> |
73 | <span class="keyword">fn</span> <span class="function declaration associated">bar</span><span class="punctuation">(</span><span class="operator">&</span><span class="self_keyword">self</span><span class="punctuation">)</span> <span class="operator">-></span> <span class="builtin_type">i32</span> <span class="punctuation">{</span> | 73 | <span class="keyword">fn</span> <span class="function declaration associated">bar</span><span class="parenthesis">(</span><span class="operator">&</span><span class="self_keyword">self</span><span class="parenthesis">)</span> <span class="operator">-></span> <span class="builtin_type">i32</span> <span class="brace">{</span> |
74 | <span class="self_keyword">self</span><span class="operator">.</span><span class="field">x</span> | 74 | <span class="self_keyword">self</span><span class="operator">.</span><span class="field">x</span> |
75 | <span class="punctuation">}</span> | 75 | <span class="brace">}</span> |
76 | <span class="punctuation">}</span> | 76 | <span class="brace">}</span> |
77 | 77 | ||
78 | <span class="keyword">impl</span> <span class="struct">Foo</span> <span class="punctuation">{</span> | 78 | <span class="keyword">impl</span> <span class="struct">Foo</span> <span class="brace">{</span> |
79 | <span class="keyword">fn</span> <span class="function declaration associated">baz</span><span class="punctuation">(</span><span class="keyword">mut</span> <span class="self_keyword mutable">self</span><span class="punctuation">,</span> <span class="value_param declaration">f</span><span class="punctuation">:</span> <span class="struct">Foo</span><span class="punctuation">)</span> <span class="operator">-></span> <span class="builtin_type">i32</span> <span class="punctuation">{</span> | 79 | <span class="keyword">fn</span> <span class="function declaration associated">baz</span><span class="parenthesis">(</span><span class="keyword">mut</span> <span class="self_keyword mutable">self</span><span class="comma">,</span> <span class="value_param declaration">f</span><span class="colon">:</span> <span class="struct">Foo</span><span class="parenthesis">)</span> <span class="operator">-></span> <span class="builtin_type">i32</span> <span class="brace">{</span> |
80 | <span class="value_param">f</span><span class="operator">.</span><span class="function consuming associated">baz</span><span class="punctuation">(</span><span class="self_keyword mutable consuming">self</span><span class="punctuation">)</span> | 80 | <span class="value_param">f</span><span class="operator">.</span><span class="function consuming associated">baz</span><span class="parenthesis">(</span><span class="self_keyword mutable consuming">self</span><span class="parenthesis">)</span> |
81 | <span class="punctuation">}</span> | 81 | <span class="brace">}</span> |
82 | 82 | ||
83 | <span class="keyword">fn</span> <span class="function declaration associated">qux</span><span class="punctuation">(</span><span class="operator">&</span><span class="keyword">mut</span> <span class="self_keyword mutable">self</span><span class="punctuation">)</span> <span class="punctuation">{</span> | 83 | <span class="keyword">fn</span> <span class="function declaration associated">qux</span><span class="parenthesis">(</span><span class="operator">&</span><span class="keyword">mut</span> <span class="self_keyword mutable">self</span><span class="parenthesis">)</span> <span class="brace">{</span> |
84 | <span class="self_keyword mutable">self</span><span class="operator">.</span><span class="field">x</span> <span class="operator">=</span> <span class="numeric_literal">0</span><span class="punctuation">;</span> | 84 | <span class="self_keyword mutable">self</span><span class="operator">.</span><span class="field">x</span> <span class="operator">=</span> <span class="numeric_literal">0</span><span class="semicolon">;</span> |
85 | <span class="punctuation">}</span> | 85 | <span class="brace">}</span> |
86 | 86 | ||
87 | <span class="keyword">fn</span> <span class="function declaration associated">quop</span><span class="punctuation">(</span><span class="operator">&</span><span class="self_keyword">self</span><span class="punctuation">)</span> <span class="operator">-></span> <span class="builtin_type">i32</span> <span class="punctuation">{</span> | 87 | <span class="keyword">fn</span> <span class="function declaration associated">quop</span><span class="parenthesis">(</span><span class="operator">&</span><span class="self_keyword">self</span><span class="parenthesis">)</span> <span class="operator">-></span> <span class="builtin_type">i32</span> <span class="brace">{</span> |
88 | <span class="self_keyword">self</span><span class="operator">.</span><span class="field">x</span> | 88 | <span class="self_keyword">self</span><span class="operator">.</span><span class="field">x</span> |
89 | <span class="punctuation">}</span> | 89 | <span class="brace">}</span> |
90 | <span class="punctuation">}</span> | 90 | <span class="brace">}</span> |
91 | 91 | ||
92 | <span class="attribute attribute">#</span><span class="attribute attribute">[</span><span class="function attribute">derive</span><span class="punctuation attribute">(</span><span class="attribute attribute">Copy</span><span class="punctuation attribute">)</span><span class="attribute attribute">]</span> | 92 | <span class="attribute attribute">#</span><span class="attribute attribute">[</span><span class="function attribute">derive</span><span class="parenthesis attribute">(</span><span class="attribute attribute">Copy</span><span class="parenthesis attribute">)</span><span class="attribute attribute">]</span> |
93 | <span class="keyword">struct</span> <span class="struct declaration">FooCopy</span> <span class="punctuation">{</span> | 93 | <span class="keyword">struct</span> <span class="struct declaration">FooCopy</span> <span class="brace">{</span> |
94 | <span class="field declaration">x</span><span class="punctuation">:</span> <span class="builtin_type">u32</span><span class="punctuation">,</span> | 94 | <span class="field declaration">x</span><span class="colon">:</span> <span class="builtin_type">u32</span><span class="comma">,</span> |
95 | <span class="punctuation">}</span> | 95 | <span class="brace">}</span> |
96 | 96 | ||
97 | <span class="keyword">impl</span> <span class="struct">FooCopy</span> <span class="punctuation">{</span> | 97 | <span class="keyword">impl</span> <span class="struct">FooCopy</span> <span class="brace">{</span> |
98 | <span class="keyword">fn</span> <span class="function declaration associated">baz</span><span class="punctuation">(</span><span class="self_keyword">self</span><span class="punctuation">,</span> <span class="value_param declaration">f</span><span class="punctuation">:</span> <span class="struct">FooCopy</span><span class="punctuation">)</span> <span class="operator">-></span> <span class="builtin_type">u32</span> <span class="punctuation">{</span> | 98 | <span class="keyword">fn</span> <span class="function declaration associated">baz</span><span class="parenthesis">(</span><span class="self_keyword">self</span><span class="comma">,</span> <span class="value_param declaration">f</span><span class="colon">:</span> <span class="struct">FooCopy</span><span class="parenthesis">)</span> <span class="operator">-></span> <span class="builtin_type">u32</span> <span class="brace">{</span> |
99 | <span class="value_param">f</span><span class="operator">.</span><span class="function associated">baz</span><span class="punctuation">(</span><span class="self_keyword">self</span><span class="punctuation">)</span> | 99 | <span class="value_param">f</span><span class="operator">.</span><span class="function associated">baz</span><span class="parenthesis">(</span><span class="self_keyword">self</span><span class="parenthesis">)</span> |
100 | <span class="punctuation">}</span> | 100 | <span class="brace">}</span> |
101 | 101 | ||
102 | <span class="keyword">fn</span> <span class="function declaration associated">qux</span><span class="punctuation">(</span><span class="operator">&</span><span class="keyword">mut</span> <span class="self_keyword mutable">self</span><span class="punctuation">)</span> <span class="punctuation">{</span> | 102 | <span class="keyword">fn</span> <span class="function declaration associated">qux</span><span class="parenthesis">(</span><span class="operator">&</span><span class="keyword">mut</span> <span class="self_keyword mutable">self</span><span class="parenthesis">)</span> <span class="brace">{</span> |
103 | <span class="self_keyword mutable">self</span><span class="operator">.</span><span class="field">x</span> <span class="operator">=</span> <span class="numeric_literal">0</span><span class="punctuation">;</span> | 103 | <span class="self_keyword mutable">self</span><span class="operator">.</span><span class="field">x</span> <span class="operator">=</span> <span class="numeric_literal">0</span><span class="semicolon">;</span> |
104 | <span class="punctuation">}</span> | 104 | <span class="brace">}</span> |
105 | 105 | ||
106 | <span class="keyword">fn</span> <span class="function declaration associated">quop</span><span class="punctuation">(</span><span class="operator">&</span><span class="self_keyword">self</span><span class="punctuation">)</span> <span class="operator">-></span> <span class="builtin_type">u32</span> <span class="punctuation">{</span> | 106 | <span class="keyword">fn</span> <span class="function declaration associated">quop</span><span class="parenthesis">(</span><span class="operator">&</span><span class="self_keyword">self</span><span class="parenthesis">)</span> <span class="operator">-></span> <span class="builtin_type">u32</span> <span class="brace">{</span> |
107 | <span class="self_keyword">self</span><span class="operator">.</span><span class="field">x</span> | 107 | <span class="self_keyword">self</span><span class="operator">.</span><span class="field">x</span> |
108 | <span class="punctuation">}</span> | 108 | <span class="brace">}</span> |
109 | <span class="punctuation">}</span> | 109 | <span class="brace">}</span> |
110 | 110 | ||
111 | <span class="keyword">static</span> <span class="keyword">mut</span> <span class="static declaration mutable unsafe">STATIC_MUT</span><span class="punctuation">:</span> <span class="builtin_type">i32</span> <span class="operator">=</span> <span class="numeric_literal">0</span><span class="punctuation">;</span> | 111 | <span class="keyword">static</span> <span class="keyword">mut</span> <span class="static declaration mutable unsafe">STATIC_MUT</span><span class="colon">:</span> <span class="builtin_type">i32</span> <span class="operator">=</span> <span class="numeric_literal">0</span><span class="semicolon">;</span> |
112 | 112 | ||
113 | <span class="keyword">fn</span> <span class="function declaration">foo</span><span class="punctuation"><</span><span class="lifetime declaration">'a</span><span class="punctuation">,</span> <span class="type_param declaration">T</span><span class="punctuation">></span><span class="punctuation">(</span><span class="punctuation">)</span> <span class="operator">-></span> <span class="type_param">T</span> <span class="punctuation">{</span> | 113 | <span class="keyword">fn</span> <span class="function declaration">foo</span><span class="angle"><</span><span class="lifetime declaration">'a</span><span class="comma">,</span> <span class="type_param declaration">T</span><span class="angle">></span><span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="operator">-></span> <span class="type_param">T</span> <span class="brace">{</span> |
114 | <span class="function">foo</span><span class="operator">::</span><span class="punctuation"><</span><span class="lifetime">'a</span><span class="punctuation">,</span> <span class="builtin_type">i32</span><span class="punctuation">></span><span class="punctuation">(</span><span class="punctuation">)</span> | 114 | <span class="function">foo</span><span class="operator">::</span><span class="angle"><</span><span class="lifetime">'a</span><span class="comma">,</span> <span class="builtin_type">i32</span><span class="angle">></span><span class="parenthesis">(</span><span class="parenthesis">)</span> |
115 | <span class="punctuation">}</span> | 115 | <span class="brace">}</span> |
116 | 116 | ||
117 | <span class="keyword">fn</span> <span class="function declaration">never</span><span class="punctuation">(</span><span class="punctuation">)</span> <span class="operator">-></span> <span class="builtin_type">!</span> <span class="punctuation">{</span> | 117 | <span class="keyword">fn</span> <span class="function declaration">never</span><span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="operator">-></span> <span class="builtin_type">!</span> <span class="brace">{</span> |
118 | <span class="keyword control">loop</span> <span class="punctuation">{</span><span class="punctuation">}</span> | 118 | <span class="keyword control">loop</span> <span class="brace">{</span><span class="brace">}</span> |
119 | <span class="punctuation">}</span> | 119 | <span class="brace">}</span> |
120 | 120 | ||
121 | <span class="keyword">fn</span> <span class="function declaration">const_param</span><span class="punctuation"><</span><span class="keyword">const</span> <span class="const_param declaration">FOO</span><span class="punctuation">:</span> <span class="builtin_type">usize</span><span class="punctuation">></span><span class="punctuation">(</span><span class="punctuation">)</span> <span class="operator">-></span> <span class="builtin_type">usize</span> <span class="punctuation">{</span> | 121 | <span class="keyword">fn</span> <span class="function declaration">const_param</span><span class="angle"><</span><span class="keyword">const</span> <span class="const_param declaration">FOO</span><span class="colon">:</span> <span class="builtin_type">usize</span><span class="angle">></span><span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="operator">-></span> <span class="builtin_type">usize</span> <span class="brace">{</span> |
122 | <span class="const_param">FOO</span> | 122 | <span class="const_param">FOO</span> |
123 | <span class="punctuation">}</span> | 123 | <span class="brace">}</span> |
124 | 124 | ||
125 | <span class="keyword">use</span> <span class="module">ops</span><span class="operator">::</span><span class="trait">Fn</span><span class="punctuation">;</span> | 125 | <span class="keyword">use</span> <span class="module">ops</span><span class="operator">::</span><span class="trait">Fn</span><span class="semicolon">;</span> |
126 | <span class="keyword">fn</span> <span class="function declaration">baz</span><span class="punctuation"><</span><span class="type_param declaration">F</span><span class="punctuation">:</span> <span class="trait">Fn</span><span class="punctuation">(</span><span class="punctuation">)</span> <span class="operator">-></span> <span class="punctuation">(</span><span class="punctuation">)</span><span class="punctuation">></span><span class="punctuation">(</span><span class="value_param declaration callable">f</span><span class="punctuation">:</span> <span class="type_param">F</span><span class="punctuation">)</span> <span class="punctuation">{</span> | 126 | <span class="keyword">fn</span> <span class="function declaration">baz</span><span class="angle"><</span><span class="type_param declaration">F</span><span class="colon">:</span> <span class="trait">Fn</span><span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="operator">-></span> <span class="parenthesis">(</span><span class="parenthesis">)</span><span class="angle">></span><span class="parenthesis">(</span><span class="value_param declaration callable">f</span><span class="colon">:</span> <span class="type_param">F</span><span class="parenthesis">)</span> <span class="brace">{</span> |
127 | <span class="value_param callable">f</span><span class="punctuation">(</span><span class="punctuation">)</span> | 127 | <span class="value_param callable">f</span><span class="parenthesis">(</span><span class="parenthesis">)</span> |
128 | <span class="punctuation">}</span> | 128 | <span class="brace">}</span> |
129 | 129 | ||
130 | <span class="keyword">fn</span> <span class="function declaration">foobar</span><span class="punctuation">(</span><span class="punctuation">)</span> <span class="operator">-></span> <span class="keyword">impl</span> <span class="macro">Copy</span> <span class="punctuation">{</span><span class="punctuation">}</span> | 130 | <span class="keyword">fn</span> <span class="function declaration">foobar</span><span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="operator">-></span> <span class="keyword">impl</span> <span class="macro">Copy</span> <span class="brace">{</span><span class="brace">}</span> |
131 | 131 | ||
132 | <span class="keyword">fn</span> <span class="function declaration">foo</span><span class="punctuation">(</span><span class="punctuation">)</span> <span class="punctuation">{</span> | 132 | <span class="keyword">fn</span> <span class="function declaration">foo</span><span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="brace">{</span> |
133 | <span class="keyword">let</span> <span class="variable declaration">bar</span> <span class="operator">=</span> <span class="function">foobar</span><span class="punctuation">(</span><span class="punctuation">)</span><span class="punctuation">;</span> | 133 | <span class="keyword">let</span> <span class="variable declaration">bar</span> <span class="operator">=</span> <span class="function">foobar</span><span class="parenthesis">(</span><span class="parenthesis">)</span><span class="semicolon">;</span> |
134 | <span class="punctuation">}</span> | 134 | <span class="brace">}</span> |
135 | 135 | ||
136 | <span class="keyword">macro_rules</span><span class="punctuation">!</span> <span class="macro declaration">def_fn</span> <span class="punctuation">{</span> | 136 | <span class="keyword">macro_rules</span><span class="punctuation">!</span> <span class="macro declaration">def_fn</span> <span class="brace">{</span> |
137 | <span class="punctuation">(</span><span class="punctuation">$</span><span class="punctuation">(</span><span class="punctuation">$</span>tt<span class="punctuation">:</span>tt<span class="punctuation">)</span><span class="punctuation">*</span><span class="punctuation">)</span> <span class="operator">=</span><span class="punctuation">></span> <span class="punctuation">{</span><span class="punctuation">$</span><span class="punctuation">(</span><span class="punctuation">$</span>tt<span class="punctuation">)</span><span class="punctuation">*</span><span class="punctuation">}</span> | 137 | <span class="parenthesis">(</span><span class="punctuation">$</span><span class="parenthesis">(</span><span class="punctuation">$</span>tt<span class="colon">:</span>tt<span class="parenthesis">)</span><span class="punctuation">*</span><span class="parenthesis">)</span> <span class="operator">=</span><span class="angle">></span> <span class="brace">{</span><span class="punctuation">$</span><span class="parenthesis">(</span><span class="punctuation">$</span>tt<span class="parenthesis">)</span><span class="punctuation">*</span><span class="brace">}</span> |
138 | <span class="punctuation">}</span> | 138 | <span class="brace">}</span> |
139 | 139 | ||
140 | <span class="macro">def_fn!</span> <span class="punctuation">{</span> | 140 | <span class="macro">def_fn!</span> <span class="brace">{</span> |
141 | <span class="keyword">fn</span> <span class="function declaration">bar</span><span class="punctuation">(</span><span class="punctuation">)</span> <span class="operator">-</span><span class="operator">></span> <span class="builtin_type">u32</span> <span class="punctuation">{</span> | 141 | <span class="keyword">fn</span> <span class="function declaration">bar</span><span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="operator">-</span><span class="operator">></span> <span class="builtin_type">u32</span> <span class="brace">{</span> |
142 | <span class="numeric_literal">100</span> | 142 | <span class="numeric_literal">100</span> |
143 | <span class="punctuation">}</span> | 143 | <span class="brace">}</span> |
144 | <span class="punctuation">}</span> | 144 | <span class="brace">}</span> |
145 | 145 | ||
146 | <span class="keyword">macro_rules</span><span class="punctuation">!</span> <span class="macro declaration">noop</span> <span class="punctuation">{</span> | 146 | <span class="keyword">macro_rules</span><span class="punctuation">!</span> <span class="macro declaration">noop</span> <span class="brace">{</span> |
147 | <span class="punctuation">(</span><span class="punctuation">$</span>expr<span class="punctuation">:</span>expr<span class="punctuation">)</span> <span class="operator">=</span><span class="punctuation">></span> <span class="punctuation">{</span> | 147 | <span class="parenthesis">(</span><span class="punctuation">$</span>expr<span class="colon">:</span>expr<span class="parenthesis">)</span> <span class="operator">=</span><span class="angle">></span> <span class="brace">{</span> |
148 | <span class="punctuation">$</span>expr | 148 | <span class="punctuation">$</span>expr |
149 | <span class="punctuation">}</span> | 149 | <span class="brace">}</span> |
150 | <span class="punctuation">}</span> | 150 | <span class="brace">}</span> |
151 | 151 | ||
152 | <span class="keyword">macro_rules</span><span class="punctuation">!</span> <span class="macro declaration">keyword_frag</span> <span class="punctuation">{</span> | 152 | <span class="keyword">macro_rules</span><span class="punctuation">!</span> <span class="macro declaration">keyword_frag</span> <span class="brace">{</span> |
153 | <span class="punctuation">(</span><span class="punctuation">$</span>type<span class="punctuation">:</span>ty<span class="punctuation">)</span> <span class="operator">=</span><span class="punctuation">></span> <span class="punctuation">(</span><span class="punctuation">$</span>type<span class="punctuation">)</span> | 153 | <span class="parenthesis">(</span><span class="punctuation">$</span>type<span class="colon">:</span>ty<span class="parenthesis">)</span> <span class="operator">=</span><span class="angle">></span> <span class="parenthesis">(</span><span class="punctuation">$</span>type<span class="parenthesis">)</span> |
154 | <span class="punctuation">}</span> | 154 | <span class="brace">}</span> |
155 | 155 | ||
156 | <span class="comment">// comment</span> | 156 | <span class="comment">// comment</span> |
157 | <span class="keyword">fn</span> <span class="function declaration">main</span><span class="punctuation">(</span><span class="punctuation">)</span> <span class="punctuation">{</span> | 157 | <span class="keyword">fn</span> <span class="function declaration">main</span><span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="brace">{</span> |
158 | <span class="macro">println!</span><span class="punctuation">(</span><span class="string_literal">"Hello, {}!"</span><span class="punctuation">,</span> <span class="numeric_literal">92</span><span class="punctuation">)</span><span class="punctuation">;</span> | 158 | <span class="macro">println!</span><span class="parenthesis">(</span><span class="string_literal">"Hello, {}!"</span><span class="comma">,</span> <span class="numeric_literal">92</span><span class="parenthesis">)</span><span class="semicolon">;</span> |
159 | 159 | ||
160 | <span class="keyword">let</span> <span class="keyword">mut</span> <span class="variable declaration mutable">vec</span> <span class="operator">=</span> <span class="unresolved_reference">Vec</span><span class="operator">::</span><span class="unresolved_reference">new</span><span class="punctuation">(</span><span class="punctuation">)</span><span class="punctuation">;</span> | 160 | <span class="keyword">let</span> <span class="keyword">mut</span> <span class="variable declaration mutable">vec</span> <span class="operator">=</span> <span class="unresolved_reference">Vec</span><span class="operator">::</span><span class="unresolved_reference">new</span><span class="parenthesis">(</span><span class="parenthesis">)</span><span class="semicolon">;</span> |
161 | <span class="keyword control">if</span> <span class="bool_literal">true</span> <span class="punctuation">{</span> | 161 | <span class="keyword control">if</span> <span class="bool_literal">true</span> <span class="brace">{</span> |
162 | <span class="keyword">let</span> <span class="variable declaration">x</span> <span class="operator">=</span> <span class="numeric_literal">92</span><span class="punctuation">;</span> | 162 | <span class="keyword">let</span> <span class="variable declaration">x</span> <span class="operator">=</span> <span class="numeric_literal">92</span><span class="semicolon">;</span> |
163 | <span class="variable mutable">vec</span><span class="operator">.</span><span class="unresolved_reference">push</span><span class="punctuation">(</span><span class="struct">Foo</span> <span class="punctuation">{</span> <span class="field">x</span><span class="punctuation">,</span> <span class="field">y</span><span class="punctuation">:</span> <span class="numeric_literal">1</span> <span class="punctuation">}</span><span class="punctuation">)</span><span class="punctuation">;</span> | 163 | <span class="variable mutable">vec</span><span class="operator">.</span><span class="unresolved_reference">push</span><span class="parenthesis">(</span><span class="struct">Foo</span> <span class="brace">{</span> <span class="field">x</span><span class="comma">,</span> <span class="field">y</span><span class="colon">:</span> <span class="numeric_literal">1</span> <span class="brace">}</span><span class="parenthesis">)</span><span class="semicolon">;</span> |
164 | <span class="punctuation">}</span> | 164 | <span class="brace">}</span> |
165 | <span class="keyword unsafe">unsafe</span> <span class="punctuation">{</span> | 165 | <span class="keyword unsafe">unsafe</span> <span class="brace">{</span> |
166 | <span class="variable mutable">vec</span><span class="operator">.</span><span class="unresolved_reference">set_len</span><span class="punctuation">(</span><span class="numeric_literal">0</span><span class="punctuation">)</span><span class="punctuation">;</span> | 166 | <span class="variable mutable">vec</span><span class="operator">.</span><span class="unresolved_reference">set_len</span><span class="parenthesis">(</span><span class="numeric_literal">0</span><span class="parenthesis">)</span><span class="semicolon">;</span> |
167 | <span class="static mutable unsafe">STATIC_MUT</span> <span class="operator">=</span> <span class="numeric_literal">1</span><span class="punctuation">;</span> | 167 | <span class="static mutable unsafe">STATIC_MUT</span> <span class="operator">=</span> <span class="numeric_literal">1</span><span class="semicolon">;</span> |
168 | <span class="punctuation">}</span> | 168 | <span class="brace">}</span> |
169 | 169 | ||
170 | <span class="keyword control">for</span> <span class="variable declaration">e</span> <span class="keyword control">in</span> <span class="variable mutable">vec</span> <span class="punctuation">{</span> | 170 | <span class="keyword control">for</span> <span class="variable declaration">e</span> <span class="keyword control">in</span> <span class="variable mutable">vec</span> <span class="brace">{</span> |
171 | <span class="comment">// Do nothing</span> | 171 | <span class="comment">// Do nothing</span> |
172 | <span class="punctuation">}</span> | 172 | <span class="brace">}</span> |
173 | 173 | ||
174 | <span class="macro">noop!</span><span class="punctuation">(</span><span class="macro">noop</span><span class="macro">!</span><span class="punctuation">(</span><span class="numeric_literal">1</span><span class="punctuation">)</span><span class="punctuation">)</span><span class="punctuation">;</span> | 174 | <span class="macro">noop!</span><span class="parenthesis">(</span><span class="macro">noop</span><span class="macro">!</span><span class="parenthesis">(</span><span class="numeric_literal">1</span><span class="parenthesis">)</span><span class="parenthesis">)</span><span class="semicolon">;</span> |
175 | 175 | ||
176 | <span class="keyword">let</span> <span class="keyword">mut</span> <span class="variable declaration mutable">x</span> <span class="operator">=</span> <span class="numeric_literal">42</span><span class="punctuation">;</span> | 176 | <span class="keyword">let</span> <span class="keyword">mut</span> <span class="variable declaration mutable">x</span> <span class="operator">=</span> <span class="numeric_literal">42</span><span class="semicolon">;</span> |
177 | <span class="keyword">let</span> <span class="variable declaration mutable">y</span> <span class="operator">=</span> <span class="operator">&</span><span class="keyword">mut</span> <span class="variable mutable">x</span><span class="punctuation">;</span> | 177 | <span class="keyword">let</span> <span class="variable declaration mutable">y</span> <span class="operator">=</span> <span class="operator">&</span><span class="keyword">mut</span> <span class="variable mutable">x</span><span class="semicolon">;</span> |
178 | <span class="keyword">let</span> <span class="variable declaration">z</span> <span class="operator">=</span> <span class="operator">&</span><span class="variable mutable">y</span><span class="punctuation">;</span> | 178 | <span class="keyword">let</span> <span class="variable declaration">z</span> <span class="operator">=</span> <span class="operator">&</span><span class="variable mutable">y</span><span class="semicolon">;</span> |
179 | 179 | ||
180 | <span class="keyword">let</span> <span class="struct">Foo</span> <span class="punctuation">{</span> <span class="field">x</span><span class="punctuation">:</span> <span class="variable declaration">z</span><span class="punctuation">,</span> <span class="field">y</span> <span class="punctuation">}</span> <span class="operator">=</span> <span class="struct">Foo</span> <span class="punctuation">{</span> <span class="field">x</span><span class="punctuation">:</span> <span class="variable">z</span><span class="punctuation">,</span> <span class="field">y</span> <span class="punctuation">}</span><span class="punctuation">;</span> | 180 | <span class="keyword">let</span> <span class="struct">Foo</span> <span class="brace">{</span> <span class="field">x</span><span class="colon">:</span> <span class="variable declaration">z</span><span class="comma">,</span> <span class="field">y</span> <span class="brace">}</span> <span class="operator">=</span> <span class="struct">Foo</span> <span class="brace">{</span> <span class="field">x</span><span class="colon">:</span> <span class="variable">z</span><span class="comma">,</span> <span class="field">y</span> <span class="brace">}</span><span class="semicolon">;</span> |
181 | 181 | ||
182 | <span class="variable">y</span><span class="punctuation">;</span> | 182 | <span class="variable">y</span><span class="semicolon">;</span> |
183 | 183 | ||
184 | <span class="keyword">let</span> <span class="keyword">mut</span> <span class="variable declaration mutable">foo</span> <span class="operator">=</span> <span class="struct">Foo</span> <span class="punctuation">{</span> <span class="field">x</span><span class="punctuation">,</span> <span class="field">y</span><span class="punctuation">:</span> <span class="variable mutable">x</span> <span class="punctuation">}</span><span class="punctuation">;</span> | 184 | <span class="keyword">let</span> <span class="keyword">mut</span> <span class="variable declaration mutable">foo</span> <span class="operator">=</span> <span class="struct">Foo</span> <span class="brace">{</span> <span class="field">x</span><span class="comma">,</span> <span class="field">y</span><span class="colon">:</span> <span class="variable mutable">x</span> <span class="brace">}</span><span class="semicolon">;</span> |
185 | <span class="keyword">let</span> <span class="variable declaration">foo2</span> <span class="operator">=</span> <span class="struct">Foo</span> <span class="punctuation">{</span> <span class="field">x</span><span class="punctuation">,</span> <span class="field">y</span><span class="punctuation">:</span> <span class="variable mutable">x</span> <span class="punctuation">}</span><span class="punctuation">;</span> | 185 | <span class="keyword">let</span> <span class="variable declaration">foo2</span> <span class="operator">=</span> <span class="struct">Foo</span> <span class="brace">{</span> <span class="field">x</span><span class="comma">,</span> <span class="field">y</span><span class="colon">:</span> <span class="variable mutable">x</span> <span class="brace">}</span><span class="semicolon">;</span> |
186 | <span class="variable mutable">foo</span><span class="operator">.</span><span class="function associated">quop</span><span class="punctuation">(</span><span class="punctuation">)</span><span class="punctuation">;</span> | 186 | <span class="variable mutable">foo</span><span class="operator">.</span><span class="function associated">quop</span><span class="parenthesis">(</span><span class="parenthesis">)</span><span class="semicolon">;</span> |
187 | <span class="variable mutable">foo</span><span class="operator">.</span><span class="function mutable associated">qux</span><span class="punctuation">(</span><span class="punctuation">)</span><span class="punctuation">;</span> | 187 | <span class="variable mutable">foo</span><span class="operator">.</span><span class="function mutable associated">qux</span><span class="parenthesis">(</span><span class="parenthesis">)</span><span class="semicolon">;</span> |
188 | <span class="variable mutable">foo</span><span class="operator">.</span><span class="function consuming associated">baz</span><span class="punctuation">(</span><span class="variable consuming">foo2</span><span class="punctuation">)</span><span class="punctuation">;</span> | 188 | <span class="variable mutable">foo</span><span class="operator">.</span><span class="function consuming associated">baz</span><span class="parenthesis">(</span><span class="variable consuming">foo2</span><span class="parenthesis">)</span><span class="semicolon">;</span> |
189 | 189 | ||
190 | <span class="keyword">let</span> <span class="keyword">mut</span> <span class="variable declaration mutable">copy</span> <span class="operator">=</span> <span class="struct">FooCopy</span> <span class="punctuation">{</span> <span class="field">x</span> <span class="punctuation">}</span><span class="punctuation">;</span> | 190 | <span class="keyword">let</span> <span class="keyword">mut</span> <span class="variable declaration mutable">copy</span> <span class="operator">=</span> <span class="struct">FooCopy</span> <span class="brace">{</span> <span class="field">x</span> <span class="brace">}</span><span class="semicolon">;</span> |
191 | <span class="variable mutable">copy</span><span class="operator">.</span><span class="function associated">quop</span><span class="punctuation">(</span><span class="punctuation">)</span><span class="punctuation">;</span> | 191 | <span class="variable mutable">copy</span><span class="operator">.</span><span class="function associated">quop</span><span class="parenthesis">(</span><span class="parenthesis">)</span><span class="semicolon">;</span> |
192 | <span class="variable mutable">copy</span><span class="operator">.</span><span class="function mutable associated">qux</span><span class="punctuation">(</span><span class="punctuation">)</span><span class="punctuation">;</span> | 192 | <span class="variable mutable">copy</span><span class="operator">.</span><span class="function mutable associated">qux</span><span class="parenthesis">(</span><span class="parenthesis">)</span><span class="semicolon">;</span> |
193 | <span class="variable mutable">copy</span><span class="operator">.</span><span class="function associated">baz</span><span class="punctuation">(</span><span class="variable mutable">copy</span><span class="punctuation">)</span><span class="punctuation">;</span> | 193 | <span class="variable mutable">copy</span><span class="operator">.</span><span class="function associated">baz</span><span class="parenthesis">(</span><span class="variable mutable">copy</span><span class="parenthesis">)</span><span class="semicolon">;</span> |
194 | 194 | ||
195 | <span class="keyword">let</span> <span class="variable declaration callable">a</span> <span class="operator">=</span> <span class="punctuation">|</span><span class="value_param declaration">x</span><span class="punctuation">|</span> <span class="value_param">x</span><span class="punctuation">;</span> | 195 | <span class="keyword">let</span> <span class="variable declaration callable">a</span> <span class="operator">=</span> <span class="punctuation">|</span><span class="value_param declaration">x</span><span class="punctuation">|</span> <span class="value_param">x</span><span class="semicolon">;</span> |
196 | <span class="keyword">let</span> <span class="variable declaration callable">bar</span> <span class="operator">=</span> <span class="struct">Foo</span><span class="operator">::</span><span class="function associated">baz</span><span class="punctuation">;</span> | 196 | <span class="keyword">let</span> <span class="variable declaration callable">bar</span> <span class="operator">=</span> <span class="struct">Foo</span><span class="operator">::</span><span class="function associated">baz</span><span class="semicolon">;</span> |
197 | 197 | ||
198 | <span class="keyword">let</span> <span class="variable declaration">baz</span> <span class="operator">=</span> <span class="numeric_literal">-</span><span class="numeric_literal">42</span><span class="punctuation">;</span> | 198 | <span class="keyword">let</span> <span class="variable declaration">baz</span> <span class="operator">=</span> <span class="numeric_literal">-</span><span class="numeric_literal">42</span><span class="semicolon">;</span> |
199 | <span class="keyword">let</span> <span class="variable declaration">baz</span> <span class="operator">=</span> <span class="operator">-</span><span class="variable">baz</span><span class="punctuation">;</span> | 199 | <span class="keyword">let</span> <span class="variable declaration">baz</span> <span class="operator">=</span> <span class="operator">-</span><span class="variable">baz</span><span class="semicolon">;</span> |
200 | 200 | ||
201 | <span class="keyword">let</span> <span class="punctuation">_</span> <span class="operator">=</span> <span class="operator">!</span><span class="bool_literal">true</span><span class="punctuation">;</span> | 201 | <span class="keyword">let</span> <span class="punctuation">_</span> <span class="operator">=</span> <span class="operator">!</span><span class="bool_literal">true</span><span class="semicolon">;</span> |
202 | 202 | ||
203 | <span class="label declaration">'foo</span><span class="punctuation">:</span> <span class="keyword control">loop</span> <span class="punctuation">{</span> | 203 | <span class="label declaration">'foo</span><span class="colon">:</span> <span class="keyword control">loop</span> <span class="brace">{</span> |
204 | <span class="keyword control">break</span> <span class="label">'foo</span><span class="punctuation">;</span> | 204 | <span class="keyword control">break</span> <span class="label">'foo</span><span class="semicolon">;</span> |
205 | <span class="keyword control">continue</span> <span class="label">'foo</span><span class="punctuation">;</span> | 205 | <span class="keyword control">continue</span> <span class="label">'foo</span><span class="semicolon">;</span> |
206 | <span class="punctuation">}</span> | 206 | <span class="brace">}</span> |
207 | <span class="punctuation">}</span> | 207 | <span class="brace">}</span> |
208 | 208 | ||
209 | <span class="keyword">enum</span> <span class="enum declaration">Option</span><span class="punctuation"><</span><span class="type_param declaration">T</span><span class="punctuation">></span> <span class="punctuation">{</span> | 209 | <span class="keyword">enum</span> <span class="enum declaration">Option</span><span class="angle"><</span><span class="type_param declaration">T</span><span class="angle">></span> <span class="brace">{</span> |
210 | <span class="enum_variant declaration">Some</span><span class="punctuation">(</span><span class="type_param">T</span><span class="punctuation">)</span><span class="punctuation">,</span> | 210 | <span class="enum_variant declaration">Some</span><span class="parenthesis">(</span><span class="type_param">T</span><span class="parenthesis">)</span><span class="comma">,</span> |
211 | <span class="enum_variant declaration">None</span><span class="punctuation">,</span> | 211 | <span class="enum_variant declaration">None</span><span class="comma">,</span> |
212 | <span class="punctuation">}</span> | 212 | <span class="brace">}</span> |
213 | <span class="keyword">use</span> <span class="enum">Option</span><span class="operator">::</span><span class="punctuation">*</span><span class="punctuation">;</span> | 213 | <span class="keyword">use</span> <span class="enum">Option</span><span class="operator">::</span><span class="punctuation">*</span><span class="semicolon">;</span> |
214 | 214 | ||
215 | <span class="keyword">impl</span><span class="punctuation"><</span><span class="type_param declaration">T</span><span class="punctuation">></span> <span class="enum">Option</span><span class="punctuation"><</span><span class="type_param">T</span><span class="punctuation">></span> <span class="punctuation">{</span> | 215 | <span class="keyword">impl</span><span class="angle"><</span><span class="type_param declaration">T</span><span class="angle">></span> <span class="enum">Option</span><span class="angle"><</span><span class="type_param">T</span><span class="angle">></span> <span class="brace">{</span> |
216 | <span class="keyword">fn</span> <span class="function declaration associated">and</span><span class="punctuation"><</span><span class="type_param declaration">U</span><span class="punctuation">></span><span class="punctuation">(</span><span class="self_keyword">self</span><span class="punctuation">,</span> <span class="value_param declaration">other</span><span class="punctuation">:</span> <span class="enum">Option</span><span class="punctuation"><</span><span class="type_param">U</span><span class="punctuation">></span><span class="punctuation">)</span> <span class="operator">-></span> <span class="enum">Option</span><span class="punctuation"><</span><span class="punctuation">(</span><span class="type_param">T</span><span class="punctuation">,</span> <span class="type_param">U</span><span class="punctuation">)</span><span class="punctuation">></span> <span class="punctuation">{</span> | 216 | <span class="keyword">fn</span> <span class="function declaration associated">and</span><span class="angle"><</span><span class="type_param declaration">U</span><span class="angle">></span><span class="parenthesis">(</span><span class="self_keyword">self</span><span class="comma">,</span> <span class="value_param declaration">other</span><span class="colon">:</span> <span class="enum">Option</span><span class="angle"><</span><span class="type_param">U</span><span class="angle">></span><span class="parenthesis">)</span> <span class="operator">-></span> <span class="enum">Option</span><span class="angle"><</span><span class="parenthesis">(</span><span class="type_param">T</span><span class="comma">,</span> <span class="type_param">U</span><span class="parenthesis">)</span><span class="angle">></span> <span class="brace">{</span> |
217 | <span class="keyword control">match</span> <span class="value_param">other</span> <span class="punctuation">{</span> | 217 | <span class="keyword control">match</span> <span class="value_param">other</span> <span class="brace">{</span> |
218 | <span class="enum_variant">None</span> <span class="operator">=></span> <span class="macro">unimplemented!</span><span class="punctuation">(</span><span class="punctuation">)</span><span class="punctuation">,</span> | 218 | <span class="enum_variant">None</span> <span class="operator">=></span> <span class="macro">unimplemented!</span><span class="parenthesis">(</span><span class="parenthesis">)</span><span class="comma">,</span> |
219 | <span class="variable declaration">Nope</span> <span class="operator">=></span> <span class="variable">Nope</span><span class="punctuation">,</span> | 219 | <span class="variable declaration">Nope</span> <span class="operator">=></span> <span class="variable">Nope</span><span class="comma">,</span> |
220 | <span class="punctuation">}</span> | 220 | <span class="brace">}</span> |
221 | <span class="punctuation">}</span> | 221 | <span class="brace">}</span> |
222 | <span class="punctuation">}</span></code></pre> \ No newline at end of file | 222 | <span class="brace">}</span></code></pre> \ No newline at end of file |
diff --git a/crates/ide/src/syntax_highlighting/test_data/injection.html b/crates/ide/src/syntax_highlighting/test_data/injection.html index 6703a84e5..78dfec951 100644 --- a/crates/ide/src/syntax_highlighting/test_data/injection.html +++ b/crates/ide/src/syntax_highlighting/test_data/injection.html | |||
@@ -36,13 +36,13 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd | |||
36 | 36 | ||
37 | .unresolved_reference { color: #FC5555; text-decoration: wavy underline; } | 37 | .unresolved_reference { color: #FC5555; text-decoration: wavy underline; } |
38 | </style> | 38 | </style> |
39 | <pre><code><span class="keyword">fn</span> <span class="function declaration">f</span><span class="punctuation">(</span><span class="value_param declaration">ra_fixture</span><span class="punctuation">:</span> <span class="operator">&</span><span class="builtin_type">str</span><span class="punctuation">)</span> <span class="punctuation">{</span><span class="punctuation">}</span> | 39 | <pre><code><span class="keyword">fn</span> <span class="function declaration">f</span><span class="parenthesis">(</span><span class="value_param declaration">ra_fixture</span><span class="colon">:</span> <span class="operator">&</span><span class="builtin_type">str</span><span class="parenthesis">)</span> <span class="brace">{</span><span class="brace">}</span> |
40 | <span class="keyword">fn</span> <span class="function declaration">main</span><span class="punctuation">(</span><span class="punctuation">)</span> <span class="punctuation">{</span> | 40 | <span class="keyword">fn</span> <span class="function declaration">main</span><span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="brace">{</span> |
41 | <span class="function">f</span><span class="punctuation">(</span><span class="string_literal">r"</span> | 41 | <span class="function">f</span><span class="parenthesis">(</span><span class="string_literal">r"</span> |
42 | <span class="keyword">fn</span> <span class="function declaration">foo</span><span class="punctuation">(</span><span class="punctuation">)</span> <span class="punctuation">{</span> | 42 | <span class="keyword">fn</span> <span class="function declaration">foo</span><span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="brace">{</span> |
43 | <span class="function">foo</span><span class="punctuation">(</span><span class="keyword">$0</span><span class="punctuation">{</span> | 43 | <span class="function">foo</span><span class="parenthesis">(</span><span class="keyword">$0</span><span class="brace">{</span> |
44 | <span class="numeric_literal">92</span> | 44 | <span class="numeric_literal">92</span> |
45 | <span class="punctuation">}</span><span class="keyword">$0</span><span class="punctuation">)</span> | 45 | <span class="brace">}</span><span class="keyword">$0</span><span class="parenthesis">)</span> |
46 | <span class="punctuation">}</span><span class="string_literal">"</span><span class="punctuation">)</span><span class="punctuation">;</span> | 46 | <span class="brace">}</span><span class="string_literal">"</span><span class="parenthesis">)</span><span class="semicolon">;</span> |
47 | <span class="punctuation">}</span> | 47 | <span class="brace">}</span> |
48 | </code></pre> \ No newline at end of file | 48 | </code></pre> \ No newline at end of file |
diff --git a/crates/ide/src/syntax_highlighting/test_data/rainbow_highlighting.html b/crates/ide/src/syntax_highlighting/test_data/rainbow_highlighting.html index 8b3dfa69f..e64f2e5e9 100644 --- a/crates/ide/src/syntax_highlighting/test_data/rainbow_highlighting.html +++ b/crates/ide/src/syntax_highlighting/test_data/rainbow_highlighting.html | |||
@@ -36,15 +36,15 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd | |||
36 | 36 | ||
37 | .unresolved_reference { color: #FC5555; text-decoration: wavy underline; } | 37 | .unresolved_reference { color: #FC5555; text-decoration: wavy underline; } |
38 | </style> | 38 | </style> |
39 | <pre><code><span class="keyword">fn</span> <span class="function declaration">main</span><span class="punctuation">(</span><span class="punctuation">)</span> <span class="punctuation">{</span> | 39 | <pre><code><span class="keyword">fn</span> <span class="function declaration">main</span><span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="brace">{</span> |
40 | <span class="keyword">let</span> <span class="variable declaration" data-binding-hash="8121853618659664005" style="color: hsl(273,88%,88%);">hello</span> <span class="operator">=</span> <span class="string_literal">"hello"</span><span class="punctuation">;</span> | 40 | <span class="keyword">let</span> <span class="variable declaration" data-binding-hash="8121853618659664005" style="color: hsl(273,88%,88%);">hello</span> <span class="operator">=</span> <span class="string_literal">"hello"</span><span class="semicolon">;</span> |
41 | <span class="keyword">let</span> <span class="variable declaration" data-binding-hash="2705725358298919760" style="color: hsl(76,47%,83%);">x</span> <span class="operator">=</span> <span class="variable" data-binding-hash="8121853618659664005" style="color: hsl(273,88%,88%);">hello</span><span class="operator">.</span><span class="unresolved_reference">to_string</span><span class="punctuation">(</span><span class="punctuation">)</span><span class="punctuation">;</span> | 41 | <span class="keyword">let</span> <span class="variable declaration" data-binding-hash="2705725358298919760" style="color: hsl(76,47%,83%);">x</span> <span class="operator">=</span> <span class="variable" data-binding-hash="8121853618659664005" style="color: hsl(273,88%,88%);">hello</span><span class="operator">.</span><span class="unresolved_reference">to_string</span><span class="parenthesis">(</span><span class="parenthesis">)</span><span class="semicolon">;</span> |
42 | <span class="keyword">let</span> <span class="variable declaration" data-binding-hash="3365759661443752373" style="color: hsl(15,86%,51%);">y</span> <span class="operator">=</span> <span class="variable" data-binding-hash="8121853618659664005" style="color: hsl(273,88%,88%);">hello</span><span class="operator">.</span><span class="unresolved_reference">to_string</span><span class="punctuation">(</span><span class="punctuation">)</span><span class="punctuation">;</span> | 42 | <span class="keyword">let</span> <span class="variable declaration" data-binding-hash="3365759661443752373" style="color: hsl(15,86%,51%);">y</span> <span class="operator">=</span> <span class="variable" data-binding-hash="8121853618659664005" style="color: hsl(273,88%,88%);">hello</span><span class="operator">.</span><span class="unresolved_reference">to_string</span><span class="parenthesis">(</span><span class="parenthesis">)</span><span class="semicolon">;</span> |
43 | 43 | ||
44 | <span class="keyword">let</span> <span class="variable declaration" data-binding-hash="794745962933817518" style="color: hsl(127,71%,87%);">x</span> <span class="operator">=</span> <span class="string_literal">"other color please!"</span><span class="punctuation">;</span> | 44 | <span class="keyword">let</span> <span class="variable declaration" data-binding-hash="794745962933817518" style="color: hsl(127,71%,87%);">x</span> <span class="operator">=</span> <span class="string_literal">"other color please!"</span><span class="semicolon">;</span> |
45 | <span class="keyword">let</span> <span class="variable declaration" data-binding-hash="6717528807933952652" style="color: hsl(90,74%,79%);">y</span> <span class="operator">=</span> <span class="variable" data-binding-hash="794745962933817518" style="color: hsl(127,71%,87%);">x</span><span class="operator">.</span><span class="unresolved_reference">to_string</span><span class="punctuation">(</span><span class="punctuation">)</span><span class="punctuation">;</span> | 45 | <span class="keyword">let</span> <span class="variable declaration" data-binding-hash="6717528807933952652" style="color: hsl(90,74%,79%);">y</span> <span class="operator">=</span> <span class="variable" data-binding-hash="794745962933817518" style="color: hsl(127,71%,87%);">x</span><span class="operator">.</span><span class="unresolved_reference">to_string</span><span class="parenthesis">(</span><span class="parenthesis">)</span><span class="semicolon">;</span> |
46 | <span class="punctuation">}</span> | 46 | <span class="brace">}</span> |
47 | 47 | ||
48 | <span class="keyword">fn</span> <span class="function declaration">bar</span><span class="punctuation">(</span><span class="punctuation">)</span> <span class="punctuation">{</span> | 48 | <span class="keyword">fn</span> <span class="function declaration">bar</span><span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="brace">{</span> |
49 | <span class="keyword">let</span> <span class="keyword">mut</span> <span class="variable declaration mutable" data-binding-hash="8121853618659664005" style="color: hsl(273,88%,88%);">hello</span> <span class="operator">=</span> <span class="string_literal">"hello"</span><span class="punctuation">;</span> | 49 | <span class="keyword">let</span> <span class="keyword">mut</span> <span class="variable declaration mutable" data-binding-hash="8121853618659664005" style="color: hsl(273,88%,88%);">hello</span> <span class="operator">=</span> <span class="string_literal">"hello"</span><span class="semicolon">;</span> |
50 | <span class="punctuation">}</span></code></pre> \ No newline at end of file | 50 | <span class="brace">}</span></code></pre> \ No newline at end of file |
diff --git a/crates/ide_db/src/defs.rs b/crates/ide_db/src/defs.rs index be1c64b03..d68fe42b0 100644 --- a/crates/ide_db/src/defs.rs +++ b/crates/ide_db/src/defs.rs | |||
@@ -6,8 +6,8 @@ | |||
6 | // FIXME: this badly needs rename/rewrite (matklad, 2020-02-06). | 6 | // FIXME: this badly needs rename/rewrite (matklad, 2020-02-06). |
7 | 7 | ||
8 | use hir::{ | 8 | use hir::{ |
9 | db::HirDatabase, ConstParam, Crate, Field, HasVisibility, Impl, Label, LifetimeParam, Local, | 9 | db::HirDatabase, Crate, Field, GenericParam, HasVisibility, Impl, Label, Local, MacroDef, |
10 | MacroDef, Module, ModuleDef, Name, PathResolution, Semantics, TypeParam, Visibility, | 10 | Module, ModuleDef, Name, PathResolution, Semantics, Visibility, |
11 | }; | 11 | }; |
12 | use syntax::{ | 12 | use syntax::{ |
13 | ast::{self, AstNode}, | 13 | ast::{self, AstNode}, |
@@ -24,9 +24,7 @@ pub enum Definition { | |||
24 | ModuleDef(ModuleDef), | 24 | ModuleDef(ModuleDef), |
25 | SelfType(Impl), | 25 | SelfType(Impl), |
26 | Local(Local), | 26 | Local(Local), |
27 | TypeParam(TypeParam), | 27 | GenericParam(GenericParam), |
28 | LifetimeParam(LifetimeParam), | ||
29 | ConstParam(ConstParam), | ||
30 | Label(Label), | 28 | Label(Label), |
31 | } | 29 | } |
32 | 30 | ||
@@ -38,9 +36,7 @@ impl Definition { | |||
38 | Definition::ModuleDef(it) => it.module(db), | 36 | Definition::ModuleDef(it) => it.module(db), |
39 | Definition::SelfType(it) => Some(it.module(db)), | 37 | Definition::SelfType(it) => Some(it.module(db)), |
40 | Definition::Local(it) => Some(it.module(db)), | 38 | Definition::Local(it) => Some(it.module(db)), |
41 | Definition::TypeParam(it) => Some(it.module(db)), | 39 | Definition::GenericParam(it) => Some(it.module(db)), |
42 | Definition::LifetimeParam(it) => Some(it.module(db)), | ||
43 | Definition::ConstParam(it) => Some(it.module(db)), | ||
44 | Definition::Label(it) => Some(it.module(db)), | 40 | Definition::Label(it) => Some(it.module(db)), |
45 | } | 41 | } |
46 | } | 42 | } |
@@ -52,9 +48,7 @@ impl Definition { | |||
52 | Definition::ModuleDef(def) => def.definition_visibility(db), | 48 | Definition::ModuleDef(def) => def.definition_visibility(db), |
53 | Definition::SelfType(_) => None, | 49 | Definition::SelfType(_) => None, |
54 | Definition::Local(_) => None, | 50 | Definition::Local(_) => None, |
55 | Definition::TypeParam(_) => None, | 51 | Definition::GenericParam(_) => None, |
56 | Definition::LifetimeParam(_) => None, | ||
57 | Definition::ConstParam(_) => None, | ||
58 | Definition::Label(_) => None, | 52 | Definition::Label(_) => None, |
59 | } | 53 | } |
60 | } | 54 | } |
@@ -80,9 +74,7 @@ impl Definition { | |||
80 | }, | 74 | }, |
81 | Definition::SelfType(_) => return None, | 75 | Definition::SelfType(_) => return None, |
82 | Definition::Local(it) => it.name(db)?, | 76 | Definition::Local(it) => it.name(db)?, |
83 | Definition::TypeParam(it) => it.name(db), | 77 | Definition::GenericParam(it) => it.name(db), |
84 | Definition::LifetimeParam(it) => it.name(db), | ||
85 | Definition::ConstParam(it) => it.name(db), | ||
86 | Definition::Label(it) => it.name(db), | 78 | Definition::Label(it) => it.name(db), |
87 | }; | 79 | }; |
88 | Some(name) | 80 | Some(name) |
@@ -235,11 +227,11 @@ impl NameClass { | |||
235 | }, | 227 | }, |
236 | ast::TypeParam(it) => { | 228 | ast::TypeParam(it) => { |
237 | let def = sema.to_def(&it)?; | 229 | let def = sema.to_def(&it)?; |
238 | Some(NameClass::Definition(Definition::TypeParam(def))) | 230 | Some(NameClass::Definition(Definition::GenericParam(def.into()))) |
239 | }, | 231 | }, |
240 | ast::ConstParam(it) => { | 232 | ast::ConstParam(it) => { |
241 | let def = sema.to_def(&it)?; | 233 | let def = sema.to_def(&it)?; |
242 | Some(NameClass::Definition(Definition::ConstParam(def))) | 234 | Some(NameClass::Definition(Definition::GenericParam(def.into()))) |
243 | }, | 235 | }, |
244 | _ => None, | 236 | _ => None, |
245 | } | 237 | } |
@@ -257,7 +249,7 @@ impl NameClass { | |||
257 | match parent { | 249 | match parent { |
258 | ast::LifetimeParam(it) => { | 250 | ast::LifetimeParam(it) => { |
259 | let def = sema.to_def(&it)?; | 251 | let def = sema.to_def(&it)?; |
260 | Some(NameClass::Definition(Definition::LifetimeParam(def))) | 252 | Some(NameClass::Definition(Definition::GenericParam(def.into()))) |
261 | }, | 253 | }, |
262 | ast::Label(it) => { | 254 | ast::Label(it) => { |
263 | let def = sema.to_def(&it)?; | 255 | let def = sema.to_def(&it)?; |
@@ -393,7 +385,8 @@ impl NameRefClass { | |||
393 | | SyntaxKind::WHERE_PRED | 385 | | SyntaxKind::WHERE_PRED |
394 | | SyntaxKind::REF_TYPE => sema | 386 | | SyntaxKind::REF_TYPE => sema |
395 | .resolve_lifetime_param(lifetime) | 387 | .resolve_lifetime_param(lifetime) |
396 | .map(Definition::LifetimeParam) | 388 | .map(GenericParam::LifetimeParam) |
389 | .map(Definition::GenericParam) | ||
397 | .map(NameRefClass::Definition), | 390 | .map(NameRefClass::Definition), |
398 | // lifetime bounds, as in the 'b in 'a: 'b aren't wrapped in TypeBound nodes so we gotta check | 391 | // lifetime bounds, as in the 'b in 'a: 'b aren't wrapped in TypeBound nodes so we gotta check |
399 | // if our lifetime is in a LifetimeParam without being the constrained lifetime | 392 | // if our lifetime is in a LifetimeParam without being the constrained lifetime |
@@ -401,7 +394,8 @@ impl NameRefClass { | |||
401 | != Some(lifetime) => | 394 | != Some(lifetime) => |
402 | { | 395 | { |
403 | sema.resolve_lifetime_param(lifetime) | 396 | sema.resolve_lifetime_param(lifetime) |
404 | .map(Definition::LifetimeParam) | 397 | .map(GenericParam::LifetimeParam) |
398 | .map(Definition::GenericParam) | ||
405 | .map(NameRefClass::Definition) | 399 | .map(NameRefClass::Definition) |
406 | } | 400 | } |
407 | _ => None, | 401 | _ => None, |
@@ -422,10 +416,10 @@ impl From<PathResolution> for Definition { | |||
422 | Definition::ModuleDef(def) | 416 | Definition::ModuleDef(def) |
423 | } | 417 | } |
424 | PathResolution::Local(local) => Definition::Local(local), | 418 | PathResolution::Local(local) => Definition::Local(local), |
425 | PathResolution::TypeParam(par) => Definition::TypeParam(par), | 419 | PathResolution::TypeParam(par) => Definition::GenericParam(par.into()), |
426 | PathResolution::Macro(def) => Definition::Macro(def), | 420 | PathResolution::Macro(def) => Definition::Macro(def), |
427 | PathResolution::SelfType(impl_def) => Definition::SelfType(impl_def), | 421 | PathResolution::SelfType(impl_def) => Definition::SelfType(impl_def), |
428 | PathResolution::ConstParam(par) => Definition::ConstParam(par), | 422 | PathResolution::ConstParam(par) => Definition::GenericParam(par.into()), |
429 | } | 423 | } |
430 | } | 424 | } |
431 | } | 425 | } |
diff --git a/crates/ide_db/src/search.rs b/crates/ide_db/src/search.rs index 37b06027c..773bfbc2c 100644 --- a/crates/ide_db/src/search.rs +++ b/crates/ide_db/src/search.rs | |||
@@ -136,7 +136,7 @@ impl Definition { | |||
136 | return SearchScope::new(res); | 136 | return SearchScope::new(res); |
137 | } | 137 | } |
138 | 138 | ||
139 | if let Definition::LifetimeParam(param) = self { | 139 | if let Definition::GenericParam(hir::GenericParam::LifetimeParam(param)) = self { |
140 | let range = match param.parent(db) { | 140 | let range = match param.parent(db) { |
141 | hir::GenericDef::Function(it) => { | 141 | hir::GenericDef::Function(it) => { |
142 | it.source(db).and_then(|src| Some(src.value.syntax().text_range())) | 142 | it.source(db).and_then(|src| Some(src.value.syntax().text_range())) |
diff --git a/crates/parser/src/grammar/expressions/atom.rs b/crates/parser/src/grammar/expressions/atom.rs index c7a3556a7..d61950b96 100644 --- a/crates/parser/src/grammar/expressions/atom.rs +++ b/crates/parser/src/grammar/expressions/atom.rs | |||
@@ -15,8 +15,16 @@ use super::*; | |||
15 | // let _ = b"e"; | 15 | // let _ = b"e"; |
16 | // let _ = br"f"; | 16 | // let _ = br"f"; |
17 | // } | 17 | // } |
18 | pub(crate) const LITERAL_FIRST: TokenSet = | 18 | pub(crate) const LITERAL_FIRST: TokenSet = TokenSet::new(&[ |
19 | TokenSet::new(&[TRUE_KW, FALSE_KW, INT_NUMBER, FLOAT_NUMBER, BYTE, CHAR, STRING, BYTE_STRING]); | 19 | T![true], |
20 | T![false], | ||
21 | INT_NUMBER, | ||
22 | FLOAT_NUMBER, | ||
23 | BYTE, | ||
24 | CHAR, | ||
25 | STRING, | ||
26 | BYTE_STRING, | ||
27 | ]); | ||
20 | 28 | ||
21 | pub(crate) fn literal(p: &mut Parser) -> Option<CompletedMarker> { | 29 | pub(crate) fn literal(p: &mut Parser) -> Option<CompletedMarker> { |
22 | if !p.at_ts(LITERAL_FIRST) { | 30 | if !p.at_ts(LITERAL_FIRST) { |
diff --git a/crates/parser/src/grammar/items.rs b/crates/parser/src/grammar/items.rs index cf4168d32..2070ce163 100644 --- a/crates/parser/src/grammar/items.rs +++ b/crates/parser/src/grammar/items.rs | |||
@@ -27,19 +27,19 @@ pub(super) fn mod_contents(p: &mut Parser, stop_on_r_curly: bool) { | |||
27 | } | 27 | } |
28 | 28 | ||
29 | pub(super) const ITEM_RECOVERY_SET: TokenSet = TokenSet::new(&[ | 29 | pub(super) const ITEM_RECOVERY_SET: TokenSet = TokenSet::new(&[ |
30 | FN_KW, | 30 | T![fn], |
31 | STRUCT_KW, | 31 | T![struct], |
32 | ENUM_KW, | 32 | T![enum], |
33 | IMPL_KW, | 33 | T![impl], |
34 | TRAIT_KW, | 34 | T![trait], |
35 | CONST_KW, | 35 | T![const], |
36 | STATIC_KW, | 36 | T![static], |
37 | LET_KW, | 37 | T![let], |
38 | MOD_KW, | 38 | T![mod], |
39 | PUB_KW, | 39 | T![pub], |
40 | CRATE_KW, | 40 | T![crate], |
41 | USE_KW, | 41 | T![use], |
42 | MACRO_KW, | 42 | T![macro], |
43 | T![;], | 43 | T![;], |
44 | ]); | 44 | ]); |
45 | 45 | ||
diff --git a/crates/parser/src/grammar/items/traits.rs b/crates/parser/src/grammar/items/traits.rs index ab9a12b4d..d076974ed 100644 --- a/crates/parser/src/grammar/items/traits.rs +++ b/crates/parser/src/grammar/items/traits.rs | |||
@@ -110,7 +110,7 @@ fn choose_type_params_over_qpath(p: &Parser) -> bool { | |||
110 | if !p.at(T![<]) { | 110 | if !p.at(T![<]) { |
111 | return false; | 111 | return false; |
112 | } | 112 | } |
113 | if p.nth(1) == T![#] || p.nth(1) == T![>] || p.nth(1) == CONST_KW { | 113 | if p.nth(1) == T![#] || p.nth(1) == T![>] || p.nth(1) == T![const] { |
114 | return true; | 114 | return true; |
115 | } | 115 | } |
116 | (p.nth(1) == LIFETIME_IDENT || p.nth(1) == IDENT) | 116 | (p.nth(1) == LIFETIME_IDENT || p.nth(1) == IDENT) |
diff --git a/crates/parser/src/grammar/patterns.rs b/crates/parser/src/grammar/patterns.rs index b53d5749f..da71498a8 100644 --- a/crates/parser/src/grammar/patterns.rs +++ b/crates/parser/src/grammar/patterns.rs | |||
@@ -83,7 +83,7 @@ fn pattern_single_r(p: &mut Parser, recovery_set: TokenSet) { | |||
83 | } | 83 | } |
84 | 84 | ||
85 | const PAT_RECOVERY_SET: TokenSet = | 85 | const PAT_RECOVERY_SET: TokenSet = |
86 | TokenSet::new(&[LET_KW, IF_KW, WHILE_KW, LOOP_KW, MATCH_KW, R_PAREN, COMMA]); | 86 | TokenSet::new(&[T![let], T![if], T![while], T![loop], T![match], T![')'], T![,]]); |
87 | 87 | ||
88 | fn atom_pat(p: &mut Parser, recovery_set: TokenSet) -> Option<CompletedMarker> { | 88 | fn atom_pat(p: &mut Parser, recovery_set: TokenSet) -> Option<CompletedMarker> { |
89 | let m = match p.nth(0) { | 89 | let m = match p.nth(0) { |
diff --git a/crates/parser/src/grammar/type_args.rs b/crates/parser/src/grammar/type_args.rs index a013c49b9..42cd426bd 100644 --- a/crates/parser/src/grammar/type_args.rs +++ b/crates/parser/src/grammar/type_args.rs | |||
@@ -26,7 +26,7 @@ pub(super) fn opt_generic_arg_list(p: &mut Parser, colon_colon_required: bool) { | |||
26 | } | 26 | } |
27 | 27 | ||
28 | // test type_arg | 28 | // test type_arg |
29 | // type A = B<'static, i32, 1, { 2 }, Item=u64>; | 29 | // type A = B<'static, i32, 1, { 2 }, Item=u64, true, false>; |
30 | fn generic_arg(p: &mut Parser) { | 30 | fn generic_arg(p: &mut Parser) { |
31 | let m = p.start(); | 31 | let m = p.start(); |
32 | match p.current() { | 32 | match p.current() { |
@@ -55,6 +55,10 @@ fn generic_arg(p: &mut Parser) { | |||
55 | expressions::literal(p); | 55 | expressions::literal(p); |
56 | m.complete(p, CONST_ARG); | 56 | m.complete(p, CONST_ARG); |
57 | } | 57 | } |
58 | T![true] | T![false] => { | ||
59 | expressions::literal(p); | ||
60 | m.complete(p, CONST_ARG); | ||
61 | } | ||
58 | _ => { | 62 | _ => { |
59 | types::type_(p); | 63 | types::type_(p); |
60 | m.complete(p, TYPE_ARG); | 64 | m.complete(p, TYPE_ARG); |
diff --git a/crates/parser/src/grammar/type_params.rs b/crates/parser/src/grammar/type_params.rs index 4aeccd193..3de5248da 100644 --- a/crates/parser/src/grammar/type_params.rs +++ b/crates/parser/src/grammar/type_params.rs | |||
@@ -25,7 +25,7 @@ fn generic_param_list(p: &mut Parser) { | |||
25 | match p.current() { | 25 | match p.current() { |
26 | LIFETIME_IDENT => lifetime_param(p, m), | 26 | LIFETIME_IDENT => lifetime_param(p, m), |
27 | IDENT => type_param(p, m), | 27 | IDENT => type_param(p, m), |
28 | CONST_KW => const_param(p, m), | 28 | T![const] => const_param(p, m), |
29 | _ => { | 29 | _ => { |
30 | m.abandon(p); | 30 | m.abandon(p); |
31 | p.err_and_bump("expected type parameter") | 31 | p.err_and_bump("expected type parameter") |
@@ -66,7 +66,7 @@ fn type_param(p: &mut Parser, m: Marker) { | |||
66 | // test const_param | 66 | // test const_param |
67 | // struct S<const N: u32>; | 67 | // struct S<const N: u32>; |
68 | fn const_param(p: &mut Parser, m: Marker) { | 68 | fn const_param(p: &mut Parser, m: Marker) { |
69 | assert!(p.at(CONST_KW)); | 69 | assert!(p.at(T![const])); |
70 | p.bump(T![const]); | 70 | p.bump(T![const]); |
71 | name(p); | 71 | name(p); |
72 | types::ascription(p); | 72 | types::ascription(p); |
diff --git a/crates/rust-analyzer/src/cli/analysis_stats.rs b/crates/rust-analyzer/src/cli/analysis_stats.rs index 9445aec07..30811bbbf 100644 --- a/crates/rust-analyzer/src/cli/analysis_stats.rs +++ b/crates/rust-analyzer/src/cli/analysis_stats.rs | |||
@@ -302,7 +302,7 @@ impl AnalysisStatsCmd { | |||
302 | report_metric("total memory", memory.allocated.megabytes() as u64, "MB"); | 302 | report_metric("total memory", memory.allocated.megabytes() as u64, "MB"); |
303 | } | 303 | } |
304 | 304 | ||
305 | if self.memory_usage { | 305 | if self.memory_usage && verbosity.is_verbose() { |
306 | print_memory_usage(host, vfs); | 306 | print_memory_usage(host, vfs); |
307 | } | 307 | } |
308 | 308 | ||
diff --git a/crates/rust-analyzer/src/global_state.rs b/crates/rust-analyzer/src/global_state.rs index 1f6bf1c8c..442fbd14c 100644 --- a/crates/rust-analyzer/src/global_state.rs +++ b/crates/rust-analyzer/src/global_state.rs | |||
@@ -22,6 +22,7 @@ use crate::{ | |||
22 | from_proto, | 22 | from_proto, |
23 | line_endings::LineEndings, | 23 | line_endings::LineEndings, |
24 | main_loop::Task, | 24 | main_loop::Task, |
25 | op_queue::OpQueue, | ||
25 | reload::SourceRootConfig, | 26 | reload::SourceRootConfig, |
26 | request_metrics::{LatestRequests, RequestMetrics}, | 27 | request_metrics::{LatestRequests, RequestMetrics}, |
27 | thread_pool::TaskPool, | 28 | thread_pool::TaskPool, |
@@ -78,6 +79,7 @@ pub(crate) struct GlobalState { | |||
78 | pub(crate) source_root_config: SourceRootConfig, | 79 | pub(crate) source_root_config: SourceRootConfig, |
79 | pub(crate) proc_macro_client: Option<ProcMacroClient>, | 80 | pub(crate) proc_macro_client: Option<ProcMacroClient>, |
80 | pub(crate) workspaces: Arc<Vec<ProjectWorkspace>>, | 81 | pub(crate) workspaces: Arc<Vec<ProjectWorkspace>>, |
82 | pub(crate) fetch_workspaces_queue: OpQueue, | ||
81 | latest_requests: Arc<RwLock<LatestRequests>>, | 83 | latest_requests: Arc<RwLock<LatestRequests>>, |
82 | } | 84 | } |
83 | 85 | ||
@@ -130,6 +132,7 @@ impl GlobalState { | |||
130 | source_root_config: SourceRootConfig::default(), | 132 | source_root_config: SourceRootConfig::default(), |
131 | proc_macro_client: None, | 133 | proc_macro_client: None, |
132 | workspaces: Arc::new(Vec::new()), | 134 | workspaces: Arc::new(Vec::new()), |
135 | fetch_workspaces_queue: OpQueue::default(), | ||
133 | latest_requests: Default::default(), | 136 | latest_requests: Default::default(), |
134 | } | 137 | } |
135 | } | 138 | } |
diff --git a/crates/rust-analyzer/src/lib.rs b/crates/rust-analyzer/src/lib.rs index c9494e300..2207b9a87 100644 --- a/crates/rust-analyzer/src/lib.rs +++ b/crates/rust-analyzer/src/lib.rs | |||
@@ -35,6 +35,7 @@ mod lsp_utils; | |||
35 | mod thread_pool; | 35 | mod thread_pool; |
36 | mod document; | 36 | mod document; |
37 | mod diff; | 37 | mod diff; |
38 | mod op_queue; | ||
38 | pub mod lsp_ext; | 39 | pub mod lsp_ext; |
39 | pub mod config; | 40 | pub mod config; |
40 | 41 | ||
diff --git a/crates/rust-analyzer/src/main_loop.rs b/crates/rust-analyzer/src/main_loop.rs index 22ee96775..51fb2eb74 100644 --- a/crates/rust-analyzer/src/main_loop.rs +++ b/crates/rust-analyzer/src/main_loop.rs | |||
@@ -11,7 +11,6 @@ use ide::{Canceled, FileId}; | |||
11 | use ide_db::base_db::VfsPath; | 11 | use ide_db::base_db::VfsPath; |
12 | use lsp_server::{Connection, Notification, Request, Response}; | 12 | use lsp_server::{Connection, Notification, Request, Response}; |
13 | use lsp_types::notification::Notification as _; | 13 | use lsp_types::notification::Notification as _; |
14 | use project_model::ProjectWorkspace; | ||
15 | use vfs::ChangeKind; | 14 | use vfs::ChangeKind; |
16 | 15 | ||
17 | use crate::{ | 16 | use crate::{ |
@@ -62,7 +61,6 @@ enum Event { | |||
62 | pub(crate) enum Task { | 61 | pub(crate) enum Task { |
63 | Response(Response), | 62 | Response(Response), |
64 | Diagnostics(Vec<(FileId, Vec<lsp_types::Diagnostic>)>), | 63 | Diagnostics(Vec<(FileId, Vec<lsp_types::Diagnostic>)>), |
65 | Workspaces(Vec<anyhow::Result<ProjectWorkspace>>), | ||
66 | PrimeCaches(PrimeCachesProgress), | 64 | PrimeCaches(PrimeCachesProgress), |
67 | FetchWorkspace(ProjectWorkspaceProgress), | 65 | FetchWorkspace(ProjectWorkspaceProgress), |
68 | } | 66 | } |
@@ -143,7 +141,8 @@ impl GlobalState { | |||
143 | |_, _| (), | 141 | |_, _| (), |
144 | ); | 142 | ); |
145 | 143 | ||
146 | self.fetch_workspaces(); | 144 | self.fetch_workspaces_request(); |
145 | self.fetch_workspaces_if_needed(); | ||
147 | 146 | ||
148 | while let Some(event) = self.next_event(&inbox) { | 147 | while let Some(event) = self.next_event(&inbox) { |
149 | if let Event::Lsp(lsp_server::Message::Notification(not)) = &event { | 148 | if let Event::Lsp(lsp_server::Message::Notification(not)) = &event { |
@@ -204,7 +203,6 @@ impl GlobalState { | |||
204 | self.diagnostics.set_native_diagnostics(file_id, diagnostics) | 203 | self.diagnostics.set_native_diagnostics(file_id, diagnostics) |
205 | } | 204 | } |
206 | } | 205 | } |
207 | Task::Workspaces(workspaces) => self.switch_workspaces(workspaces), | ||
208 | Task::PrimeCaches(progress) => match progress { | 206 | Task::PrimeCaches(progress) => match progress { |
209 | PrimeCachesProgress::Started => prime_caches_progress.push(progress), | 207 | PrimeCachesProgress::Started => prime_caches_progress.push(progress), |
210 | PrimeCachesProgress::StartedOnCrate { .. } => { | 208 | PrimeCachesProgress::StartedOnCrate { .. } => { |
@@ -224,7 +222,11 @@ impl GlobalState { | |||
224 | ProjectWorkspaceProgress::Report(msg) => { | 222 | ProjectWorkspaceProgress::Report(msg) => { |
225 | (Progress::Report, Some(msg)) | 223 | (Progress::Report, Some(msg)) |
226 | } | 224 | } |
227 | ProjectWorkspaceProgress::End => (Progress::End, None), | 225 | ProjectWorkspaceProgress::End(workspaces) => { |
226 | self.fetch_workspaces_completed(); | ||
227 | self.switch_workspaces(workspaces); | ||
228 | (Progress::End, None) | ||
229 | } | ||
228 | }; | 230 | }; |
229 | self.report_progress("fetching", state, msg, None); | 231 | self.report_progress("fetching", state, msg, None); |
230 | } | 232 | } |
@@ -403,6 +405,8 @@ impl GlobalState { | |||
403 | } | 405 | } |
404 | } | 406 | } |
405 | 407 | ||
408 | self.fetch_workspaces_if_needed(); | ||
409 | |||
406 | let loop_duration = loop_start.elapsed(); | 410 | let loop_duration = loop_start.elapsed(); |
407 | if loop_duration > Duration::from_millis(100) { | 411 | if loop_duration > Duration::from_millis(100) { |
408 | log::warn!("overly long loop turn: {:?}", loop_duration); | 412 | log::warn!("overly long loop turn: {:?}", loop_duration); |
@@ -440,7 +444,7 @@ impl GlobalState { | |||
440 | } | 444 | } |
441 | 445 | ||
442 | RequestDispatcher { req: Some(req), global_state: self } | 446 | RequestDispatcher { req: Some(req), global_state: self } |
443 | .on_sync::<lsp_ext::ReloadWorkspace>(|s, ()| Ok(s.fetch_workspaces()))? | 447 | .on_sync::<lsp_ext::ReloadWorkspace>(|s, ()| Ok(s.fetch_workspaces_request()))? |
444 | .on_sync::<lsp_ext::JoinLines>(|s, p| handlers::handle_join_lines(s.snapshot(), p))? | 448 | .on_sync::<lsp_ext::JoinLines>(|s, p| handlers::handle_join_lines(s.snapshot(), p))? |
445 | .on_sync::<lsp_ext::OnEnter>(|s, p| handlers::handle_on_enter(s.snapshot(), p))? | 449 | .on_sync::<lsp_ext::OnEnter>(|s, p| handlers::handle_on_enter(s.snapshot(), p))? |
446 | .on_sync::<lsp_types::request::Shutdown>(|s, ()| { | 450 | .on_sync::<lsp_types::request::Shutdown>(|s, ()| { |
diff --git a/crates/rust-analyzer/src/op_queue.rs b/crates/rust-analyzer/src/op_queue.rs new file mode 100644 index 000000000..51d66f4b3 --- /dev/null +++ b/crates/rust-analyzer/src/op_queue.rs | |||
@@ -0,0 +1,25 @@ | |||
1 | //! Bookkeeping to make sure only one long-running operation is executed. | ||
2 | |||
3 | #[derive(Default)] | ||
4 | pub(crate) struct OpQueue { | ||
5 | op_scheduled: bool, | ||
6 | op_in_progress: bool, | ||
7 | } | ||
8 | |||
9 | impl OpQueue { | ||
10 | pub(crate) fn request_op(&mut self) { | ||
11 | self.op_scheduled = true; | ||
12 | } | ||
13 | pub(crate) fn should_start_op(&mut self) -> bool { | ||
14 | if !self.op_in_progress && self.op_scheduled { | ||
15 | self.op_in_progress = true; | ||
16 | self.op_scheduled = false; | ||
17 | return true; | ||
18 | } | ||
19 | false | ||
20 | } | ||
21 | pub(crate) fn op_completed(&mut self) { | ||
22 | assert!(self.op_in_progress); | ||
23 | self.op_in_progress = false; | ||
24 | } | ||
25 | } | ||
diff --git a/crates/rust-analyzer/src/reload.rs b/crates/rust-analyzer/src/reload.rs index f4e084741..accf2ef8c 100644 --- a/crates/rust-analyzer/src/reload.rs +++ b/crates/rust-analyzer/src/reload.rs | |||
@@ -19,7 +19,7 @@ use lsp_ext::StatusParams; | |||
19 | pub(crate) enum ProjectWorkspaceProgress { | 19 | pub(crate) enum ProjectWorkspaceProgress { |
20 | Begin, | 20 | Begin, |
21 | Report(String), | 21 | Report(String), |
22 | End, | 22 | End(Vec<anyhow::Result<ProjectWorkspace>>), |
23 | } | 23 | } |
24 | 24 | ||
25 | impl GlobalState { | 25 | impl GlobalState { |
@@ -30,7 +30,7 @@ impl GlobalState { | |||
30 | self.analysis_host.update_lru_capacity(self.config.lru_capacity()); | 30 | self.analysis_host.update_lru_capacity(self.config.lru_capacity()); |
31 | } | 31 | } |
32 | if self.config.linked_projects() != old_config.linked_projects() { | 32 | if self.config.linked_projects() != old_config.linked_projects() { |
33 | self.fetch_workspaces() | 33 | self.fetch_workspaces_request() |
34 | } else if self.config.flycheck() != old_config.flycheck() { | 34 | } else if self.config.flycheck() != old_config.flycheck() { |
35 | self.reload_flycheck(); | 35 | self.reload_flycheck(); |
36 | } | 36 | } |
@@ -44,7 +44,7 @@ impl GlobalState { | |||
44 | Status::Ready | Status::Invalid => (), | 44 | Status::Ready | Status::Invalid => (), |
45 | } | 45 | } |
46 | if self.config.cargo_autoreload() { | 46 | if self.config.cargo_autoreload() { |
47 | self.fetch_workspaces(); | 47 | self.fetch_workspaces_request(); |
48 | } else { | 48 | } else { |
49 | self.transition(Status::NeedsReload); | 49 | self.transition(Status::NeedsReload); |
50 | } | 50 | } |
@@ -98,8 +98,15 @@ impl GlobalState { | |||
98 | }); | 98 | }); |
99 | } | 99 | } |
100 | } | 100 | } |
101 | pub(crate) fn fetch_workspaces(&mut self) { | 101 | |
102 | pub(crate) fn fetch_workspaces_request(&mut self) { | ||
103 | self.fetch_workspaces_queue.request_op() | ||
104 | } | ||
105 | pub(crate) fn fetch_workspaces_if_needed(&mut self) { | ||
102 | log::info!("will fetch workspaces"); | 106 | log::info!("will fetch workspaces"); |
107 | if !self.fetch_workspaces_queue.should_start_op() { | ||
108 | return; | ||
109 | } | ||
103 | 110 | ||
104 | self.task_pool.handle.spawn_with_sender({ | 111 | self.task_pool.handle.spawn_with_sender({ |
105 | let linked_projects = self.config.linked_projects(); | 112 | let linked_projects = self.config.linked_projects(); |
@@ -133,12 +140,17 @@ impl GlobalState { | |||
133 | }) | 140 | }) |
134 | .collect::<Vec<_>>(); | 141 | .collect::<Vec<_>>(); |
135 | 142 | ||
136 | sender.send(Task::FetchWorkspace(ProjectWorkspaceProgress::End)).unwrap(); | ||
137 | log::info!("did fetch workspaces {:?}", workspaces); | 143 | log::info!("did fetch workspaces {:?}", workspaces); |
138 | sender.send(Task::Workspaces(workspaces)).unwrap() | 144 | sender |
145 | .send(Task::FetchWorkspace(ProjectWorkspaceProgress::End(workspaces))) | ||
146 | .unwrap(); | ||
139 | } | 147 | } |
140 | }); | 148 | }); |
141 | } | 149 | } |
150 | pub(crate) fn fetch_workspaces_completed(&mut self) { | ||
151 | self.fetch_workspaces_queue.op_completed() | ||
152 | } | ||
153 | |||
142 | pub(crate) fn switch_workspaces(&mut self, workspaces: Vec<anyhow::Result<ProjectWorkspace>>) { | 154 | pub(crate) fn switch_workspaces(&mut self, workspaces: Vec<anyhow::Result<ProjectWorkspace>>) { |
143 | let _p = profile::span("GlobalState::switch_workspaces"); | 155 | let _p = profile::span("GlobalState::switch_workspaces"); |
144 | log::info!("will switch workspaces: {:?}", workspaces); | 156 | log::info!("will switch workspaces: {:?}", workspaces); |
diff --git a/crates/rust-analyzer/src/semantic_tokens.rs b/crates/rust-analyzer/src/semantic_tokens.rs index 5c4366f16..7ce9a4ab6 100644 --- a/crates/rust-analyzer/src/semantic_tokens.rs +++ b/crates/rust-analyzer/src/semantic_tokens.rs | |||
@@ -38,17 +38,25 @@ macro_rules! define_semantic_token_types { | |||
38 | } | 38 | } |
39 | 39 | ||
40 | define_semantic_token_types![ | 40 | define_semantic_token_types![ |
41 | (ANGLE, "angle"), | ||
41 | (ATTRIBUTE, "attribute"), | 42 | (ATTRIBUTE, "attribute"), |
42 | (BOOLEAN, "boolean"), | 43 | (BOOLEAN, "boolean"), |
44 | (BRACE, "brace"), | ||
45 | (BRACKET, "bracket"), | ||
43 | (BUILTIN_TYPE, "builtinType"), | 46 | (BUILTIN_TYPE, "builtinType"), |
47 | (COMMA, "comma"), | ||
48 | (COLON, "colon"), | ||
49 | (DOT, "dot"), | ||
44 | (ESCAPE_SEQUENCE, "escapeSequence"), | 50 | (ESCAPE_SEQUENCE, "escapeSequence"), |
45 | (FORMAT_SPECIFIER, "formatSpecifier"), | 51 | (FORMAT_SPECIFIER, "formatSpecifier"), |
46 | (GENERIC, "generic"), | 52 | (GENERIC, "generic"), |
47 | (CONST_PARAMETER, "constParameter"), | 53 | (CONST_PARAMETER, "constParameter"), |
48 | (LIFETIME, "lifetime"), | 54 | (LIFETIME, "lifetime"), |
49 | (LABEL, "label"), | 55 | (LABEL, "label"), |
56 | (PARENTHESIS, "parenthesis"), | ||
50 | (PUNCTUATION, "punctuation"), | 57 | (PUNCTUATION, "punctuation"), |
51 | (SELF_KEYWORD, "selfKeyword"), | 58 | (SELF_KEYWORD, "selfKeyword"), |
59 | (SEMICOLON, "semicolon"), | ||
52 | (TYPE_ALIAS, "typeAlias"), | 60 | (TYPE_ALIAS, "typeAlias"), |
53 | (UNION, "union"), | 61 | (UNION, "union"), |
54 | (UNRESOLVED_REFERENCE, "unresolvedReference"), | 62 | (UNRESOLVED_REFERENCE, "unresolvedReference"), |
diff --git a/crates/rust-analyzer/src/to_proto.rs b/crates/rust-analyzer/src/to_proto.rs index d6bf60cde..bdddca9da 100644 --- a/crates/rust-analyzer/src/to_proto.rs +++ b/crates/rust-analyzer/src/to_proto.rs | |||
@@ -6,9 +6,9 @@ use std::{ | |||
6 | 6 | ||
7 | use ide::{ | 7 | use ide::{ |
8 | Assist, AssistKind, CallInfo, CompletionItem, CompletionItemKind, Documentation, FileId, | 8 | Assist, AssistKind, CallInfo, CompletionItem, CompletionItemKind, Documentation, FileId, |
9 | FileRange, FileSystemEdit, Fold, FoldKind, Highlight, HlMod, HlRange, HlTag, Indel, InlayHint, | 9 | FileRange, FileSystemEdit, Fold, FoldKind, Highlight, HlMod, HlPunct, HlRange, HlTag, Indel, |
10 | InlayKind, InsertTextFormat, LineIndex, Markup, NavigationTarget, ReferenceAccess, Runnable, | 10 | InlayHint, InlayKind, InsertTextFormat, LineIndex, Markup, NavigationTarget, ReferenceAccess, |
11 | Severity, SourceChange, SourceFileEdit, SymbolKind, TextEdit, TextRange, TextSize, | 11 | Runnable, Severity, SourceChange, SourceFileEdit, SymbolKind, TextEdit, TextRange, TextSize, |
12 | }; | 12 | }; |
13 | use itertools::Itertools; | 13 | use itertools::Itertools; |
14 | 14 | ||
@@ -423,7 +423,17 @@ fn semantic_token_type_and_modifiers( | |||
423 | HlTag::FormatSpecifier => semantic_tokens::FORMAT_SPECIFIER, | 423 | HlTag::FormatSpecifier => semantic_tokens::FORMAT_SPECIFIER, |
424 | HlTag::Operator => lsp_types::SemanticTokenType::OPERATOR, | 424 | HlTag::Operator => lsp_types::SemanticTokenType::OPERATOR, |
425 | HlTag::EscapeSequence => semantic_tokens::ESCAPE_SEQUENCE, | 425 | HlTag::EscapeSequence => semantic_tokens::ESCAPE_SEQUENCE, |
426 | HlTag::Punctuation => semantic_tokens::PUNCTUATION, | 426 | HlTag::Punctuation(punct) => match punct { |
427 | HlPunct::Bracket => semantic_tokens::BRACKET, | ||
428 | HlPunct::Brace => semantic_tokens::BRACE, | ||
429 | HlPunct::Parenthesis => semantic_tokens::PARENTHESIS, | ||
430 | HlPunct::Angle => semantic_tokens::ANGLE, | ||
431 | HlPunct::Comma => semantic_tokens::COMMA, | ||
432 | HlPunct::Dot => semantic_tokens::DOT, | ||
433 | HlPunct::Colon => semantic_tokens::COLON, | ||
434 | HlPunct::Semi => semantic_tokens::SEMICOLON, | ||
435 | HlPunct::Other => semantic_tokens::PUNCTUATION, | ||
436 | }, | ||
427 | }; | 437 | }; |
428 | 438 | ||
429 | for modifier in highlight.mods.iter() { | 439 | for modifier in highlight.mods.iter() { |
diff --git a/crates/stdx/src/lib.rs b/crates/stdx/src/lib.rs index 5aacdb16e..13aab1451 100644 --- a/crates/stdx/src/lib.rs +++ b/crates/stdx/src/lib.rs | |||
@@ -152,13 +152,13 @@ where | |||
152 | left | 152 | left |
153 | } | 153 | } |
154 | 154 | ||
155 | pub fn equal_range_by<T, F>(slice: &[T], mut key: F) -> (usize, usize) | 155 | pub fn equal_range_by<T, F>(slice: &[T], mut key: F) -> ops::Range<usize> |
156 | where | 156 | where |
157 | F: FnMut(&T) -> Ordering, | 157 | F: FnMut(&T) -> Ordering, |
158 | { | 158 | { |
159 | let start = partition_point(slice, |it| key(it) == Ordering::Less); | 159 | let start = partition_point(slice, |it| key(it) == Ordering::Less); |
160 | let len = partition_point(&slice[start..], |it| key(it) == Ordering::Equal); | 160 | let len = partition_point(&slice[start..], |it| key(it) == Ordering::Equal); |
161 | (start, len) | 161 | start..start + len |
162 | } | 162 | } |
163 | 163 | ||
164 | pub struct JodChild(pub process::Child); | 164 | pub struct JodChild(pub process::Child); |
diff --git a/crates/syntax/src/ast/node_ext.rs b/crates/syntax/src/ast/node_ext.rs index 2aa472fb4..27381ba80 100644 --- a/crates/syntax/src/ast/node_ext.rs +++ b/crates/syntax/src/ast/node_ext.rs | |||
@@ -133,7 +133,7 @@ impl ast::Attr { | |||
133 | first_token.and_then(|token| token.next_token()).as_ref().map(SyntaxToken::kind); | 133 | first_token.and_then(|token| token.next_token()).as_ref().map(SyntaxToken::kind); |
134 | 134 | ||
135 | match (first_token_kind, second_token_kind) { | 135 | match (first_token_kind, second_token_kind) { |
136 | (Some(SyntaxKind::POUND), Some(T![!])) => AttrKind::Inner, | 136 | (Some(T![#]), Some(T![!])) => AttrKind::Inner, |
137 | _ => AttrKind::Outer, | 137 | _ => AttrKind::Outer, |
138 | } | 138 | } |
139 | } | 139 | } |
diff --git a/crates/syntax/src/validation.rs b/crates/syntax/src/validation.rs index b3a02f4ae..bfa2dc4ba 100644 --- a/crates/syntax/src/validation.rs +++ b/crates/syntax/src/validation.rs | |||
@@ -344,9 +344,9 @@ fn validate_trait_object_ty(ty: ast::DynTraitType) -> Option<SyntaxError> { | |||
344 | 344 | ||
345 | if tbl.bounds().count() > 1 { | 345 | if tbl.bounds().count() > 1 { |
346 | let dyn_token = ty.dyn_token()?; | 346 | let dyn_token = ty.dyn_token()?; |
347 | let potential_parentheses = | 347 | let potential_parenthesis = |
348 | algo::skip_trivia_token(dyn_token.prev_token()?, Direction::Prev)?; | 348 | algo::skip_trivia_token(dyn_token.prev_token()?, Direction::Prev)?; |
349 | let kind = potential_parentheses.kind(); | 349 | let kind = potential_parenthesis.kind(); |
350 | if !matches!(kind, T!['('] | T![<] | T![=]) { | 350 | if !matches!(kind, T!['('] | T![<] | T![=]) { |
351 | return Some(SyntaxError::new("ambiguous `+` in a type", ty.syntax().text_range())); | 351 | return Some(SyntaxError::new("ambiguous `+` in a type", ty.syntax().text_range())); |
352 | } | 352 | } |
diff --git a/crates/syntax/test_data/parser/inline/ok/0039_type_arg.rast b/crates/syntax/test_data/parser/inline/ok/0039_type_arg.rast index 51e881a8e..68c0f1c66 100644 --- a/crates/syntax/test_data/parser/inline/ok/0039_type_arg.rast +++ b/crates/syntax/test_data/parser/inline/ok/0039_type_arg.rast | |||
@@ -1,5 +1,5 @@ | |||
1 | SOURCE_FILE@0..46 | 1 | SOURCE_FILE@0..59 |
2 | TYPE_ALIAS@0..45 | 2 | [email protected]8 |
3 | [email protected] "type" | 3 | [email protected] "type" |
4 | [email protected] " " | 4 | [email protected] " " |
5 | [email protected] | 5 | [email protected] |
@@ -7,12 +7,12 @@ [email protected] | |||
7 | [email protected] " " | 7 | [email protected] " " |
8 | [email protected] "=" | 8 | [email protected] "=" |
9 | [email protected] " " | 9 | [email protected] " " |
10 | PATH_TYPE@9..44 | 10 | PATH_TYPE@9..57 |
11 | PATH@9..44 | 11 | PATH@9..57 |
12 | PATH_SEGMENT@9..44 | 12 | PATH_SEGMENT@9..57 |
13 | [email protected] | 13 | [email protected] |
14 | [email protected] "B" | 14 | [email protected] "B" |
15 | GENERIC_ARG_LIST@10..44 | 15 | GENERIC_ARG_LIST@10..57 |
16 | [email protected] "<" | 16 | [email protected] "<" |
17 | [email protected] | 17 | [email protected] |
18 | [email protected] | 18 | [email protected] |
@@ -51,6 +51,16 @@ [email protected] | |||
51 | [email protected] | 51 | [email protected] |
52 | [email protected] | 52 | [email protected] |
53 | [email protected] "u64" | 53 | [email protected] "u64" |
54 | [email protected] ">" | 54 | [email protected] "," |
55 | [email protected] ";" | 55 | [email protected] " " |
56 | [email protected] "\n" | 56 | [email protected] |
57 | [email protected] | ||
58 | [email protected] "true" | ||
59 | [email protected] "," | ||
60 | [email protected] " " | ||
61 | [email protected] | ||
62 | [email protected] | ||
63 | [email protected] "false" | ||
64 | [email protected] ">" | ||
65 | [email protected] ";" | ||
66 | [email protected] "\n" | ||
diff --git a/crates/syntax/test_data/parser/inline/ok/0039_type_arg.rs b/crates/syntax/test_data/parser/inline/ok/0039_type_arg.rs index 0d07d7651..6a8721a73 100644 --- a/crates/syntax/test_data/parser/inline/ok/0039_type_arg.rs +++ b/crates/syntax/test_data/parser/inline/ok/0039_type_arg.rs | |||
@@ -1 +1 @@ | |||
type A = B<'static, i32, 1, { 2 }, Item=u64>; | type A = B<'static, i32, 1, { 2 }, Item=u64, true, false>; | ||