diff options
-rw-r--r-- | crates/hir/src/code_model.rs | 15 | ||||
-rw-r--r-- | crates/hir/src/lib.rs | 2 | ||||
-rw-r--r-- | crates/hir/src/semantics.rs | 50 | ||||
-rw-r--r-- | crates/ide/src/syntax_highlighting.rs | 117 | ||||
-rw-r--r-- | crates/ide/src/syntax_highlighting/tags.rs | 3 | ||||
-rw-r--r-- | crates/ide/src/syntax_highlighting/tests.rs | 39 | ||||
-rw-r--r-- | crates/ide/test_data/highlighting.html | 41 | ||||
-rw-r--r-- | crates/rust-analyzer/src/semantic_tokens.rs | 1 | ||||
-rw-r--r-- | crates/rust-analyzer/src/to_proto.rs | 1 |
9 files changed, 220 insertions, 49 deletions
diff --git a/crates/hir/src/code_model.rs b/crates/hir/src/code_model.rs index c442654dd..31d5276b0 100644 --- a/crates/hir/src/code_model.rs +++ b/crates/hir/src/code_model.rs | |||
@@ -670,6 +670,21 @@ impl Function { | |||
670 | db.function_data(self.id).has_self_param | 670 | db.function_data(self.id).has_self_param |
671 | } | 671 | } |
672 | 672 | ||
673 | pub fn mutability_of_self_param(self, db: &dyn HirDatabase) -> Option<Mutability> { | ||
674 | let func_data = db.function_data(self.id); | ||
675 | if !func_data.has_self_param { | ||
676 | return None; | ||
677 | } | ||
678 | |||
679 | func_data.params.first().and_then(|param| { | ||
680 | if let TypeRef::Reference(_, mutability) = param { | ||
681 | Some(*mutability) | ||
682 | } else { | ||
683 | None | ||
684 | } | ||
685 | }) | ||
686 | } | ||
687 | |||
673 | pub fn params(self, db: &dyn HirDatabase) -> Vec<TypeRef> { | 688 | pub fn params(self, db: &dyn HirDatabase) -> Vec<TypeRef> { |
674 | db.function_data(self.id).params.clone() | 689 | db.function_data(self.id).params.clone() |
675 | } | 690 | } |
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs index 8961ba8fd..fc1c1ccd3 100644 --- a/crates/hir/src/lib.rs +++ b/crates/hir/src/lib.rs | |||
@@ -38,7 +38,7 @@ pub use crate::{ | |||
38 | Static, Struct, Trait, Type, TypeAlias, TypeParam, Union, VariantDef, Visibility, | 38 | Static, Struct, Trait, Type, TypeAlias, TypeParam, Union, VariantDef, Visibility, |
39 | }, | 39 | }, |
40 | has_source::HasSource, | 40 | has_source::HasSource, |
41 | semantics::{original_range, PathResolution, Semantics, SemanticsScope}, | 41 | semantics::{original_range, PathResolution, SelfKind, Semantics, SemanticsScope}, |
42 | }; | 42 | }; |
43 | 43 | ||
44 | pub use hir_def::{ | 44 | pub use hir_def::{ |
diff --git a/crates/hir/src/semantics.rs b/crates/hir/src/semantics.rs index c693176fa..aff0e73da 100644 --- a/crates/hir/src/semantics.rs +++ b/crates/hir/src/semantics.rs | |||
@@ -6,8 +6,10 @@ use std::{cell::RefCell, fmt, iter::successors}; | |||
6 | 6 | ||
7 | use base_db::{FileId, FileRange}; | 7 | use base_db::{FileId, FileRange}; |
8 | use hir_def::{ | 8 | use hir_def::{ |
9 | lang_item::LangItemTarget, | ||
9 | resolver::{self, HasResolver, Resolver, TypeNs}, | 10 | resolver::{self, HasResolver, Resolver, TypeNs}, |
10 | AsMacroCall, FunctionId, TraitId, VariantId, | 11 | src::HasSource, |
12 | AsMacroCall, FunctionId, Lookup, TraitId, VariantId, | ||
11 | }; | 13 | }; |
12 | use hir_expand::{hygiene::Hygiene, name::AsName, ExpansionInfo}; | 14 | use hir_expand::{hygiene::Hygiene, name::AsName, ExpansionInfo}; |
13 | use hir_ty::associated_type_shorthand_candidates; | 15 | use hir_ty::associated_type_shorthand_candidates; |
@@ -15,7 +17,7 @@ use itertools::Itertools; | |||
15 | use rustc_hash::{FxHashMap, FxHashSet}; | 17 | use rustc_hash::{FxHashMap, FxHashSet}; |
16 | use syntax::{ | 18 | use syntax::{ |
17 | algo::{find_node_at_offset, skip_trivia_token}, | 19 | algo::{find_node_at_offset, skip_trivia_token}, |
18 | ast, AstNode, Direction, SyntaxNode, SyntaxToken, TextRange, TextSize, | 20 | ast, AstNode, Direction, SmolStr, SyntaxNode, SyntaxToken, TextRange, TextSize, |
19 | }; | 21 | }; |
20 | 22 | ||
21 | use crate::{ | 23 | use crate::{ |
@@ -79,6 +81,13 @@ impl PathResolution { | |||
79 | } | 81 | } |
80 | } | 82 | } |
81 | 83 | ||
84 | pub enum SelfKind { | ||
85 | Shared, | ||
86 | Mutable, | ||
87 | Consuming, | ||
88 | Copied, | ||
89 | } | ||
90 | |||
82 | /// Primary API to get semantic information, like types, from syntax trees. | 91 | /// Primary API to get semantic information, like types, from syntax trees. |
83 | pub struct Semantics<'db, DB> { | 92 | pub struct Semantics<'db, DB> { |
84 | pub db: &'db DB, | 93 | pub db: &'db DB, |
@@ -188,6 +197,10 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> { | |||
188 | self.imp.type_of_self(param) | 197 | self.imp.type_of_self(param) |
189 | } | 198 | } |
190 | 199 | ||
200 | pub fn method_reciever_kind(&self, call: &ast::MethodCallExpr) -> Option<SelfKind> { | ||
201 | self.imp.method_receiver_kind(call) | ||
202 | } | ||
203 | |||
191 | pub fn resolve_method_call(&self, call: &ast::MethodCallExpr) -> Option<Function> { | 204 | pub fn resolve_method_call(&self, call: &ast::MethodCallExpr) -> Option<Function> { |
192 | self.imp.resolve_method_call(call).map(Function::from) | 205 | self.imp.resolve_method_call(call).map(Function::from) |
193 | } | 206 | } |
@@ -267,7 +280,7 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> { | |||
267 | self.imp.assert_contains_node(node) | 280 | self.imp.assert_contains_node(node) |
268 | } | 281 | } |
269 | 282 | ||
270 | pub fn is_unsafe_method_call(&self, method_call_expr: ast::MethodCallExpr) -> bool { | 283 | pub fn is_unsafe_method_call(&self, method_call_expr: &ast::MethodCallExpr) -> bool { |
271 | self.imp.is_unsafe_method_call(method_call_expr) | 284 | self.imp.is_unsafe_method_call(method_call_expr) |
272 | } | 285 | } |
273 | 286 | ||
@@ -410,6 +423,35 @@ impl<'db> SemanticsImpl<'db> { | |||
410 | self.analyze(param.syntax()).type_of_self(self.db, ¶m) | 423 | self.analyze(param.syntax()).type_of_self(self.db, ¶m) |
411 | } | 424 | } |
412 | 425 | ||
426 | fn method_receiver_kind(&self, call: &ast::MethodCallExpr) -> Option<SelfKind> { | ||
427 | self.resolve_method_call(call).and_then(|func| { | ||
428 | let lookup = func.lookup(self.db.upcast()); | ||
429 | let src = lookup.source(self.db.upcast()); | ||
430 | let param_list = src.value.param_list()?; | ||
431 | let self_param = param_list.self_param()?; | ||
432 | if self_param.amp_token().is_some() { | ||
433 | return Some(if self_param.mut_token().is_some() { | ||
434 | SelfKind::Mutable | ||
435 | } else { | ||
436 | SelfKind::Shared | ||
437 | }); | ||
438 | } | ||
439 | |||
440 | let ty = self.type_of_expr(&call.expr()?)?; | ||
441 | let krate = Function::from(func).krate(self.db)?; | ||
442 | let lang_item = self.db.lang_item(krate.id, SmolStr::new("copy")); | ||
443 | let copy_trait = match lang_item? { | ||
444 | LangItemTarget::TraitId(copy_trait) => Trait::from(copy_trait), | ||
445 | _ => return None, | ||
446 | }; | ||
447 | Some(if ty.impls_trait(self.db, copy_trait, &[]) { | ||
448 | SelfKind::Copied | ||
449 | } else { | ||
450 | SelfKind::Consuming | ||
451 | }) | ||
452 | }) | ||
453 | } | ||
454 | |||
413 | fn resolve_method_call(&self, call: &ast::MethodCallExpr) -> Option<FunctionId> { | 455 | fn resolve_method_call(&self, call: &ast::MethodCallExpr) -> Option<FunctionId> { |
414 | self.analyze(call.syntax()).resolve_method_call(self.db, call) | 456 | self.analyze(call.syntax()).resolve_method_call(self.db, call) |
415 | } | 457 | } |
@@ -571,7 +613,7 @@ impl<'db> SemanticsImpl<'db> { | |||
571 | InFile::new(file_id, node) | 613 | InFile::new(file_id, node) |
572 | } | 614 | } |
573 | 615 | ||
574 | pub fn is_unsafe_method_call(&self, method_call_expr: ast::MethodCallExpr) -> bool { | 616 | pub fn is_unsafe_method_call(&self, method_call_expr: &ast::MethodCallExpr) -> bool { |
575 | method_call_expr | 617 | method_call_expr |
576 | .expr() | 618 | .expr() |
577 | .and_then(|expr| { | 619 | .and_then(|expr| { |
diff --git a/crates/ide/src/syntax_highlighting.rs b/crates/ide/src/syntax_highlighting.rs index 5d7c7e8d0..9827c68af 100644 --- a/crates/ide/src/syntax_highlighting.rs +++ b/crates/ide/src/syntax_highlighting.rs | |||
@@ -4,7 +4,7 @@ mod injection; | |||
4 | #[cfg(test)] | 4 | #[cfg(test)] |
5 | mod tests; | 5 | mod tests; |
6 | 6 | ||
7 | use hir::{Name, Semantics, VariantDef}; | 7 | use hir::{Mutability, Name, SelfKind, Semantics, VariantDef}; |
8 | use ide_db::{ | 8 | use ide_db::{ |
9 | defs::{classify_name, classify_name_ref, Definition, NameClass, NameRefClass}, | 9 | defs::{classify_name, classify_name_ref, Definition, NameClass, NameRefClass}, |
10 | RootDatabase, | 10 | RootDatabase, |
@@ -519,27 +519,29 @@ fn highlight_element( | |||
519 | } | 519 | } |
520 | NAME_REF => { | 520 | NAME_REF => { |
521 | let name_ref = element.into_node().and_then(ast::NameRef::cast).unwrap(); | 521 | let name_ref = element.into_node().and_then(ast::NameRef::cast).unwrap(); |
522 | let possibly_unsafe = is_possibly_unsafe(&name_ref); | 522 | highlight_func_by_name_ref(sema, &name_ref).unwrap_or_else(|| { |
523 | match classify_name_ref(sema, &name_ref) { | 523 | let possibly_unsafe = is_possibly_unsafe(&name_ref); |
524 | Some(name_kind) => match name_kind { | 524 | match classify_name_ref(sema, &name_ref) { |
525 | NameRefClass::ExternCrate(_) => HighlightTag::Module.into(), | 525 | Some(name_kind) => match name_kind { |
526 | NameRefClass::Definition(def) => { | 526 | NameRefClass::ExternCrate(_) => HighlightTag::Module.into(), |
527 | if let Definition::Local(local) = &def { | 527 | NameRefClass::Definition(def) => { |
528 | if let Some(name) = local.name(db) { | 528 | if let Definition::Local(local) = &def { |
529 | let shadow_count = | 529 | if let Some(name) = local.name(db) { |
530 | bindings_shadow_count.entry(name.clone()).or_default(); | 530 | let shadow_count = |
531 | binding_hash = Some(calc_binding_hash(&name, *shadow_count)) | 531 | bindings_shadow_count.entry(name.clone()).or_default(); |
532 | } | 532 | binding_hash = Some(calc_binding_hash(&name, *shadow_count)) |
533 | }; | 533 | } |
534 | highlight_name(sema, db, def, Some(name_ref), possibly_unsafe) | 534 | }; |
535 | highlight_name(sema, db, def, Some(name_ref), possibly_unsafe) | ||
536 | } | ||
537 | NameRefClass::FieldShorthand { .. } => HighlightTag::Field.into(), | ||
538 | }, | ||
539 | None if syntactic_name_ref_highlighting => { | ||
540 | highlight_name_ref_by_syntax(name_ref, sema) | ||
535 | } | 541 | } |
536 | NameRefClass::FieldShorthand { .. } => HighlightTag::Field.into(), | 542 | None => HighlightTag::UnresolvedReference.into(), |
537 | }, | ||
538 | None if syntactic_name_ref_highlighting => { | ||
539 | highlight_name_ref_by_syntax(name_ref, sema) | ||
540 | } | 543 | } |
541 | None => HighlightTag::UnresolvedReference.into(), | 544 | }) |
542 | } | ||
543 | } | 545 | } |
544 | 546 | ||
545 | // Simple token-based highlighting | 547 | // Simple token-based highlighting |
@@ -700,6 +702,35 @@ fn is_child_of_impl(element: &SyntaxElement) -> bool { | |||
700 | } | 702 | } |
701 | } | 703 | } |
702 | 704 | ||
705 | fn highlight_func_by_name_ref( | ||
706 | sema: &Semantics<RootDatabase>, | ||
707 | name_ref: &ast::NameRef, | ||
708 | ) -> Option<Highlight> { | ||
709 | let parent = name_ref.syntax().parent()?; | ||
710 | let method_call = ast::MethodCallExpr::cast(parent)?; | ||
711 | highlight_method_call(sema, &method_call) | ||
712 | } | ||
713 | |||
714 | fn highlight_method_call( | ||
715 | sema: &Semantics<RootDatabase>, | ||
716 | method_call: &ast::MethodCallExpr, | ||
717 | ) -> Option<Highlight> { | ||
718 | let func = sema.resolve_method_call(&method_call)?; | ||
719 | let mut h = HighlightTag::Function.into(); | ||
720 | if func.is_unsafe(sema.db) || sema.is_unsafe_method_call(&method_call) { | ||
721 | h |= HighlightModifier::Unsafe; | ||
722 | } | ||
723 | |||
724 | sema.method_reciever_kind(&method_call) | ||
725 | .map(|self_kind| match self_kind { | ||
726 | SelfKind::Shared => h, | ||
727 | SelfKind::Mutable => h | HighlightModifier::Mutable, | ||
728 | SelfKind::Consuming => h | HighlightModifier::Consuming, | ||
729 | SelfKind::Copied => h, | ||
730 | }) | ||
731 | .or_else(|| Some(h)) | ||
732 | } | ||
733 | |||
703 | fn highlight_name( | 734 | fn highlight_name( |
704 | sema: &Semantics<RootDatabase>, | 735 | sema: &Semantics<RootDatabase>, |
705 | db: &RootDatabase, | 736 | db: &RootDatabase, |
@@ -722,20 +753,26 @@ fn highlight_name( | |||
722 | Definition::ModuleDef(def) => match def { | 753 | Definition::ModuleDef(def) => match def { |
723 | hir::ModuleDef::Module(_) => HighlightTag::Module, | 754 | hir::ModuleDef::Module(_) => HighlightTag::Module, |
724 | hir::ModuleDef::Function(func) => { | 755 | hir::ModuleDef::Function(func) => { |
725 | let mut h = HighlightTag::Function.into(); | 756 | return name_ref |
726 | if func.is_unsafe(db) { | 757 | .and_then(|name_ref| highlight_func_by_name_ref(sema, &name_ref)) |
727 | h |= HighlightModifier::Unsafe; | 758 | .unwrap_or_else(|| { |
728 | } else { | 759 | let mut h = HighlightTag::Function.into(); |
729 | let is_unsafe = name_ref | 760 | if func.is_unsafe(db) { |
730 | .and_then(|name_ref| name_ref.syntax().parent()) | 761 | h |= HighlightModifier::Unsafe; |
731 | .and_then(ast::MethodCallExpr::cast) | 762 | } |
732 | .map(|method_call_expr| sema.is_unsafe_method_call(method_call_expr)) | 763 | |
733 | .unwrap_or(false); | 764 | return if func.has_self_param(db) { |
734 | if is_unsafe { | 765 | match func.mutability_of_self_param(db) { |
735 | h |= HighlightModifier::Unsafe; | 766 | Some(mutability) => match mutability { |
736 | } | 767 | Mutability::Mut => h | HighlightModifier::Mutable, |
737 | } | 768 | Mutability::Shared => h, |
738 | return h; | 769 | }, |
770 | None => h, | ||
771 | } | ||
772 | } else { | ||
773 | h | ||
774 | }; | ||
775 | }); | ||
739 | } | 776 | } |
740 | hir::ModuleDef::Adt(hir::Adt::Struct(_)) => HighlightTag::Struct, | 777 | hir::ModuleDef::Adt(hir::Adt::Struct(_)) => HighlightTag::Struct, |
741 | hir::ModuleDef::Adt(hir::Adt::Enum(_)) => HighlightTag::Enum, | 778 | hir::ModuleDef::Adt(hir::Adt::Enum(_)) => HighlightTag::Enum, |
@@ -807,15 +844,9 @@ fn highlight_name_ref_by_syntax(name: ast::NameRef, sema: &Semantics<RootDatabas | |||
807 | 844 | ||
808 | match parent.kind() { | 845 | match parent.kind() { |
809 | METHOD_CALL_EXPR => { | 846 | METHOD_CALL_EXPR => { |
810 | let mut h = Highlight::new(HighlightTag::Function); | 847 | return ast::MethodCallExpr::cast(parent) |
811 | let is_unsafe = ast::MethodCallExpr::cast(parent) | 848 | .and_then(|method_call| highlight_method_call(sema, &method_call)) |
812 | .map(|method_call_expr| sema.is_unsafe_method_call(method_call_expr)) | 849 | .unwrap_or_else(|| HighlightTag::Function.into()); |
813 | .unwrap_or(false); | ||
814 | if is_unsafe { | ||
815 | h |= HighlightModifier::Unsafe; | ||
816 | } | ||
817 | |||
818 | h | ||
819 | } | 850 | } |
820 | FIELD_EXPR => { | 851 | FIELD_EXPR => { |
821 | let h = HighlightTag::Field; | 852 | let h = HighlightTag::Field; |
diff --git a/crates/ide/src/syntax_highlighting/tags.rs b/crates/ide/src/syntax_highlighting/tags.rs index 49ec94bdc..c1b817f06 100644 --- a/crates/ide/src/syntax_highlighting/tags.rs +++ b/crates/ide/src/syntax_highlighting/tags.rs | |||
@@ -62,6 +62,7 @@ pub enum HighlightModifier { | |||
62 | Documentation, | 62 | Documentation, |
63 | Injected, | 63 | Injected, |
64 | Mutable, | 64 | Mutable, |
65 | Consuming, | ||
65 | Unsafe, | 66 | Unsafe, |
66 | } | 67 | } |
67 | 68 | ||
@@ -119,6 +120,7 @@ impl HighlightModifier { | |||
119 | HighlightModifier::Documentation, | 120 | HighlightModifier::Documentation, |
120 | HighlightModifier::Injected, | 121 | HighlightModifier::Injected, |
121 | HighlightModifier::Mutable, | 122 | HighlightModifier::Mutable, |
123 | HighlightModifier::Consuming, | ||
122 | HighlightModifier::Unsafe, | 124 | HighlightModifier::Unsafe, |
123 | ]; | 125 | ]; |
124 | 126 | ||
@@ -130,6 +132,7 @@ impl HighlightModifier { | |||
130 | HighlightModifier::Documentation => "documentation", | 132 | HighlightModifier::Documentation => "documentation", |
131 | HighlightModifier::Injected => "injected", | 133 | HighlightModifier::Injected => "injected", |
132 | HighlightModifier::Mutable => "mutable", | 134 | HighlightModifier::Mutable => "mutable", |
135 | HighlightModifier::Consuming => "consuming", | ||
133 | HighlightModifier::Unsafe => "unsafe", | 136 | HighlightModifier::Unsafe => "unsafe", |
134 | } | 137 | } |
135 | } | 138 | } |
diff --git a/crates/ide/src/syntax_highlighting/tests.rs b/crates/ide/src/syntax_highlighting/tests.rs index 94f37d773..ccb76f552 100644 --- a/crates/ide/src/syntax_highlighting/tests.rs +++ b/crates/ide/src/syntax_highlighting/tests.rs | |||
@@ -12,6 +12,12 @@ fn test_highlighting() { | |||
12 | use inner::{self as inner_mod}; | 12 | use inner::{self as inner_mod}; |
13 | mod inner {} | 13 | mod inner {} |
14 | 14 | ||
15 | // Needed for function consuming vs normal | ||
16 | pub mod marker { | ||
17 | #[lang = "copy"] | ||
18 | pub trait Copy {} | ||
19 | } | ||
20 | |||
15 | #[derive(Clone, Debug)] | 21 | #[derive(Clone, Debug)] |
16 | struct Foo { | 22 | struct Foo { |
17 | pub x: i32, | 23 | pub x: i32, |
@@ -36,6 +42,29 @@ impl Foo { | |||
36 | fn qux(&mut self) { | 42 | fn qux(&mut self) { |
37 | self.x = 0; | 43 | self.x = 0; |
38 | } | 44 | } |
45 | |||
46 | fn quop(&self) -> i32 { | ||
47 | self.x | ||
48 | } | ||
49 | } | ||
50 | |||
51 | #[derive(Copy, Clone)] | ||
52 | struct FooCopy { | ||
53 | x: u32, | ||
54 | } | ||
55 | |||
56 | impl FooCopy { | ||
57 | fn baz(self) -> u32 { | ||
58 | self.x | ||
59 | } | ||
60 | |||
61 | fn qux(&mut self) { | ||
62 | self.x = 0; | ||
63 | } | ||
64 | |||
65 | fn quop(&self) -> u32 { | ||
66 | self.x | ||
67 | } | ||
39 | } | 68 | } |
40 | 69 | ||
41 | static mut STATIC_MUT: i32 = 0; | 70 | static mut STATIC_MUT: i32 = 0; |
@@ -87,6 +116,16 @@ fn main() { | |||
87 | let Foo { x: z, y } = Foo { x: z, y }; | 116 | let Foo { x: z, y } = Foo { x: z, y }; |
88 | 117 | ||
89 | y; | 118 | y; |
119 | |||
120 | let mut foo = Foo { x, y: x }; | ||
121 | foo.quop(); | ||
122 | foo.qux(); | ||
123 | foo.baz(); | ||
124 | |||
125 | let mut copy = FooCopy { x }; | ||
126 | copy.quop(); | ||
127 | copy.qux(); | ||
128 | copy.baz(); | ||
90 | } | 129 | } |
91 | 130 | ||
92 | enum Option<T> { | 131 | enum Option<T> { |
diff --git a/crates/ide/test_data/highlighting.html b/crates/ide/test_data/highlighting.html index 8e0160eee..a6b79589b 100644 --- a/crates/ide/test_data/highlighting.html +++ b/crates/ide/test_data/highlighting.html | |||
@@ -38,6 +38,12 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd | |||
38 | <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> | 38 | <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 | <span class="keyword">mod</span> <span class="module declaration">inner</span> <span class="punctuation">{</span><span class="punctuation">}</span> | 39 | <span class="keyword">mod</span> <span class="module declaration">inner</span> <span class="punctuation">{</span><span class="punctuation">}</span> |
40 | 40 | ||
41 | <span class="comment">// Needed for function consuming vs normal</span> | ||
42 | <span class="keyword">pub</span> <span class="keyword">mod</span> <span class="module declaration">marker</span> <span class="punctuation">{</span> | ||
43 | <span class="attribute">#</span><span class="attribute">[</span><span class="function attribute">lang</span><span class="attribute"> </span><span class="operator">=</span><span class="attribute"> </span><span class="string_literal">"copy"</span><span class="attribute">]</span> | ||
44 | <span class="keyword">pub</span> <span class="keyword">trait</span> <span class="trait declaration">Copy</span> <span class="punctuation">{</span><span class="punctuation">}</span> | ||
45 | <span class="punctuation">}</span> | ||
46 | |||
41 | <span class="attribute">#</span><span class="attribute">[</span><span class="function attribute">derive</span><span class="punctuation">(</span><span class="attribute">Clone</span><span class="punctuation">,</span><span class="attribute"> Debug</span><span class="punctuation">)</span><span class="attribute">]</span> | 47 | <span class="attribute">#</span><span class="attribute">[</span><span class="function attribute">derive</span><span class="punctuation">(</span><span class="attribute">Clone</span><span class="punctuation">,</span><span class="attribute"> Debug</span><span class="punctuation">)</span><span class="attribute">]</span> |
42 | <span class="keyword">struct</span> <span class="struct declaration">Foo</span> <span class="punctuation">{</span> | 48 | <span class="keyword">struct</span> <span class="struct declaration">Foo</span> <span class="punctuation">{</span> |
43 | <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> | 49 | <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> |
@@ -59,9 +65,32 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd | |||
59 | <span class="self_keyword">self</span><span class="punctuation">.</span><span class="field">x</span> | 65 | <span class="self_keyword">self</span><span class="punctuation">.</span><span class="field">x</span> |
60 | <span class="punctuation">}</span> | 66 | <span class="punctuation">}</span> |
61 | 67 | ||
62 | <span class="keyword">fn</span> <span class="function declaration">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> | 68 | <span class="keyword">fn</span> <span class="function declaration mutable">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> |
63 | <span class="self_keyword mutable">self</span><span class="punctuation">.</span><span class="field">x</span> <span class="operator">=</span> <span class="numeric_literal">0</span><span class="punctuation">;</span> | 69 | <span class="self_keyword mutable">self</span><span class="punctuation">.</span><span class="field">x</span> <span class="operator">=</span> <span class="numeric_literal">0</span><span class="punctuation">;</span> |
64 | <span class="punctuation">}</span> | 70 | <span class="punctuation">}</span> |
71 | |||
72 | <span class="keyword">fn</span> <span class="function declaration">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> | ||
73 | <span class="self_keyword">self</span><span class="punctuation">.</span><span class="field">x</span> | ||
74 | <span class="punctuation">}</span> | ||
75 | <span class="punctuation">}</span> | ||
76 | |||
77 | <span class="attribute">#</span><span class="attribute">[</span><span class="function attribute">derive</span><span class="punctuation">(</span><span class="attribute">Copy</span><span class="punctuation">,</span><span class="attribute"> Clone</span><span class="punctuation">)</span><span class="attribute">]</span> | ||
78 | <span class="keyword">struct</span> <span class="struct declaration">FooCopy</span> <span class="punctuation">{</span> | ||
79 | <span class="field declaration">x</span><span class="punctuation">:</span> <span class="builtin_type">u32</span><span class="punctuation">,</span> | ||
80 | <span class="punctuation">}</span> | ||
81 | |||
82 | <span class="keyword">impl</span> <span class="struct">FooCopy</span> <span class="punctuation">{</span> | ||
83 | <span class="keyword">fn</span> <span class="function declaration">baz</span><span class="punctuation">(</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> | ||
84 | <span class="self_keyword">self</span><span class="punctuation">.</span><span class="field">x</span> | ||
85 | <span class="punctuation">}</span> | ||
86 | |||
87 | <span class="keyword">fn</span> <span class="function declaration mutable">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> | ||
88 | <span class="self_keyword mutable">self</span><span class="punctuation">.</span><span class="field">x</span> <span class="operator">=</span> <span class="numeric_literal">0</span><span class="punctuation">;</span> | ||
89 | <span class="punctuation">}</span> | ||
90 | |||
91 | <span class="keyword">fn</span> <span class="function declaration">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> | ||
92 | <span class="self_keyword">self</span><span class="punctuation">.</span><span class="field">x</span> | ||
93 | <span class="punctuation">}</span> | ||
65 | <span class="punctuation">}</span> | 94 | <span class="punctuation">}</span> |
66 | 95 | ||
67 | <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> | 96 | <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> |
@@ -113,6 +142,16 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd | |||
113 | <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> | 142 | <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> |
114 | 143 | ||
115 | <span class="variable">y</span><span class="punctuation">;</span> | 144 | <span class="variable">y</span><span class="punctuation">;</span> |
145 | |||
146 | <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> | ||
147 | <span class="variable mutable">foo</span><span class="punctuation">.</span><span class="function">quop</span><span class="punctuation">(</span><span class="punctuation">)</span><span class="punctuation">;</span> | ||
148 | <span class="variable mutable">foo</span><span class="punctuation">.</span><span class="function mutable">qux</span><span class="punctuation">(</span><span class="punctuation">)</span><span class="punctuation">;</span> | ||
149 | <span class="variable mutable">foo</span><span class="punctuation">.</span><span class="function consuming">baz</span><span class="punctuation">(</span><span class="punctuation">)</span><span class="punctuation">;</span> | ||
150 | |||
151 | <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> | ||
152 | <span class="variable mutable">copy</span><span class="punctuation">.</span><span class="function">quop</span><span class="punctuation">(</span><span class="punctuation">)</span><span class="punctuation">;</span> | ||
153 | <span class="variable mutable">copy</span><span class="punctuation">.</span><span class="function mutable">qux</span><span class="punctuation">(</span><span class="punctuation">)</span><span class="punctuation">;</span> | ||
154 | <span class="variable mutable">copy</span><span class="punctuation">.</span><span class="function">baz</span><span class="punctuation">(</span><span class="punctuation">)</span><span class="punctuation">;</span> | ||
116 | <span class="punctuation">}</span> | 155 | <span class="punctuation">}</span> |
117 | 156 | ||
118 | <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> | 157 | <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> |
diff --git a/crates/rust-analyzer/src/semantic_tokens.rs b/crates/rust-analyzer/src/semantic_tokens.rs index afc38fb4e..9db7b8af5 100644 --- a/crates/rust-analyzer/src/semantic_tokens.rs +++ b/crates/rust-analyzer/src/semantic_tokens.rs | |||
@@ -75,6 +75,7 @@ define_semantic_token_modifiers![ | |||
75 | (CONTROL_FLOW, "controlFlow"), | 75 | (CONTROL_FLOW, "controlFlow"), |
76 | (INJECTED, "injected"), | 76 | (INJECTED, "injected"), |
77 | (MUTABLE, "mutable"), | 77 | (MUTABLE, "mutable"), |
78 | (CONSUMING, "consuming"), | ||
78 | (UNSAFE, "unsafe"), | 79 | (UNSAFE, "unsafe"), |
79 | (ATTRIBUTE_MODIFIER, "attribute"), | 80 | (ATTRIBUTE_MODIFIER, "attribute"), |
80 | ]; | 81 | ]; |
diff --git a/crates/rust-analyzer/src/to_proto.rs b/crates/rust-analyzer/src/to_proto.rs index 643dcb4fc..a5191c16e 100644 --- a/crates/rust-analyzer/src/to_proto.rs +++ b/crates/rust-analyzer/src/to_proto.rs | |||
@@ -400,6 +400,7 @@ fn semantic_token_type_and_modifiers( | |||
400 | HighlightModifier::Injected => semantic_tokens::INJECTED, | 400 | HighlightModifier::Injected => semantic_tokens::INJECTED, |
401 | HighlightModifier::ControlFlow => semantic_tokens::CONTROL_FLOW, | 401 | HighlightModifier::ControlFlow => semantic_tokens::CONTROL_FLOW, |
402 | HighlightModifier::Mutable => semantic_tokens::MUTABLE, | 402 | HighlightModifier::Mutable => semantic_tokens::MUTABLE, |
403 | HighlightModifier::Consuming => semantic_tokens::CONSUMING, | ||
403 | HighlightModifier::Unsafe => semantic_tokens::UNSAFE, | 404 | HighlightModifier::Unsafe => semantic_tokens::UNSAFE, |
404 | }; | 405 | }; |
405 | mods |= modifier; | 406 | mods |= modifier; |