aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crates/hir/src/lib.rs33
-rw-r--r--crates/ide/src/inlay_hints.rs2
-rw-r--r--crates/ide/src/runnables.rs2
-rw-r--r--crates/ide/src/syntax_highlighting.rs3
-rw-r--r--crates/ide/src/syntax_highlighting/highlight.rs84
-rw-r--r--crates/ide/src/syntax_highlighting/tags.rs4
-rw-r--r--crates/ide/src/syntax_highlighting/test_data/highlighting.html18
-rw-r--r--crates/ide/src/syntax_highlighting/tests.rs38
-rw-r--r--crates/rust-analyzer/src/semantic_tokens.rs1
-rw-r--r--crates/rust-analyzer/src/to_proto.rs1
10 files changed, 124 insertions, 62 deletions
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs
index ca9a7f7fa..cdf65a044 100644
--- a/crates/hir/src/lib.rs
+++ b/crates/hir/src/lib.rs
@@ -551,10 +551,6 @@ impl Struct {
551 Module { id: self.id.lookup(db.upcast()).container } 551 Module { id: self.id.lookup(db.upcast()).container }
552 } 552 }
553 553
554 pub fn krate(self, db: &dyn HirDatabase) -> Option<Crate> {
555 Some(self.module(db).krate())
556 }
557
558 pub fn name(self, db: &dyn HirDatabase) -> Name { 554 pub fn name(self, db: &dyn HirDatabase) -> Name {
559 db.struct_data(self.id).name.clone() 555 db.struct_data(self.id).name.clone()
560 } 556 }
@@ -639,10 +635,6 @@ impl Enum {
639 Module { id: self.id.lookup(db.upcast()).container } 635 Module { id: self.id.lookup(db.upcast()).container }
640 } 636 }
641 637
642 pub fn krate(self, db: &dyn HirDatabase) -> Option<Crate> {
643 Some(self.module(db).krate())
644 }
645
646 pub fn name(self, db: &dyn HirDatabase) -> Name { 638 pub fn name(self, db: &dyn HirDatabase) -> Name {
647 db.enum_data(self.id).name.clone() 639 db.enum_data(self.id).name.clone()
648 } 640 }
@@ -672,6 +664,7 @@ impl Variant {
672 pub fn module(self, db: &dyn HirDatabase) -> Module { 664 pub fn module(self, db: &dyn HirDatabase) -> Module {
673 self.parent.module(db) 665 self.parent.module(db)
674 } 666 }
667
675 pub fn parent_enum(self, _db: &dyn HirDatabase) -> Enum { 668 pub fn parent_enum(self, _db: &dyn HirDatabase) -> Enum {
676 self.parent 669 self.parent
677 } 670 }
@@ -728,10 +721,6 @@ impl Adt {
728 } 721 }
729 } 722 }
730 723
731 pub fn krate(self, db: &dyn HirDatabase) -> Crate {
732 self.module(db).krate()
733 }
734
735 pub fn name(self, db: &dyn HirDatabase) -> Name { 724 pub fn name(self, db: &dyn HirDatabase) -> Name {
736 match self { 725 match self {
737 Adt::Struct(s) => s.name(db), 726 Adt::Struct(s) => s.name(db),
@@ -820,10 +809,6 @@ impl Function {
820 self.id.lookup(db.upcast()).module(db.upcast()).into() 809 self.id.lookup(db.upcast()).module(db.upcast()).into()
821 } 810 }
822 811
823 pub fn krate(self, db: &dyn HirDatabase) -> Option<Crate> {
824 Some(self.module(db).krate())
825 }
826
827 pub fn name(self, db: &dyn HirDatabase) -> Name { 812 pub fn name(self, db: &dyn HirDatabase) -> Name {
828 db.function_data(self.id).name.clone() 813 db.function_data(self.id).name.clone()
829 } 814 }
@@ -1013,10 +998,6 @@ impl Const {
1013 Module { id: self.id.lookup(db.upcast()).module(db.upcast()) } 998 Module { id: self.id.lookup(db.upcast()).module(db.upcast()) }
1014 } 999 }
1015 1000
1016 pub fn krate(self, db: &dyn HirDatabase) -> Option<Crate> {
1017 Some(self.module(db).krate())
1018 }
1019
1020 pub fn name(self, db: &dyn HirDatabase) -> Option<Name> { 1001 pub fn name(self, db: &dyn HirDatabase) -> Option<Name> {
1021 db.const_data(self.id).name.clone() 1002 db.const_data(self.id).name.clone()
1022 } 1003 }
@@ -1044,10 +1025,6 @@ impl Static {
1044 Module { id: self.id.lookup(db.upcast()).module(db.upcast()) } 1025 Module { id: self.id.lookup(db.upcast()).module(db.upcast()) }
1045 } 1026 }
1046 1027
1047 pub fn krate(self, db: &dyn HirDatabase) -> Option<Crate> {
1048 Some(self.module(db).krate())
1049 }
1050
1051 pub fn name(self, db: &dyn HirDatabase) -> Option<Name> { 1028 pub fn name(self, db: &dyn HirDatabase) -> Option<Name> {
1052 db.static_data(self.id).name.clone() 1029 db.static_data(self.id).name.clone()
1053 } 1030 }
@@ -1111,10 +1088,6 @@ impl TypeAlias {
1111 Module { id: self.id.lookup(db.upcast()).module(db.upcast()) } 1088 Module { id: self.id.lookup(db.upcast()).module(db.upcast()) }
1112 } 1089 }
1113 1090
1114 pub fn krate(self, db: &dyn HirDatabase) -> Crate {
1115 self.module(db).krate()
1116 }
1117
1118 pub fn type_ref(self, db: &dyn HirDatabase) -> Option<TypeRef> { 1091 pub fn type_ref(self, db: &dyn HirDatabase) -> Option<TypeRef> {
1119 db.type_alias_data(self.id).type_ref.as_deref().cloned() 1092 db.type_alias_data(self.id).type_ref.as_deref().cloned()
1120 } 1093 }
@@ -1666,10 +1639,6 @@ impl Impl {
1666 self.id.lookup(db.upcast()).container.into() 1639 self.id.lookup(db.upcast()).container.into()
1667 } 1640 }
1668 1641
1669 pub fn krate(self, db: &dyn HirDatabase) -> Crate {
1670 Crate { id: self.module(db).id.krate() }
1671 }
1672
1673 pub fn is_builtin_derive(self, db: &dyn HirDatabase) -> Option<InFile<ast::Attr>> { 1642 pub fn is_builtin_derive(self, db: &dyn HirDatabase) -> Option<InFile<ast::Attr>> {
1674 let src = self.source(db)?; 1643 let src = self.source(db)?;
1675 let item = src.file_id.is_builtin_derive(db.upcast())?; 1644 let item = src.file_id.is_builtin_derive(db.upcast())?;
diff --git a/crates/ide/src/inlay_hints.rs b/crates/ide/src/inlay_hints.rs
index 8f490e922..85f887737 100644
--- a/crates/ide/src/inlay_hints.rs
+++ b/crates/ide/src/inlay_hints.rs
@@ -219,7 +219,7 @@ fn hint_iterator(
219) -> Option<SmolStr> { 219) -> Option<SmolStr> {
220 let db = sema.db; 220 let db = sema.db;
221 let strukt = ty.strip_references().as_adt()?; 221 let strukt = ty.strip_references().as_adt()?;
222 let krate = strukt.krate(db); 222 let krate = strukt.module(db).krate();
223 if krate != famous_defs.core()? { 223 if krate != famous_defs.core()? {
224 return None; 224 return None;
225 } 225 }
diff --git a/crates/ide/src/runnables.rs b/crates/ide/src/runnables.rs
index f76715d84..ce1c76f37 100644
--- a/crates/ide/src/runnables.rs
+++ b/crates/ide/src/runnables.rs
@@ -227,7 +227,7 @@ pub(crate) fn runnable_fn(sema: &Semantics<RootDatabase>, def: hir::Function) ->
227 let func = def.source(sema.db)?; 227 let func = def.source(sema.db)?;
228 let name_string = def.name(sema.db).to_string(); 228 let name_string = def.name(sema.db).to_string();
229 229
230 let root = def.krate(sema.db)?.root_module(sema.db); 230 let root = def.module(sema.db).krate().root_module(sema.db);
231 231
232 let kind = if name_string == "main" && def.module(sema.db) == root { 232 let kind = if name_string == "main" && def.module(sema.db) == root {
233 RunnableKind::Bin 233 RunnableKind::Bin
diff --git a/crates/ide/src/syntax_highlighting.rs b/crates/ide/src/syntax_highlighting.rs
index 9df8d21af..cf1a8bad7 100644
--- a/crates/ide/src/syntax_highlighting.rs
+++ b/crates/ide/src/syntax_highlighting.rs
@@ -80,6 +80,7 @@ pub(crate) fn highlight(
80 &mut hl, 80 &mut hl,
81 &sema, 81 &sema,
82 InFile::new(file_id.into(), &root), 82 InFile::new(file_id.into(), &root),
83 sema.scope(&root).krate(),
83 range_to_highlight, 84 range_to_highlight,
84 syntactic_name_ref_highlighting, 85 syntactic_name_ref_highlighting,
85 ); 86 );
@@ -90,6 +91,7 @@ fn traverse(
90 hl: &mut Highlights, 91 hl: &mut Highlights,
91 sema: &Semantics<RootDatabase>, 92 sema: &Semantics<RootDatabase>,
92 root: InFile<&SyntaxNode>, 93 root: InFile<&SyntaxNode>,
94 krate: Option<hir::Crate>,
93 range_to_highlight: TextRange, 95 range_to_highlight: TextRange,
94 syntactic_name_ref_highlighting: bool, 96 syntactic_name_ref_highlighting: bool,
95) { 97) {
@@ -209,6 +211,7 @@ fn traverse(
209 211
210 if let Some((mut highlight, binding_hash)) = highlight::element( 212 if let Some((mut highlight, binding_hash)) = highlight::element(
211 &sema, 213 &sema,
214 krate,
212 &mut bindings_shadow_count, 215 &mut bindings_shadow_count,
213 syntactic_name_ref_highlighting, 216 syntactic_name_ref_highlighting,
214 element_to_highlight.clone(), 217 element_to_highlight.clone(),
diff --git a/crates/ide/src/syntax_highlighting/highlight.rs b/crates/ide/src/syntax_highlighting/highlight.rs
index 058e37ff0..b4a3d39c9 100644
--- a/crates/ide/src/syntax_highlighting/highlight.rs
+++ b/crates/ide/src/syntax_highlighting/highlight.rs
@@ -19,6 +19,7 @@ use crate::{
19 19
20pub(super) fn element( 20pub(super) fn element(
21 sema: &Semantics<RootDatabase>, 21 sema: &Semantics<RootDatabase>,
22 krate: Option<hir::Crate>,
22 bindings_shadow_count: &mut FxHashMap<hir::Name, u32>, 23 bindings_shadow_count: &mut FxHashMap<hir::Name, u32>,
23 syntactic_name_ref_highlighting: bool, 24 syntactic_name_ref_highlighting: bool,
24 element: SyntaxElement, 25 element: SyntaxElement,
@@ -46,8 +47,10 @@ pub(super) fn element(
46 47
47 match name_kind { 48 match name_kind {
48 Some(NameClass::ExternCrate(_)) => SymbolKind::Module.into(), 49 Some(NameClass::ExternCrate(_)) => SymbolKind::Module.into(),
49 Some(NameClass::Definition(def)) => highlight_def(db, def) | HlMod::Definition, 50 Some(NameClass::Definition(def)) => {
50 Some(NameClass::ConstReference(def)) => highlight_def(db, def), 51 highlight_def(db, krate, def) | HlMod::Definition
52 }
53 Some(NameClass::ConstReference(def)) => highlight_def(db, krate, def),
51 Some(NameClass::PatFieldShorthand { field_ref, .. }) => { 54 Some(NameClass::PatFieldShorthand { field_ref, .. }) => {
52 let mut h = HlTag::Symbol(SymbolKind::Field).into(); 55 let mut h = HlTag::Symbol(SymbolKind::Field).into();
53 if let Definition::Field(field) = field_ref { 56 if let Definition::Field(field) = field_ref {
@@ -82,7 +85,7 @@ pub(super) fn element(
82 } 85 }
83 }; 86 };
84 87
85 let mut h = highlight_def(db, def); 88 let mut h = highlight_def(db, krate, def);
86 89
87 if let Definition::Local(local) = &def { 90 if let Definition::Local(local) = &def {
88 if is_consumed_lvalue(name_ref.syntax().clone().into(), local, db) { 91 if is_consumed_lvalue(name_ref.syntax().clone().into(), local, db) {
@@ -136,9 +139,11 @@ pub(super) fn element(
136 let lifetime = element.into_node().and_then(ast::Lifetime::cast).unwrap(); 139 let lifetime = element.into_node().and_then(ast::Lifetime::cast).unwrap();
137 140
138 match NameClass::classify_lifetime(sema, &lifetime) { 141 match NameClass::classify_lifetime(sema, &lifetime) {
139 Some(NameClass::Definition(def)) => highlight_def(db, def) | HlMod::Definition, 142 Some(NameClass::Definition(def)) => {
143 highlight_def(db, krate, def) | HlMod::Definition
144 }
140 None => match NameRefClass::classify_lifetime(sema, &lifetime) { 145 None => match NameRefClass::classify_lifetime(sema, &lifetime) {
141 Some(NameRefClass::Definition(def)) => highlight_def(db, def), 146 Some(NameRefClass::Definition(def)) => highlight_def(db, krate, def),
142 _ => SymbolKind::LifetimeParam.into(), 147 _ => SymbolKind::LifetimeParam.into(),
143 }, 148 },
144 _ => Highlight::from(SymbolKind::LifetimeParam) | HlMod::Definition, 149 _ => Highlight::from(SymbolKind::LifetimeParam) | HlMod::Definition,
@@ -277,12 +282,12 @@ pub(super) fn element(
277 hash((name, shadow_count)) 282 hash((name, shadow_count))
278 } 283 }
279} 284}
280fn highlight_def(db: &RootDatabase, def: Definition) -> Highlight { 285fn highlight_def(db: &RootDatabase, krate: Option<hir::Crate>, def: Definition) -> Highlight {
281 match def { 286 let mut h = match def {
282 Definition::Macro(_) => HlTag::Symbol(SymbolKind::Macro), 287 Definition::Macro(_) => Highlight::new(HlTag::Symbol(SymbolKind::Macro)),
283 Definition::Field(_) => HlTag::Symbol(SymbolKind::Field), 288 Definition::Field(_) => Highlight::new(HlTag::Symbol(SymbolKind::Field)),
284 Definition::ModuleDef(def) => match def { 289 Definition::ModuleDef(def) => match def {
285 hir::ModuleDef::Module(_) => HlTag::Symbol(SymbolKind::Module), 290 hir::ModuleDef::Module(_) => Highlight::new(HlTag::Symbol(SymbolKind::Module)),
286 hir::ModuleDef::Function(func) => { 291 hir::ModuleDef::Function(func) => {
287 let mut h = Highlight::new(HlTag::Symbol(SymbolKind::Function)); 292 let mut h = Highlight::new(HlTag::Symbol(SymbolKind::Function));
288 if let Some(item) = func.as_assoc_item(db) { 293 if let Some(item) = func.as_assoc_item(db) {
@@ -314,14 +319,22 @@ fn highlight_def(db: &RootDatabase, def: Definition) -> Highlight {
314 if func.is_async(db) { 319 if func.is_async(db) {
315 h |= HlMod::Async; 320 h |= HlMod::Async;
316 } 321 }
317 return h; 322
323 h
318 } 324 }
319 hir::ModuleDef::Adt(hir::Adt::Struct(_)) => HlTag::Symbol(SymbolKind::Struct), 325 hir::ModuleDef::Adt(adt) => {
320 hir::ModuleDef::Adt(hir::Adt::Enum(_)) => HlTag::Symbol(SymbolKind::Enum), 326 let h = match adt {
321 hir::ModuleDef::Adt(hir::Adt::Union(_)) => HlTag::Symbol(SymbolKind::Union), 327 hir::Adt::Struct(_) => HlTag::Symbol(SymbolKind::Struct),
322 hir::ModuleDef::Variant(_) => HlTag::Symbol(SymbolKind::Variant), 328 hir::Adt::Enum(_) => HlTag::Symbol(SymbolKind::Enum),
329 hir::Adt::Union(_) => HlTag::Symbol(SymbolKind::Union),
330 };
331
332 Highlight::new(h)
333 }
334 hir::ModuleDef::Variant(_) => Highlight::new(HlTag::Symbol(SymbolKind::Variant)),
323 hir::ModuleDef::Const(konst) => { 335 hir::ModuleDef::Const(konst) => {
324 let mut h = Highlight::new(HlTag::Symbol(SymbolKind::Const)); 336 let mut h = Highlight::new(HlTag::Symbol(SymbolKind::Const));
337
325 if let Some(item) = konst.as_assoc_item(db) { 338 if let Some(item) = konst.as_assoc_item(db) {
326 h |= HlMod::Associated; 339 h |= HlMod::Associated;
327 match item.container(db) { 340 match item.container(db) {
@@ -336,7 +349,7 @@ fn highlight_def(db: &RootDatabase, def: Definition) -> Highlight {
336 } 349 }
337 } 350 }
338 351
339 return h; 352 h
340 } 353 }
341 hir::ModuleDef::Trait(trait_) => { 354 hir::ModuleDef::Trait(trait_) => {
342 let mut h = Highlight::new(HlTag::Symbol(SymbolKind::Trait)); 355 let mut h = Highlight::new(HlTag::Symbol(SymbolKind::Trait));
@@ -344,10 +357,12 @@ fn highlight_def(db: &RootDatabase, def: Definition) -> Highlight {
344 if trait_.is_unsafe(db) { 357 if trait_.is_unsafe(db) {
345 h |= HlMod::Unsafe; 358 h |= HlMod::Unsafe;
346 } 359 }
347 return h; 360
361 h
348 } 362 }
349 hir::ModuleDef::TypeAlias(type_) => { 363 hir::ModuleDef::TypeAlias(type_) => {
350 let mut h = Highlight::new(HlTag::Symbol(SymbolKind::TypeAlias)); 364 let mut h = Highlight::new(HlTag::Symbol(SymbolKind::TypeAlias));
365
351 if let Some(item) = type_.as_assoc_item(db) { 366 if let Some(item) = type_.as_assoc_item(db) {
352 h |= HlMod::Associated; 367 h |= HlMod::Associated;
353 match item.container(db) { 368 match item.container(db) {
@@ -361,23 +376,30 @@ fn highlight_def(db: &RootDatabase, def: Definition) -> Highlight {
361 } 376 }
362 } 377 }
363 } 378 }
364 return h; 379
380 h
365 } 381 }
366 hir::ModuleDef::BuiltinType(_) => HlTag::BuiltinType, 382 hir::ModuleDef::BuiltinType(_) => Highlight::new(HlTag::BuiltinType),
367 hir::ModuleDef::Static(s) => { 383 hir::ModuleDef::Static(s) => {
368 let mut h = Highlight::new(HlTag::Symbol(SymbolKind::Static)); 384 let mut h = Highlight::new(HlTag::Symbol(SymbolKind::Static));
385
369 if s.is_mut(db) { 386 if s.is_mut(db) {
370 h |= HlMod::Mutable; 387 h |= HlMod::Mutable;
371 h |= HlMod::Unsafe; 388 h |= HlMod::Unsafe;
372 } 389 }
373 return h; 390
391 h
374 } 392 }
375 }, 393 },
376 Definition::SelfType(_) => HlTag::Symbol(SymbolKind::Impl), 394 Definition::SelfType(_) => Highlight::new(HlTag::Symbol(SymbolKind::Impl)),
377 Definition::GenericParam(it) => match it { 395 Definition::GenericParam(it) => match it {
378 hir::GenericParam::TypeParam(_) => HlTag::Symbol(SymbolKind::TypeParam), 396 hir::GenericParam::TypeParam(_) => Highlight::new(HlTag::Symbol(SymbolKind::TypeParam)),
379 hir::GenericParam::ConstParam(_) => HlTag::Symbol(SymbolKind::ConstParam), 397 hir::GenericParam::ConstParam(_) => {
380 hir::GenericParam::LifetimeParam(_) => HlTag::Symbol(SymbolKind::LifetimeParam), 398 Highlight::new(HlTag::Symbol(SymbolKind::ConstParam))
399 }
400 hir::GenericParam::LifetimeParam(_) => {
401 Highlight::new(HlTag::Symbol(SymbolKind::LifetimeParam))
402 }
381 }, 403 },
382 Definition::Local(local) => { 404 Definition::Local(local) => {
383 let tag = if local.is_self(db) { 405 let tag = if local.is_self(db) {
@@ -395,11 +417,19 @@ fn highlight_def(db: &RootDatabase, def: Definition) -> Highlight {
395 if ty.as_callable(db).is_some() || ty.impls_fnonce(db) { 417 if ty.as_callable(db).is_some() || ty.impls_fnonce(db) {
396 h |= HlMod::Callable; 418 h |= HlMod::Callable;
397 } 419 }
398 return h; 420 h
399 } 421 }
400 Definition::Label(_) => HlTag::Symbol(SymbolKind::Label), 422 Definition::Label(_) => Highlight::new(HlTag::Symbol(SymbolKind::Label)),
423 };
424
425 let is_from_other_crate = def.module(db).map(hir::Module::krate) != krate;
426 let is_builtin_type = matches!(def, Definition::ModuleDef(hir::ModuleDef::BuiltinType(_)));
427
428 if is_from_other_crate && !is_builtin_type {
429 h |= HlMod::Library;
401 } 430 }
402 .into() 431
432 h
403} 433}
404 434
405fn highlight_func_by_name_ref( 435fn highlight_func_by_name_ref(
diff --git a/crates/ide/src/syntax_highlighting/tags.rs b/crates/ide/src/syntax_highlighting/tags.rs
index 27473a2f9..e94f17cd9 100644
--- a/crates/ide/src/syntax_highlighting/tags.rs
+++ b/crates/ide/src/syntax_highlighting/tags.rs
@@ -67,6 +67,8 @@ pub enum HlMod {
67 Trait, 67 Trait,
68 /// Used with keywords like `async` and `await`. 68 /// Used with keywords like `async` and `await`.
69 Async, 69 Async,
70 /// Used for items from other crates.
71 Library,
70 // Keep this last! 72 // Keep this last!
71 /// Used for unsafe functions, unsafe traits, mutable statics, union accesses and unsafe operations. 73 /// Used for unsafe functions, unsafe traits, mutable statics, union accesses and unsafe operations.
72 Unsafe, 74 Unsafe,
@@ -189,6 +191,7 @@ impl HlMod {
189 HlMod::Static, 191 HlMod::Static,
190 HlMod::Trait, 192 HlMod::Trait,
191 HlMod::Async, 193 HlMod::Async,
194 HlMod::Library,
192 HlMod::Unsafe, 195 HlMod::Unsafe,
193 ]; 196 ];
194 197
@@ -207,6 +210,7 @@ impl HlMod {
207 HlMod::Static => "static", 210 HlMod::Static => "static",
208 HlMod::Trait => "trait", 211 HlMod::Trait => "trait",
209 HlMod::Async => "async", 212 HlMod::Async => "async",
213 HlMod::Library => "library",
210 HlMod::Unsafe => "unsafe", 214 HlMod::Unsafe => "unsafe",
211 } 215 }
212 } 216 }
diff --git a/crates/ide/src/syntax_highlighting/test_data/highlighting.html b/crates/ide/src/syntax_highlighting/test_data/highlighting.html
index 878431b56..055d21109 100644
--- a/crates/ide/src/syntax_highlighting/test_data/highlighting.html
+++ b/crates/ide/src/syntax_highlighting/test_data/highlighting.html
@@ -248,4 +248,20 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
248<span class="brace">}</span> 248<span class="brace">}</span>
249 249
250<span class="keyword unsafe">unsafe</span> <span class="keyword">trait</span> <span class="trait declaration unsafe">Dangerous</span> <span class="brace">{</span><span class="brace">}</span> 250<span class="keyword unsafe">unsafe</span> <span class="keyword">trait</span> <span class="trait declaration unsafe">Dangerous</span> <span class="brace">{</span><span class="brace">}</span>
251<span class="keyword">impl</span> <span class="trait unsafe">Dangerous</span> <span class="keyword">for</span> <span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="brace">{</span><span class="brace">}</span></code></pre> \ No newline at end of file 251<span class="keyword">impl</span> <span class="trait unsafe">Dangerous</span> <span class="keyword">for</span> <span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="brace">{</span><span class="brace">}</span>
252
253<span class="keyword">fn</span> <span class="function declaration">use_foo_items</span><span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="brace">{</span>
254 <span class="keyword">let</span> <span class="variable declaration">bob</span> <span class="operator">=</span> <span class="module library">foo</span><span class="operator">::</span><span class="struct library">Person</span> <span class="brace">{</span>
255 <span class="field library">name</span><span class="colon">:</span> <span class="string_literal">"Bob"</span><span class="comma">,</span>
256 <span class="field library">age</span><span class="colon">:</span> <span class="module library">foo</span><span class="operator">::</span><span class="module library">consts</span><span class="operator">::</span><span class="constant library">NUMBER</span><span class="comma">,</span>
257 <span class="brace">}</span><span class="semicolon">;</span>
258
259 <span class="keyword">let</span> <span class="variable declaration">control_flow</span> <span class="operator">=</span> <span class="module library">foo</span><span class="operator">::</span><span class="function library">identity</span><span class="parenthesis">(</span><span class="module library">foo</span><span class="operator">::</span><span class="enum library">ControlFlow</span><span class="operator">::</span><span class="enum_variant library">Continue</span><span class="parenthesis">)</span><span class="semicolon">;</span>
260
261 <span class="keyword control">if</span> <span class="keyword">let</span> <span class="module library">foo</span><span class="operator">::</span><span class="enum library">ControlFlow</span><span class="operator">::</span><span class="enum_variant library">Die</span> <span class="operator">=</span> <span class="variable">control_flow</span> <span class="brace">{</span>
262 foo::<span class="macro">die!</span><span class="parenthesis">(</span><span class="parenthesis">)</span><span class="semicolon">;</span>
263 <span class="brace">}</span>
264<span class="brace">}</span>
265
266
267</code></pre> \ No newline at end of file
diff --git a/crates/ide/src/syntax_highlighting/tests.rs b/crates/ide/src/syntax_highlighting/tests.rs
index 9ce26e930..be4447ebb 100644
--- a/crates/ide/src/syntax_highlighting/tests.rs
+++ b/crates/ide/src/syntax_highlighting/tests.rs
@@ -10,6 +10,7 @@ use crate::{fixture, FileRange, HlTag, TextRange};
10fn test_highlighting() { 10fn test_highlighting() {
11 check_highlighting( 11 check_highlighting(
12 r#" 12 r#"
13//- /main.rs crate:main deps:foo
13use inner::{self as inner_mod}; 14use inner::{self as inner_mod};
14mod inner {} 15mod inner {}
15 16
@@ -222,6 +223,43 @@ async fn async_main() {
222 223
223unsafe trait Dangerous {} 224unsafe trait Dangerous {}
224impl Dangerous for () {} 225impl Dangerous for () {}
226
227fn use_foo_items() {
228 let bob = foo::Person {
229 name: "Bob",
230 age: foo::consts::NUMBER,
231 };
232
233 let control_flow = foo::identity(foo::ControlFlow::Continue);
234
235 if let foo::ControlFlow::Die = control_flow {
236 foo::die!();
237 }
238}
239
240
241//- /foo.rs crate:foo
242pub struct Person {
243 pub name: &'static str,
244 pub age: u8,
245}
246
247pub enum ControlFlow {
248 Continue,
249 Die,
250}
251
252pub fn identity<T>(x: T) -> T { x }
253
254pub mod consts {
255 pub const NUMBER: i64 = 92;
256}
257
258macro_rules! die {
259 () => {
260 panic!();
261 };
262}
225"# 263"#
226 .trim(), 264 .trim(),
227 expect_file!["./test_data/highlighting.html"], 265 expect_file!["./test_data/highlighting.html"],
diff --git a/crates/rust-analyzer/src/semantic_tokens.rs b/crates/rust-analyzer/src/semantic_tokens.rs
index 4fd576adb..6129af95f 100644
--- a/crates/rust-analyzer/src/semantic_tokens.rs
+++ b/crates/rust-analyzer/src/semantic_tokens.rs
@@ -92,6 +92,7 @@ define_semantic_token_modifiers![
92 (MUTABLE, "mutable"), 92 (MUTABLE, "mutable"),
93 (CONSUMING, "consuming"), 93 (CONSUMING, "consuming"),
94 (ASYNC, "async"), 94 (ASYNC, "async"),
95 (LIBRARY, "library"),
95 (UNSAFE, "unsafe"), 96 (UNSAFE, "unsafe"),
96 (ATTRIBUTE_MODIFIER, "attribute"), 97 (ATTRIBUTE_MODIFIER, "attribute"),
97 (TRAIT_MODIFIER, "trait"), 98 (TRAIT_MODIFIER, "trait"),
diff --git a/crates/rust-analyzer/src/to_proto.rs b/crates/rust-analyzer/src/to_proto.rs
index 410384ae5..ca9513928 100644
--- a/crates/rust-analyzer/src/to_proto.rs
+++ b/crates/rust-analyzer/src/to_proto.rs
@@ -504,6 +504,7 @@ fn semantic_token_type_and_modifiers(
504 HlMod::Mutable => semantic_tokens::MUTABLE, 504 HlMod::Mutable => semantic_tokens::MUTABLE,
505 HlMod::Consuming => semantic_tokens::CONSUMING, 505 HlMod::Consuming => semantic_tokens::CONSUMING,
506 HlMod::Async => semantic_tokens::ASYNC, 506 HlMod::Async => semantic_tokens::ASYNC,
507 HlMod::Library => semantic_tokens::LIBRARY,
507 HlMod::Unsafe => semantic_tokens::UNSAFE, 508 HlMod::Unsafe => semantic_tokens::UNSAFE,
508 HlMod::Callable => semantic_tokens::CALLABLE, 509 HlMod::Callable => semantic_tokens::CALLABLE,
509 HlMod::Static => lsp_types::SemanticTokenModifier::STATIC, 510 HlMod::Static => lsp_types::SemanticTokenModifier::STATIC,