about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2021-09-30 16:10:23 +0000
committerGitHub <noreply@github.com>2021-09-30 16:10:23 +0000
commit529b7a4167aab91257da02277c00e5cba245babb (patch)
tree05e04c24d2c36325eb5e53512d269e3ad0ccabd6
parent26a10767cb4490cb34a7d0baeec6df6399214356 (diff)
parent0b2ba8be689225d6f243e484816cfc91f2b45bc4 (diff)
downloadrust-529b7a4167aab91257da02277c00e5cba245babb.tar.gz
rust-529b7a4167aab91257da02277c00e5cba245babb.zip
Merge #10398
10398: Give defaultLibrary semantic token modifier to items from standard library r=Veykril a=lhvy

Fixes #8999, fixes #2155

`builtInCrates` could be an alternate name to `defaultLibrary`, which one is better?

> P.S. I'm participating in [Hacktoberfest 2021](https://hacktoberfest.digitalocean.com/). If this PR is up to standard and merged, I'd appreciate if the `hacktoberfest-accepted` label could be added. Thanks!

Co-authored-by: lhvy <me@lhvy.dev>
Co-authored-by: Lucas <me@lhvy.dev>
-rw-r--r--crates/ide/src/syntax_highlighting.rs1
-rw-r--r--crates/ide/src/syntax_highlighting/highlight.rs44
-rw-r--r--crates/ide/src/syntax_highlighting/tags.rs16
-rw-r--r--crates/ide/src/syntax_highlighting/test_data/highlight_assoc_functions.html8
-rw-r--r--crates/ide/src/syntax_highlighting/test_data/highlight_default_library.html49
-rw-r--r--crates/ide/src/syntax_highlighting/test_data/highlight_doctest.html4
-rw-r--r--crates/ide/src/syntax_highlighting/test_data/highlight_extern_crate.html4
-rw-r--r--crates/ide/src/syntax_highlighting/test_data/highlighting.html8
-rw-r--r--crates/ide/src/syntax_highlighting/tests.rs17
-rw-r--r--crates/ide_db/src/helpers/famous_defs.rs23
-rw-r--r--crates/rust-analyzer/src/semantic_tokens.rs16
-rw-r--r--crates/rust-analyzer/src/to_proto.rs19
12 files changed, 163 insertions, 46 deletions
diff --git a/crates/ide/src/syntax_highlighting.rs b/crates/ide/src/syntax_highlighting.rs
index f876bbca351..6d352942cab 100644
--- a/crates/ide/src/syntax_highlighting.rs
+++ b/crates/ide/src/syntax_highlighting.rs
@@ -134,6 +134,7 @@ pub struct HlRange {
 // consuming:: Emitted for locals that are being consumed when use in a function call.
 // controlFlow:: Emitted for control-flow related tokens, this includes the `?` operator.
 // declaration:: Emitted for names of definitions, like `foo` in `fn foo() {}`.
+// defaultLibrary:: Emitted for items from built-in crates (std, core, alloc, test and proc_macro).
 // documentation:: Emitted for documentation comments.
 // injected:: Emitted for doc-string injected highlighting like rust source blocks in documentation.
 // intraDocLink:: Emitted for intra doc links in doc-strings.
diff --git a/crates/ide/src/syntax_highlighting/highlight.rs b/crates/ide/src/syntax_highlighting/highlight.rs
index dba0636930f..5113ab84d53 100644
--- a/crates/ide/src/syntax_highlighting/highlight.rs
+++ b/crates/ide/src/syntax_highlighting/highlight.rs
@@ -3,7 +3,7 @@
 use hir::{AsAssocItem, HasVisibility, Semantics};
 use ide_db::{
     defs::{Definition, NameClass, NameRefClass},
-    helpers::try_resolve_derive_input_at,
+    helpers::{try_resolve_derive_input_at, FamousDefs},
     RootDatabase, SymbolKind,
 };
 use rustc_hash::FxHashMap;
@@ -25,7 +25,6 @@ pub(super) fn element(
     syntactic_name_ref_highlighting: bool,
     element: SyntaxElement,
 ) -> Option<(Highlight, Option<u64>)> {
-    let db = sema.db;
     let mut binding_hash = None;
     let highlight: Highlight = match element.kind() {
         FN => {
@@ -79,10 +78,10 @@ pub(super) fn element(
 
             match NameClass::classify_lifetime(sema, &lifetime) {
                 Some(NameClass::Definition(def)) => {
-                    highlight_def(db, krate, def) | HlMod::Definition
+                    highlight_def(sema, krate, def) | HlMod::Definition
                 }
                 None => match NameRefClass::classify_lifetime(sema, &lifetime) {
-                    Some(NameRefClass::Definition(def)) => highlight_def(db, krate, def),
+                    Some(NameRefClass::Definition(def)) => highlight_def(sema, krate, def),
                     _ => SymbolKind::LifetimeParam.into(),
                 },
                 _ => Highlight::from(SymbolKind::LifetimeParam) | HlMod::Definition,
@@ -93,7 +92,7 @@ pub(super) fn element(
                 element.ancestors().nth(2).and_then(ast::Attr::cast).zip(element.as_token())
             {
                 match try_resolve_derive_input_at(sema, &attr, token) {
-                    Some(makro) => highlight_def(sema.db, krate, Definition::Macro(makro)),
+                    Some(makro) => highlight_def(sema, krate, Definition::Macro(makro)),
                     None => HlTag::None.into(),
                 }
             } else {
@@ -275,7 +274,7 @@ fn highlight_name_ref(
                     }
                 };
 
-                let mut h = highlight_def(db, krate, def);
+                let mut h = highlight_def(sema, krate, def);
 
                 match def {
                     Definition::Local(local)
@@ -334,7 +333,7 @@ fn highlight_name(
     };
     match name_kind {
         Some(NameClass::Definition(def)) => {
-            let mut h = highlight_def(db, krate, def) | HlMod::Definition;
+            let mut h = highlight_def(sema, krate, def) | HlMod::Definition;
             if let Definition::ModuleDef(hir::ModuleDef::Trait(trait_)) = &def {
                 if trait_.is_unsafe(db) {
                     h |= HlMod::Unsafe;
@@ -342,7 +341,7 @@ fn highlight_name(
             }
             h
         }
-        Some(NameClass::ConstReference(def)) => highlight_def(db, krate, def),
+        Some(NameClass::ConstReference(def)) => highlight_def(sema, krate, def),
         Some(NameClass::PatFieldShorthand { field_ref, .. }) => {
             let mut h = HlTag::Symbol(SymbolKind::Field).into();
             if let hir::VariantDef::Union(_) = field_ref.parent_def(db) {
@@ -366,7 +365,12 @@ fn calc_binding_hash(name: &hir::Name, shadow_count: u32) -> u64 {
     hash((name, shadow_count))
 }
 
-fn highlight_def(db: &RootDatabase, krate: Option<hir::Crate>, def: Definition) -> Highlight {
+fn highlight_def(
+    sema: &Semantics<RootDatabase>,
+    krate: Option<hir::Crate>,
+    def: Definition,
+) -> Highlight {
+    let db = sema.db;
     let mut h = match def {
         Definition::Macro(_) => Highlight::new(HlTag::Symbol(SymbolKind::Macro)),
         Definition::Field(_) => Highlight::new(HlTag::Symbol(SymbolKind::Field)),
@@ -504,7 +508,14 @@ fn highlight_def(db: &RootDatabase, krate: Option<hir::Crate>, def: Definition)
         Definition::Label(_) => Highlight::new(HlTag::Symbol(SymbolKind::Label)),
     };
 
-    let is_from_other_crate = def.module(db).map(hir::Module::krate) != krate;
+    let famous_defs = FamousDefs(&sema, krate);
+    let def_crate = def.module(db).map(hir::Module::krate).or_else(|| match def {
+        Definition::ModuleDef(hir::ModuleDef::Module(module)) => Some(module.krate()),
+        _ => None,
+    });
+    let is_from_other_crate = def_crate != krate;
+    let is_from_builtin_crate =
+        def_crate.map_or(false, |def_crate| famous_defs.builtin_crates().any(|it| def_crate == it));
     let is_builtin_type = matches!(def, Definition::ModuleDef(hir::ModuleDef::BuiltinType(_)));
     let is_public = def.visibility(db) == Some(hir::Visibility::Public);
 
@@ -514,6 +525,10 @@ fn highlight_def(db: &RootDatabase, krate: Option<hir::Crate>, def: Definition)
         _ => {}
     }
 
+    if is_from_builtin_crate {
+        h |= HlMod::DefaultLibrary;
+    }
+
     h
 }
 
@@ -546,7 +561,10 @@ fn highlight_method_call(
         h |= HlMod::Trait;
     }
 
-    let is_from_other_crate = Some(func.module(sema.db).krate()) != krate;
+    let famous_defs = FamousDefs(&sema, krate);
+    let def_crate = func.module(sema.db).krate();
+    let is_from_other_crate = Some(def_crate) != krate;
+    let is_from_builtin_crate = famous_defs.builtin_crates().any(|it| def_crate == it);
     let is_public = func.visibility(sema.db) == hir::Visibility::Public;
 
     if is_from_other_crate {
@@ -555,6 +573,10 @@ fn highlight_method_call(
         h |= HlMod::Public;
     }
 
+    if is_from_builtin_crate {
+        h |= HlMod::DefaultLibrary;
+    }
+
     if let Some(self_param) = func.self_param(sema.db) {
         match self_param.access(sema.db) {
             hir::Access::Shared => h |= HlMod::Reference,
diff --git a/crates/ide/src/syntax_highlighting/tags.rs b/crates/ide/src/syntax_highlighting/tags.rs
index dc5dfec1165..0f9a99efac6 100644
--- a/crates/ide/src/syntax_highlighting/tags.rs
+++ b/crates/ide/src/syntax_highlighting/tags.rs
@@ -55,6 +55,8 @@ pub enum HlMod {
     Consuming,
     /// Used with keywords like `if` and `break`.
     ControlFlow,
+    /// Used for items from built-in crates (std, core, alloc, test and proc_macro).
+    DefaultLibrary,
     /// `foo` in `fn foo(x: i32)` is a definition, `foo` in `foo(90 + 2)` is
     /// not.
     Definition,
@@ -187,42 +189,44 @@ impl fmt::Display for HlTag {
 impl HlMod {
     const ALL: &'static [HlMod; HlMod::Unsafe as u8 as usize + 1] = &[
         HlMod::Associated,
+        HlMod::Async,
         HlMod::Attribute,
         HlMod::Callable,
         HlMod::Consuming,
         HlMod::ControlFlow,
+        HlMod::DefaultLibrary,
         HlMod::Definition,
         HlMod::Documentation,
         HlMod::Injected,
         HlMod::IntraDocLink,
+        HlMod::Library,
         HlMod::Mutable,
+        HlMod::Public,
         HlMod::Reference,
         HlMod::Static,
         HlMod::Trait,
-        HlMod::Async,
-        HlMod::Library,
-        HlMod::Public,
         HlMod::Unsafe,
     ];
 
     fn as_str(self) -> &'static str {
         match self {
             HlMod::Associated => "associated",
+            HlMod::Async => "async",
             HlMod::Attribute => "attribute",
             HlMod::Callable => "callable",
             HlMod::Consuming => "consuming",
             HlMod::ControlFlow => "control",
+            HlMod::DefaultLibrary => "default_library",
             HlMod::Definition => "declaration",
             HlMod::Documentation => "documentation",
             HlMod::Injected => "injected",
             HlMod::IntraDocLink => "intra_doc_link",
+            HlMod::Library => "library",
             HlMod::Mutable => "mutable",
+            HlMod::Public => "public",
             HlMod::Reference => "reference",
             HlMod::Static => "static",
             HlMod::Trait => "trait",
-            HlMod::Async => "async",
-            HlMod::Library => "library",
-            HlMod::Public => "public",
             HlMod::Unsafe => "unsafe",
         }
     }
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 0d0c21cb0c7..bf3f1616ac1 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
@@ -45,8 +45,8 @@ pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
 <span class="keyword">struct</span> <span class="struct declaration">foo</span> <span class="brace">{</span><span class="brace">}</span>
 
 <span class="keyword">impl</span> <span class="struct">foo</span> <span class="brace">{</span>
-    <span class="keyword">pub</span> <span class="keyword">fn</span> <span class="function associated declaration static public">is_static</span><span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="brace">{</span><span class="brace">}</span>
-    <span class="keyword">pub</span> <span class="keyword">fn</span> <span class="function associated declaration reference public">is_not_static</span><span class="parenthesis">(</span><span class="operator">&</span><span class="self_keyword declaration reference">self</span><span class="parenthesis">)</span> <span class="brace">{</span><span class="brace">}</span>
+    <span class="keyword">pub</span> <span class="keyword">fn</span> <span class="function associated declaration public static">is_static</span><span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="brace">{</span><span class="brace">}</span>
+    <span class="keyword">pub</span> <span class="keyword">fn</span> <span class="function associated declaration public reference">is_not_static</span><span class="parenthesis">(</span><span class="operator">&</span><span class="self_keyword declaration reference">self</span><span class="parenthesis">)</span> <span class="brace">{</span><span class="brace">}</span>
 <span class="brace">}</span>
 
 <span class="keyword">trait</span> <span class="trait declaration">t</span> <span class="brace">{</span>
@@ -55,7 +55,7 @@ pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
 <span class="brace">}</span>
 
 <span class="keyword">impl</span> <span class="trait">t</span> <span class="keyword">for</span> <span class="struct">foo</span> <span class="brace">{</span>
-    <span class="keyword">pub</span> <span class="keyword">fn</span> <span class="function associated declaration static trait public">is_static</span><span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="brace">{</span><span class="brace">}</span>
-    <span class="keyword">pub</span> <span class="keyword">fn</span> <span class="function associated declaration reference trait public">is_not_static</span><span class="parenthesis">(</span><span class="operator">&</span><span class="self_keyword declaration reference">self</span><span class="parenthesis">)</span> <span class="brace">{</span><span class="brace">}</span>
+    <span class="keyword">pub</span> <span class="keyword">fn</span> <span class="function associated declaration public static trait">is_static</span><span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="brace">{</span><span class="brace">}</span>
+    <span class="keyword">pub</span> <span class="keyword">fn</span> <span class="function associated declaration public reference trait">is_not_static</span><span class="parenthesis">(</span><span class="operator">&</span><span class="self_keyword declaration reference">self</span><span class="parenthesis">)</span> <span class="brace">{</span><span class="brace">}</span>
 <span class="brace">}</span>
         </code></pre>
\ No newline at end of file
diff --git a/crates/ide/src/syntax_highlighting/test_data/highlight_default_library.html b/crates/ide/src/syntax_highlighting/test_data/highlight_default_library.html
new file mode 100644
index 00000000000..33d3196cdb3
--- /dev/null
+++ b/crates/ide/src/syntax_highlighting/test_data/highlight_default_library.html
@@ -0,0 +1,49 @@
+
+<style>
+body                { margin: 0; }
+pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padding: 0.4em; }
+
+.lifetime           { color: #DFAF8F; font-style: italic; }
+.label              { color: #DFAF8F; font-style: italic; }
+.comment            { color: #7F9F7F; }
+.documentation      { color: #629755; }
+.intra_doc_link     { font-style: italic; }
+.injected           { opacity: 0.65 ; }
+.struct, .enum      { color: #7CB8BB; }
+.enum_variant       { color: #BDE0F3; }
+.string_literal     { color: #CC9393; }
+.field              { color: #94BFF3; }
+.function           { color: #93E0E3; }
+.function.unsafe    { color: #BC8383; }
+.trait.unsafe       { color: #BC8383; }
+.operator.unsafe    { color: #BC8383; }
+.mutable.unsafe     { color: #BC8383; text-decoration: underline; }
+.keyword.unsafe     { color: #BC8383; font-weight: bold; }
+.parameter          { color: #94BFF3; }
+.text               { color: #DCDCCC; }
+.type               { color: #7CB8BB; }
+.builtin_type       { color: #8CD0D3; }
+.type_param         { color: #DFAF8F; }
+.attribute          { color: #94BFF3; }
+.numeric_literal    { color: #BFEBBF; }
+.bool_literal       { color: #BFE6EB; }
+.macro              { color: #94BFF3; }
+.module             { color: #AFD8AF; }
+.value_param        { color: #DCDCCC; }
+.variable           { color: #DCDCCC; }
+.format_specifier   { color: #CC696B; }
+.mutable            { text-decoration: underline; }
+.escape_sequence    { color: #94BFF3; }
+.keyword            { color: #F0DFAF; font-weight: bold; }
+.control            { font-style: italic; }
+.reference          { font-style: italic; font-weight: bold; }
+
+.unresolved_reference { color: #FC5555; text-decoration: wavy underline; }
+</style>
+<pre><code><span class="keyword">use</span> <span class="module default_library library">core</span><span class="operator">::</span><span class="module default_library library">iter</span><span class="semicolon">;</span>
+
+<span class="keyword">fn</span> <span class="function declaration">main</span><span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="brace">{</span>
+    <span class="keyword">let</span> <span class="variable declaration">foo</span> <span class="operator">=</span> <span class="enum_variant default_library library">Some</span><span class="parenthesis">(</span><span class="numeric_literal">92</span><span class="parenthesis">)</span><span class="semicolon">;</span>
+    <span class="keyword">let</span> <span class="variable declaration">nums</span> <span class="operator">=</span> <span class="module default_library library">iter</span><span class="operator">::</span><span class="function default_library library">repeat</span><span class="parenthesis">(</span><span class="variable">foo</span><span class="operator">.</span><span class="function associated consuming default_library library">unwrap</span><span class="parenthesis">(</span><span class="parenthesis">)</span><span class="parenthesis">)</span><span class="semicolon">;</span>
+<span class="brace">}</span>
+</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 f54af2d92e4..d9e1a05a036 100644
--- a/crates/ide/src/syntax_highlighting/test_data/highlight_doctest.html
+++ b/crates/ide/src/syntax_highlighting/test_data/highlight_doctest.html
@@ -75,7 +75,7 @@ pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
     <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="builtin_attr attribute injected">allow</span><span class="parenthesis attribute injected">(</span><span class="none attribute injected">unused_mut</span><span class="parenthesis attribute injected">)</span><span class="attribute attribute injected">]</span>
     <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>
     <span class="comment documentation">/// ```</span>
-    <span class="keyword">pub</span> <span class="keyword">const</span> <span class="keyword">fn</span> <span class="function associated declaration static public">new</span><span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="operator">-&gt;</span> <span class="struct">Foo</span> <span class="brace">{</span>
+    <span class="keyword">pub</span> <span class="keyword">const</span> <span class="keyword">fn</span> <span class="function associated declaration public static">new</span><span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="operator">-&gt;</span> <span class="struct">Foo</span> <span class="brace">{</span>
         <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>
     <span class="brace">}</span>
 
@@ -109,7 +109,7 @@ pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
     <span class="comment documentation">/// ```sh</span>
     <span class="comment documentation">/// echo 1</span>
     <span class="comment documentation">/// ```</span>
-    <span class="keyword">pub</span> <span class="keyword">fn</span> <span class="function associated declaration reference public">foo</span><span class="parenthesis">(</span><span class="operator">&</span><span class="self_keyword declaration reference">self</span><span class="parenthesis">)</span> <span class="operator">-&gt;</span> <span class="builtin_type">bool</span> <span class="brace">{</span>
+    <span class="keyword">pub</span> <span class="keyword">fn</span> <span class="function associated declaration public reference">foo</span><span class="parenthesis">(</span><span class="operator">&</span><span class="self_keyword declaration reference">self</span><span class="parenthesis">)</span> <span class="operator">-&gt;</span> <span class="builtin_type">bool</span> <span class="brace">{</span>
         <span class="bool_literal">true</span>
     <span class="brace">}</span>
 <span class="brace">}</span>
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 9c01832e754..92cfa0d0a87 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
@@ -40,6 +40,6 @@ pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
 
 .unresolved_reference { color: #FC5555; text-decoration: wavy underline; }
 </style>
-<pre><code><span class="keyword">extern</span> <span class="keyword">crate</span> <span class="module library">std</span><span class="semicolon">;</span>
-<span class="keyword">extern</span> <span class="keyword">crate</span> <span class="module library">alloc</span> <span class="keyword">as</span> <span class="module declaration library">abc</span><span class="semicolon">;</span>
+<pre><code><span class="keyword">extern</span> <span class="keyword">crate</span> <span class="module default_library library">std</span><span class="semicolon">;</span>
+<span class="keyword">extern</span> <span class="keyword">crate</span> <span class="module default_library library">alloc</span> <span class="keyword">as</span> <span class="module default_library declaration library">abc</span><span class="semicolon">;</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 16760c24deb..7918a962750 100644
--- a/crates/ide/src/syntax_highlighting/test_data/highlighting.html
+++ b/crates/ide/src/syntax_highlighting/test_data/highlighting.html
@@ -241,12 +241,12 @@ proc_macros::<span class="macro">mirror!</span> <span class="brace">{</span>
     <span class="brace">}</span>
 <span class="brace">}</span>
 
-<span class="keyword async">async</span> <span class="keyword">fn</span> <span class="function declaration async">learn_and_sing</span><span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="brace">{</span>
-    <span class="keyword">let</span> <span class="variable declaration">song</span> <span class="operator">=</span> <span class="unresolved_reference">learn_song</span><span class="parenthesis">(</span><span class="parenthesis">)</span><span class="operator">.</span><span class="keyword control async">await</span><span class="semicolon">;</span>
-    <span class="unresolved_reference">sing_song</span><span class="parenthesis">(</span><span class="variable consuming">song</span><span class="parenthesis">)</span><span class="operator">.</span><span class="keyword control async">await</span><span class="semicolon">;</span>
+<span class="keyword async">async</span> <span class="keyword">fn</span> <span class="function async declaration">learn_and_sing</span><span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="brace">{</span>
+    <span class="keyword">let</span> <span class="variable declaration">song</span> <span class="operator">=</span> <span class="unresolved_reference">learn_song</span><span class="parenthesis">(</span><span class="parenthesis">)</span><span class="operator">.</span><span class="keyword async control">await</span><span class="semicolon">;</span>
+    <span class="unresolved_reference">sing_song</span><span class="parenthesis">(</span><span class="variable consuming">song</span><span class="parenthesis">)</span><span class="operator">.</span><span class="keyword async control">await</span><span class="semicolon">;</span>
 <span class="brace">}</span>
 
-<span class="keyword async">async</span> <span class="keyword">fn</span> <span class="function declaration async">async_main</span><span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="brace">{</span>
+<span class="keyword async">async</span> <span class="keyword">fn</span> <span class="function async declaration">async_main</span><span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="brace">{</span>
     <span class="keyword">let</span> <span class="variable declaration">f1</span> <span class="operator">=</span> <span class="function async">learn_and_sing</span><span class="parenthesis">(</span><span class="parenthesis">)</span><span class="semicolon">;</span>
     <span class="keyword">let</span> <span class="variable declaration">f2</span> <span class="operator">=</span> <span class="unresolved_reference">dance</span><span class="parenthesis">(</span><span class="parenthesis">)</span><span class="semicolon">;</span>
     futures::<span class="macro">join!</span><span class="parenthesis">(</span>f1<span class="comma">,</span> f2<span class="parenthesis">)</span><span class="semicolon">;</span>
diff --git a/crates/ide/src/syntax_highlighting/tests.rs b/crates/ide/src/syntax_highlighting/tests.rs
index f5f7d8fe951..e7bfbcc6040 100644
--- a/crates/ide/src/syntax_highlighting/tests.rs
+++ b/crates/ide/src/syntax_highlighting/tests.rs
@@ -777,6 +777,23 @@ fn test_extern_crate() {
 }
 
 #[test]
+fn test_default_library() {
+    check_highlighting(
+        r#"
+        //- minicore: option, iterators
+        use core::iter;
+
+        fn main() {
+            let foo = Some(92);
+            let nums = iter::repeat(foo.unwrap());
+        }
+        "#,
+        expect_file!["./test_data/highlight_default_library.html"],
+        false,
+    );
+}
+
+#[test]
 fn test_associated_function() {
     check_highlighting(
         r#"
diff --git a/crates/ide_db/src/helpers/famous_defs.rs b/crates/ide_db/src/helpers/famous_defs.rs
index 7c59bc28d75..08bd8e0cba6 100644
--- a/crates/ide_db/src/helpers/famous_defs.rs
+++ b/crates/ide_db/src/helpers/famous_defs.rs
@@ -68,6 +68,29 @@ impl FamousDefs<'_, '_> {
         self.find_trait("core:ops:Deref")
     }
 
+    pub fn alloc(&self) -> Option<Crate> {
+        self.find_crate("alloc")
+    }
+
+    pub fn test(&self) -> Option<Crate> {
+        self.find_crate("test")
+    }
+
+    pub fn proc_macro(&self) -> Option<Crate> {
+        self.find_crate("proc_macro")
+    }
+
+    pub fn builtin_crates(&self) -> impl Iterator<Item = Crate> {
+        IntoIterator::into_iter([
+            self.std(),
+            self.core(),
+            self.alloc(),
+            self.test(),
+            self.proc_macro(),
+        ])
+        .filter_map(|it| it)
+    }
+
     fn find_trait(&self, path: &str) -> Option<Trait> {
         match self.find_def(path)? {
             hir::ScopeDef::ModuleDef(hir::ModuleDef::Trait(it)) => Some(it),
diff --git a/crates/rust-analyzer/src/semantic_tokens.rs b/crates/rust-analyzer/src/semantic_tokens.rs
index f2ed98f2a4b..8a5d09ad788 100644
--- a/crates/rust-analyzer/src/semantic_tokens.rs
+++ b/crates/rust-analyzer/src/semantic_tokens.rs
@@ -87,20 +87,20 @@ macro_rules! define_semantic_token_modifiers {
 }
 
 define_semantic_token_modifiers![
+    (ASYNC, "async"),
+    (ATTRIBUTE_MODIFIER, "attribute"),
+    (CALLABLE, "callable"),
     (CONSTANT, "constant"),
+    (CONSUMING, "consuming"),
     (CONTROL_FLOW, "controlFlow"),
     (INJECTED, "injected"),
-    (MUTABLE, "mutable"),
-    (CONSUMING, "consuming"),
-    (ASYNC, "async"),
+    (INTRA_DOC_LINK, "intraDocLink"),
     (LIBRARY, "library"),
+    (MUTABLE, "mutable"),
     (PUBLIC, "public"),
-    (UNSAFE, "unsafe"),
-    (ATTRIBUTE_MODIFIER, "attribute"),
-    (TRAIT_MODIFIER, "trait"),
-    (CALLABLE, "callable"),
-    (INTRA_DOC_LINK, "intraDocLink"),
     (REFERENCE, "reference"),
+    (TRAIT_MODIFIER, "trait"),
+    (UNSAFE, "unsafe"),
 ];
 
 #[derive(Default)]
diff --git a/crates/rust-analyzer/src/to_proto.rs b/crates/rust-analyzer/src/to_proto.rs
index 277476981f1..3508fcc189e 100644
--- a/crates/rust-analyzer/src/to_proto.rs
+++ b/crates/rust-analyzer/src/to_proto.rs
@@ -529,23 +529,24 @@ fn semantic_token_type_and_modifiers(
 
     for modifier in highlight.mods.iter() {
         let modifier = match modifier {
+            HlMod::Associated => continue,
+            HlMod::Async => semantic_tokens::ASYNC,
             HlMod::Attribute => semantic_tokens::ATTRIBUTE_MODIFIER,
+            HlMod::Callable => semantic_tokens::CALLABLE,
+            HlMod::Consuming => semantic_tokens::CONSUMING,
+            HlMod::ControlFlow => semantic_tokens::CONTROL_FLOW,
+            HlMod::DefaultLibrary => lsp_types::SemanticTokenModifier::DEFAULT_LIBRARY,
             HlMod::Definition => lsp_types::SemanticTokenModifier::DECLARATION,
             HlMod::Documentation => lsp_types::SemanticTokenModifier::DOCUMENTATION,
             HlMod::Injected => semantic_tokens::INJECTED,
-            HlMod::ControlFlow => semantic_tokens::CONTROL_FLOW,
-            HlMod::Mutable => semantic_tokens::MUTABLE,
-            HlMod::Reference => semantic_tokens::REFERENCE,
-            HlMod::Consuming => semantic_tokens::CONSUMING,
-            HlMod::Async => semantic_tokens::ASYNC,
+            HlMod::IntraDocLink => semantic_tokens::INTRA_DOC_LINK,
             HlMod::Library => semantic_tokens::LIBRARY,
+            HlMod::Mutable => semantic_tokens::MUTABLE,
             HlMod::Public => semantic_tokens::PUBLIC,
-            HlMod::Unsafe => semantic_tokens::UNSAFE,
-            HlMod::Callable => semantic_tokens::CALLABLE,
+            HlMod::Reference => semantic_tokens::REFERENCE,
             HlMod::Static => lsp_types::SemanticTokenModifier::STATIC,
-            HlMod::IntraDocLink => semantic_tokens::INTRA_DOC_LINK,
             HlMod::Trait => semantic_tokens::TRAIT_MODIFIER,
-            HlMod::Associated => continue,
+            HlMod::Unsafe => semantic_tokens::UNSAFE,
         };
         mods |= modifier;
     }