aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/ci.yaml2
-rw-r--r--Cargo.lock32
-rw-r--r--crates/ra_assists/src/ast_transform.rs7
-rw-r--r--crates/ra_cargo_watch/Cargo.toml2
-rw-r--r--crates/ra_hir/src/semantics.rs7
-rw-r--r--crates/ra_hir/src/source_analyzer.rs27
-rw-r--r--crates/ra_hir_def/src/nameres/tests.rs36
-rw-r--r--crates/ra_hir_def/src/path/lower.rs4
-rw-r--r--crates/ra_hir_def/src/path/lower/lower_use.rs11
-rw-r--r--crates/ra_hir_ty/Cargo.toml8
-rw-r--r--crates/ra_hir_ty/src/infer/pat.rs13
-rw-r--r--crates/ra_hir_ty/src/infer/unify.rs15
-rw-r--r--crates/ra_hir_ty/src/lib.rs4
-rw-r--r--crates/ra_hir_ty/src/method_resolution.rs13
-rw-r--r--crates/ra_hir_ty/src/tests/method_resolution.rs19
-rw-r--r--crates/ra_hir_ty/src/tests/patterns.rs93
-rw-r--r--crates/ra_hir_ty/src/traits/chalk.rs41
-rw-r--r--crates/ra_ide/src/completion/complete_dot.rs39
-rw-r--r--crates/ra_ide/src/goto_definition.rs6
-rw-r--r--crates/ra_ide/src/hover.rs2
-rw-r--r--crates/ra_ide/src/references.rs8
-rw-r--r--crates/ra_ide/src/references/classify.rs39
-rw-r--r--crates/ra_ide/src/syntax_highlighting.rs30
-rw-r--r--crates/ra_ide_db/src/defs.rs30
-rw-r--r--crates/rust-analyzer/Cargo.toml2
-rw-r--r--crates/rust-analyzer/src/caps.rs4
-rw-r--r--crates/rust-analyzer/src/main_loop/handlers.rs4
-rw-r--r--crates/rust-analyzer/src/req.rs18
-rw-r--r--crates/rust-analyzer/src/semantic_tokens.rs3
-rw-r--r--editors/code/README.md5
-rw-r--r--editors/code/package-lock.json157
-rw-r--r--editors/code/package.json25
-rw-r--r--editors/code/src/highlighting.ts10
-rw-r--r--xtask/src/install.rs3
-rw-r--r--xtask/src/lib.rs16
35 files changed, 520 insertions, 215 deletions
diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml
index 3f41d32f7..50c4265cf 100644
--- a/.github/workflows/ci.yaml
+++ b/.github/workflows/ci.yaml
@@ -87,7 +87,7 @@ jobs:
87 87
88 - name: Prepare cache 2 88 - name: Prepare cache 2
89 if: matrix.os == 'windows-latest' 89 if: matrix.os == 'windows-latest'
90 run: Remove-Item ./target/debug/xtask.exe 90 run: Remove-Item ./target/debug/xtask.exe, ./target/debug/deps/xtask.exe
91 91
92 typescript: 92 typescript:
93 name: TypeScript 93 name: TypeScript
diff --git a/Cargo.lock b/Cargo.lock
index 49fddef4b..373e176b0 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -2,9 +2,9 @@
2# It is not intended for manual editing. 2# It is not intended for manual editing.
3[[package]] 3[[package]]
4name = "aho-corasick" 4name = "aho-corasick"
5version = "0.7.8" 5version = "0.7.9"
6source = "registry+https://github.com/rust-lang/crates.io-index" 6source = "registry+https://github.com/rust-lang/crates.io-index"
7checksum = "743ad5a418686aad3b87fd14c43badd828cf26e214a00f92a384291cf22e1811" 7checksum = "d5e63fd144e18ba274ae7095c0197a870a7b9468abc801dd62f190d80817d2ec"
8dependencies = [ 8dependencies = [
9 "memchr", 9 "memchr",
10] 10]
@@ -129,7 +129,7 @@ checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
129[[package]] 129[[package]]
130name = "chalk-derive" 130name = "chalk-derive"
131version = "0.1.0" 131version = "0.1.0"
132source = "git+https://github.com/rust-lang/chalk.git?rev=2939913fb7bb94ac2a6721087dc086be11410702#2939913fb7bb94ac2a6721087dc086be11410702" 132source = "git+https://github.com/rust-lang/chalk.git?rev=177d71340acc7a7204a33115fc63075d86452179#177d71340acc7a7204a33115fc63075d86452179"
133dependencies = [ 133dependencies = [
134 "proc-macro2", 134 "proc-macro2",
135 "quote", 135 "quote",
@@ -139,7 +139,7 @@ dependencies = [
139[[package]] 139[[package]]
140name = "chalk-engine" 140name = "chalk-engine"
141version = "0.9.0" 141version = "0.9.0"
142source = "git+https://github.com/rust-lang/chalk.git?rev=2939913fb7bb94ac2a6721087dc086be11410702#2939913fb7bb94ac2a6721087dc086be11410702" 142source = "git+https://github.com/rust-lang/chalk.git?rev=177d71340acc7a7204a33115fc63075d86452179#177d71340acc7a7204a33115fc63075d86452179"
143dependencies = [ 143dependencies = [
144 "chalk-macros", 144 "chalk-macros",
145 "rustc-hash", 145 "rustc-hash",
@@ -148,18 +148,17 @@ dependencies = [
148[[package]] 148[[package]]
149name = "chalk-ir" 149name = "chalk-ir"
150version = "0.1.0" 150version = "0.1.0"
151source = "git+https://github.com/rust-lang/chalk.git?rev=2939913fb7bb94ac2a6721087dc086be11410702#2939913fb7bb94ac2a6721087dc086be11410702" 151source = "git+https://github.com/rust-lang/chalk.git?rev=177d71340acc7a7204a33115fc63075d86452179#177d71340acc7a7204a33115fc63075d86452179"
152dependencies = [ 152dependencies = [
153 "chalk-derive", 153 "chalk-derive",
154 "chalk-engine", 154 "chalk-engine",
155 "chalk-macros", 155 "chalk-macros",
156 "lalrpop-intern",
157] 156]
158 157
159[[package]] 158[[package]]
160name = "chalk-macros" 159name = "chalk-macros"
161version = "0.1.1" 160version = "0.1.1"
162source = "git+https://github.com/rust-lang/chalk.git?rev=2939913fb7bb94ac2a6721087dc086be11410702#2939913fb7bb94ac2a6721087dc086be11410702" 161source = "git+https://github.com/rust-lang/chalk.git?rev=177d71340acc7a7204a33115fc63075d86452179#177d71340acc7a7204a33115fc63075d86452179"
163dependencies = [ 162dependencies = [
164 "lazy_static", 163 "lazy_static",
165] 164]
@@ -167,7 +166,7 @@ dependencies = [
167[[package]] 166[[package]]
168name = "chalk-rust-ir" 167name = "chalk-rust-ir"
169version = "0.1.0" 168version = "0.1.0"
170source = "git+https://github.com/rust-lang/chalk.git?rev=2939913fb7bb94ac2a6721087dc086be11410702#2939913fb7bb94ac2a6721087dc086be11410702" 169source = "git+https://github.com/rust-lang/chalk.git?rev=177d71340acc7a7204a33115fc63075d86452179#177d71340acc7a7204a33115fc63075d86452179"
171dependencies = [ 170dependencies = [
172 "chalk-derive", 171 "chalk-derive",
173 "chalk-engine", 172 "chalk-engine",
@@ -178,7 +177,7 @@ dependencies = [
178[[package]] 177[[package]]
179name = "chalk-solve" 178name = "chalk-solve"
180version = "0.1.0" 179version = "0.1.0"
181source = "git+https://github.com/rust-lang/chalk.git?rev=2939913fb7bb94ac2a6721087dc086be11410702#2939913fb7bb94ac2a6721087dc086be11410702" 180source = "git+https://github.com/rust-lang/chalk.git?rev=177d71340acc7a7204a33115fc63075d86452179#177d71340acc7a7204a33115fc63075d86452179"
182dependencies = [ 181dependencies = [
183 "chalk-derive", 182 "chalk-derive",
184 "chalk-engine", 183 "chalk-engine",
@@ -601,12 +600,6 @@ dependencies = [
601] 600]
602 601
603[[package]] 602[[package]]
604name = "lalrpop-intern"
605version = "0.15.1"
606source = "registry+https://github.com/rust-lang/crates.io-index"
607checksum = "cc4fd87be4a815fd373e02773983940f0d75fb26fde8c098e9e45f7af03154c0"
608
609[[package]]
610name = "lazy_static" 603name = "lazy_static"
611version = "1.4.0" 604version = "1.4.0"
612source = "registry+https://github.com/rust-lang/crates.io-index" 605source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -662,9 +655,9 @@ dependencies = [
662 655
663[[package]] 656[[package]]
664name = "lsp-types" 657name = "lsp-types"
665version = "0.71.0" 658version = "0.72.0"
666source = "registry+https://github.com/rust-lang/crates.io-index" 659source = "registry+https://github.com/rust-lang/crates.io-index"
667checksum = "efa6b75633b0c3412ee36fc416e6d9c1e4ff576b536217f4ac3f34ac83d9e564" 660checksum = "face91691e558746745dc9dc6c67a4e2a24e044926e274d8378e6f19659329f0"
668dependencies = [ 661dependencies = [
669 "base64", 662 "base64",
670 "bitflags", 663 "bitflags",
@@ -1024,7 +1017,6 @@ dependencies = [
1024 "chalk-solve", 1017 "chalk-solve",
1025 "ena", 1018 "ena",
1026 "insta", 1019 "insta",
1027 "lalrpop-intern",
1028 "log", 1020 "log",
1029 "ra_arena", 1021 "ra_arena",
1030 "ra_db", 1022 "ra_db",
@@ -1266,9 +1258,9 @@ dependencies = [
1266 1258
1267[[package]] 1259[[package]]
1268name = "regex-syntax" 1260name = "regex-syntax"
1269version = "0.6.14" 1261version = "0.6.15"
1270source = "registry+https://github.com/rust-lang/crates.io-index" 1262source = "registry+https://github.com/rust-lang/crates.io-index"
1271checksum = "b28dfe3fe9badec5dbf0a79a9cccad2cfc2ab5484bdb3e44cbd1ae8b3ba2be06" 1263checksum = "7246cd0a0a6ec2239a5405b2b16e3f404fa0dcc6d28f5f5b877bf80e33e0f294"
1272 1264
1273[[package]] 1265[[package]]
1274name = "relative-path" 1266name = "relative-path"
diff --git a/crates/ra_assists/src/ast_transform.rs b/crates/ra_assists/src/ast_transform.rs
index 0e53c1eee..42856f0ca 100644
--- a/crates/ra_assists/src/ast_transform.rs
+++ b/crates/ra_assists/src/ast_transform.rs
@@ -178,5 +178,10 @@ impl<'a> AstTransform<'a> for QualifyPaths<'a> {
178 178
179pub(crate) fn path_to_ast(path: hir::ModPath) -> ast::Path { 179pub(crate) fn path_to_ast(path: hir::ModPath) -> ast::Path {
180 let parse = ast::SourceFile::parse(&path.to_string()); 180 let parse = ast::SourceFile::parse(&path.to_string());
181 parse.tree().syntax().descendants().find_map(ast::Path::cast).unwrap() 181 parse
182 .tree()
183 .syntax()
184 .descendants()
185 .find_map(ast::Path::cast)
186 .unwrap_or_else(|| panic!("failed to parse path {:?}, `{}`", path, path))
182} 187}
diff --git a/crates/ra_cargo_watch/Cargo.toml b/crates/ra_cargo_watch/Cargo.toml
index 1fdbffea1..731d50371 100644
--- a/crates/ra_cargo_watch/Cargo.toml
+++ b/crates/ra_cargo_watch/Cargo.toml
@@ -6,7 +6,7 @@ authors = ["rust-analyzer developers"]
6 6
7[dependencies] 7[dependencies]
8crossbeam-channel = "0.4.0" 8crossbeam-channel = "0.4.0"
9lsp-types = { version = "0.71.0", features = ["proposed"] } 9lsp-types = { version = "0.72.0", features = ["proposed"] }
10log = "0.4.8" 10log = "0.4.8"
11cargo_metadata = "0.9.1" 11cargo_metadata = "0.9.1"
12serde_json = "1.0.48" 12serde_json = "1.0.48"
diff --git a/crates/ra_hir/src/semantics.rs b/crates/ra_hir/src/semantics.rs
index a0853957c..afc7f7ee7 100644
--- a/crates/ra_hir/src/semantics.rs
+++ b/crates/ra_hir/src/semantics.rs
@@ -107,8 +107,11 @@ impl<'db, DB: HirDatabase> Semantics<'db, DB> {
107 self.analyze(field.syntax()).resolve_field(field) 107 self.analyze(field.syntax()).resolve_field(field)
108 } 108 }
109 109
110 pub fn resolve_record_field(&self, field: &ast::RecordField) -> Option<StructField> { 110 pub fn resolve_record_field(
111 self.analyze(field.syntax()).resolve_record_field(field) 111 &self,
112 field: &ast::RecordField,
113 ) -> Option<(StructField, Option<Local>)> {
114 self.analyze(field.syntax()).resolve_record_field(self.db, field)
112 } 115 }
113 116
114 pub fn resolve_record_literal(&self, record_lit: &ast::RecordLit) -> Option<VariantDef> { 117 pub fn resolve_record_literal(&self, record_lit: &ast::RecordLit) -> Option<VariantDef> {
diff --git a/crates/ra_hir/src/source_analyzer.rs b/crates/ra_hir/src/source_analyzer.rs
index 4c121eb73..015389fb0 100644
--- a/crates/ra_hir/src/source_analyzer.rs
+++ b/crates/ra_hir/src/source_analyzer.rs
@@ -5,7 +5,7 @@
5//! 5//!
6//! So, this modules should not be used during hir construction, it exists 6//! So, this modules should not be used during hir construction, it exists
7//! purely for "IDE needs". 7//! purely for "IDE needs".
8use std::sync::Arc; 8use std::{iter::once, sync::Arc};
9 9
10use either::Either; 10use either::Either;
11use hir_def::{ 11use hir_def::{
@@ -25,8 +25,8 @@ use ra_syntax::{
25}; 25};
26 26
27use crate::{ 27use crate::{
28 db::HirDatabase, Adt, Const, EnumVariant, Function, Local, MacroDef, ModuleDef, Path, Static, 28 db::HirDatabase, Adt, Const, EnumVariant, Function, Local, MacroDef, ModPath, ModuleDef, Path,
29 Struct, Trait, Type, TypeAlias, TypeParam, 29 PathKind, Static, Struct, Trait, Type, TypeAlias, TypeParam,
30}; 30};
31 31
32/// `SourceAnalyzer` is a convenience wrapper which exposes HIR API in terms of 32/// `SourceAnalyzer` is a convenience wrapper which exposes HIR API in terms of
@@ -162,16 +162,27 @@ impl SourceAnalyzer {
162 162
163 pub(crate) fn resolve_record_field( 163 pub(crate) fn resolve_record_field(
164 &self, 164 &self,
165 db: &impl HirDatabase,
165 field: &ast::RecordField, 166 field: &ast::RecordField,
166 ) -> Option<crate::StructField> { 167 ) -> Option<(crate::StructField, Option<Local>)> {
167 let expr_id = match field.expr() { 168 let (expr_id, local) = match field.expr() {
168 Some(it) => self.expr_id(&it)?, 169 Some(it) => (self.expr_id(&it)?, None),
169 None => { 170 None => {
170 let src = InFile { file_id: self.file_id, value: field }; 171 let src = InFile { file_id: self.file_id, value: field };
171 self.body_source_map.as_ref()?.field_init_shorthand_expr(src)? 172 let expr_id = self.body_source_map.as_ref()?.field_init_shorthand_expr(src)?;
173 let local_name = field.name_ref()?.as_name();
174 let path = ModPath::from_segments(PathKind::Plain, once(local_name));
175 let local = match self.resolver.resolve_path_in_value_ns_fully(db, &path) {
176 Some(ValueNs::LocalBinding(pat_id)) => {
177 Some(Local { pat_id, parent: self.resolver.body_owner()? })
178 }
179 _ => None,
180 };
181 (expr_id, local)
172 } 182 }
173 }; 183 };
174 self.infer.as_ref()?.record_field_resolution(expr_id).map(|it| it.into()) 184 let struct_field = self.infer.as_ref()?.record_field_resolution(expr_id)?;
185 Some((struct_field.into(), local))
175 } 186 }
176 187
177 pub(crate) fn resolve_record_literal( 188 pub(crate) fn resolve_record_literal(
diff --git a/crates/ra_hir_def/src/nameres/tests.rs b/crates/ra_hir_def/src/nameres/tests.rs
index 82f0f835c..dda5ed699 100644
--- a/crates/ra_hir_def/src/nameres/tests.rs
+++ b/crates/ra_hir_def/src/nameres/tests.rs
@@ -66,6 +66,42 @@ fn crate_def_map_smoke_test() {
66} 66}
67 67
68#[test] 68#[test]
69fn crate_def_map_super_super() {
70 let map = def_map(
71 "
72 //- /lib.rs
73 mod a {
74 const A: usize = 0;
75
76 mod b {
77 const B: usize = 0;
78
79 mod c {
80 use super::super::*;
81 }
82 }
83 }
84 ",
85 );
86 assert_snapshot!(map, @r###"
87 â‹®crate
88 â‹®a: t
89 â‹®
90 â‹®crate::a
91 â‹®A: v
92 â‹®b: t
93 â‹®
94 â‹®crate::a::b
95 â‹®B: v
96 â‹®c: t
97 â‹®
98 â‹®crate::a::b::c
99 â‹®A: v
100 â‹®b: t
101 "###)
102}
103
104#[test]
69fn bogus_paths() { 105fn bogus_paths() {
70 covers!(bogus_paths); 106 covers!(bogus_paths);
71 let map = def_map( 107 let map = def_map(
diff --git a/crates/ra_hir_def/src/path/lower.rs b/crates/ra_hir_def/src/path/lower.rs
index 62aafd508..4900000fe 100644
--- a/crates/ra_hir_def/src/path/lower.rs
+++ b/crates/ra_hir_def/src/path/lower.rs
@@ -101,8 +101,8 @@ pub(super) fn lower_path(mut path: ast::Path, hygiene: &Hygiene) -> Option<Path>
101 break; 101 break;
102 } 102 }
103 ast::PathSegmentKind::SuperKw => { 103 ast::PathSegmentKind::SuperKw => {
104 kind = PathKind::Super(1); 104 let nested_super_count = if let PathKind::Super(n) = kind { n } else { 0 };
105 break; 105 kind = PathKind::Super(nested_super_count + 1);
106 } 106 }
107 } 107 }
108 path = match qualifier(&path) { 108 path = match qualifier(&path) {
diff --git a/crates/ra_hir_def/src/path/lower/lower_use.rs b/crates/ra_hir_def/src/path/lower/lower_use.rs
index b6d1125e2..278d5196e 100644
--- a/crates/ra_hir_def/src/path/lower/lower_use.rs
+++ b/crates/ra_hir_def/src/path/lower/lower_use.rs
@@ -103,10 +103,13 @@ fn convert_path(prefix: Option<ModPath>, path: ast::Path, hygiene: &Hygiene) ->
103 ModPath::from_segments(PathKind::Super(0), iter::empty()) 103 ModPath::from_segments(PathKind::Super(0), iter::empty())
104 } 104 }
105 ast::PathSegmentKind::SuperKw => { 105 ast::PathSegmentKind::SuperKw => {
106 if prefix.is_some() { 106 let nested_super_count = match prefix.map(|p| p.kind) {
107 return None; 107 Some(PathKind::Super(n)) => n,
108 } 108 Some(_) => return None,
109 ModPath::from_segments(PathKind::Super(1), iter::empty()) 109 None => 0,
110 };
111
112 ModPath::from_segments(PathKind::Super(nested_super_count + 1), iter::empty())
110 } 113 }
111 ast::PathSegmentKind::Type { .. } => { 114 ast::PathSegmentKind::Type { .. } => {
112 // not allowed in imports 115 // not allowed in imports
diff --git a/crates/ra_hir_ty/Cargo.toml b/crates/ra_hir_ty/Cargo.toml
index 99e2fe1bf..f2558b579 100644
--- a/crates/ra_hir_ty/Cargo.toml
+++ b/crates/ra_hir_ty/Cargo.toml
@@ -21,11 +21,9 @@ ra_prof = { path = "../ra_prof" }
21ra_syntax = { path = "../ra_syntax" } 21ra_syntax = { path = "../ra_syntax" }
22test_utils = { path = "../test_utils" } 22test_utils = { path = "../test_utils" }
23 23
24chalk-solve = { git = "https://github.com/rust-lang/chalk.git", rev = "2939913fb7bb94ac2a6721087dc086be11410702" } 24chalk-solve = { git = "https://github.com/rust-lang/chalk.git", rev = "177d71340acc7a7204a33115fc63075d86452179" }
25chalk-rust-ir = { git = "https://github.com/rust-lang/chalk.git", rev = "2939913fb7bb94ac2a6721087dc086be11410702" } 25chalk-rust-ir = { git = "https://github.com/rust-lang/chalk.git", rev = "177d71340acc7a7204a33115fc63075d86452179" }
26chalk-ir = { git = "https://github.com/rust-lang/chalk.git", rev = "2939913fb7bb94ac2a6721087dc086be11410702" } 26chalk-ir = { git = "https://github.com/rust-lang/chalk.git", rev = "177d71340acc7a7204a33115fc63075d86452179" }
27
28lalrpop-intern = "0.15.1"
29 27
30[dev-dependencies] 28[dev-dependencies]
31insta = "0.13.1" 29insta = "0.13.1"
diff --git a/crates/ra_hir_ty/src/infer/pat.rs b/crates/ra_hir_ty/src/infer/pat.rs
index bf8ea192b..7a84e47f8 100644
--- a/crates/ra_hir_ty/src/infer/pat.rs
+++ b/crates/ra_hir_ty/src/infer/pat.rs
@@ -185,6 +185,19 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
185 self.write_pat_ty(pat, bound_ty); 185 self.write_pat_ty(pat, bound_ty);
186 return inner_ty; 186 return inner_ty;
187 } 187 }
188 Pat::Slice { prefix, slice: _slice, suffix } => {
189 let (container_ty, elem_ty) = match &expected {
190 ty_app!(TypeCtor::Array, st) => (TypeCtor::Array, st.as_single().clone()),
191 ty_app!(TypeCtor::Slice, st) => (TypeCtor::Slice, st.as_single().clone()),
192 _ => (TypeCtor::Slice, Ty::Unknown),
193 };
194
195 for pat_id in prefix.iter().chain(suffix) {
196 self.infer_pat(*pat_id, &elem_ty, default_bm);
197 }
198
199 Ty::apply_one(container_ty, elem_ty)
200 }
188 _ => Ty::Unknown, 201 _ => Ty::Unknown,
189 }; 202 };
190 // use a new type variable if we got Ty::Unknown here 203 // use a new type variable if we got Ty::Unknown here
diff --git a/crates/ra_hir_ty/src/infer/unify.rs b/crates/ra_hir_ty/src/infer/unify.rs
index aed527fe5..82b85d570 100644
--- a/crates/ra_hir_ty/src/infer/unify.rs
+++ b/crates/ra_hir_ty/src/infer/unify.rs
@@ -142,12 +142,21 @@ impl<T> Canonicalized<T> {
142 142
143pub fn unify(ty1: &Canonical<Ty>, ty2: &Canonical<Ty>) -> Option<Substs> { 143pub fn unify(ty1: &Canonical<Ty>, ty2: &Canonical<Ty>) -> Option<Substs> {
144 let mut table = InferenceTable::new(); 144 let mut table = InferenceTable::new();
145 let num_vars = ty1.num_vars.max(ty2.num_vars);
145 let vars = 146 let vars =
146 Substs::builder(ty1.num_vars).fill(std::iter::repeat_with(|| table.new_type_var())).build(); 147 Substs::builder(num_vars).fill(std::iter::repeat_with(|| table.new_type_var())).build();
147 let ty_with_vars = ty1.value.clone().subst_bound_vars(&vars); 148 let ty1_with_vars = ty1.value.clone().subst_bound_vars(&vars);
148 if !table.unify(&ty_with_vars, &ty2.value) { 149 let ty2_with_vars = ty2.value.clone().subst_bound_vars(&vars);
150 if !table.unify(&ty1_with_vars, &ty2_with_vars) {
149 return None; 151 return None;
150 } 152 }
153 // default any type vars that weren't unified back to their original bound vars
154 // (kind of hacky)
155 for (i, var) in vars.iter().enumerate() {
156 if &*table.resolve_ty_shallow(var) == var {
157 table.unify(var, &Ty::Bound(i as u32));
158 }
159 }
151 Some( 160 Some(
152 Substs::builder(ty1.num_vars) 161 Substs::builder(ty1.num_vars)
153 .fill(vars.iter().map(|v| table.resolve_ty_completely(v.clone()))) 162 .fill(vars.iter().map(|v| table.resolve_ty_completely(v.clone())))
diff --git a/crates/ra_hir_ty/src/lib.rs b/crates/ra_hir_ty/src/lib.rs
index 0009c426c..ca194f806 100644
--- a/crates/ra_hir_ty/src/lib.rs
+++ b/crates/ra_hir_ty/src/lib.rs
@@ -355,6 +355,10 @@ impl Substs {
355 Substs(self.0[..std::cmp::min(self.0.len(), n)].into()) 355 Substs(self.0[..std::cmp::min(self.0.len(), n)].into())
356 } 356 }
357 357
358 pub fn suffix(&self, n: usize) -> Substs {
359 Substs(self.0[self.0.len() - std::cmp::min(self.0.len(), n)..].into())
360 }
361
358 pub fn as_single(&self) -> &Ty { 362 pub fn as_single(&self) -> &Ty {
359 if self.0.len() != 1 { 363 if self.0.len() != 1 {
360 panic!("expected substs of len 1, got {:?}", self); 364 panic!("expected substs of len 1, got {:?}", self);
diff --git a/crates/ra_hir_ty/src/method_resolution.rs b/crates/ra_hir_ty/src/method_resolution.rs
index 74b908c2e..b7e8855fb 100644
--- a/crates/ra_hir_ty/src/method_resolution.rs
+++ b/crates/ra_hir_ty/src/method_resolution.rs
@@ -508,10 +508,17 @@ pub(crate) fn inherent_impl_substs(
508 impl_id: ImplId, 508 impl_id: ImplId,
509 self_ty: &Canonical<Ty>, 509 self_ty: &Canonical<Ty>,
510) -> Option<Substs> { 510) -> Option<Substs> {
511 let vars = Substs::build_for_def(db, impl_id).fill_with_bound_vars(0).build(); 511 // we create a var for each type parameter of the impl; we need to keep in
512 // mind here that `self_ty` might have vars of its own
513 let vars =
514 Substs::build_for_def(db, impl_id).fill_with_bound_vars(self_ty.num_vars as u32).build();
512 let self_ty_with_vars = db.impl_self_ty(impl_id).subst(&vars); 515 let self_ty_with_vars = db.impl_self_ty(impl_id).subst(&vars);
513 let self_ty_with_vars = Canonical { num_vars: vars.len(), value: self_ty_with_vars }; 516 let self_ty_with_vars =
514 super::infer::unify(&self_ty_with_vars, self_ty) 517 Canonical { num_vars: vars.len() + self_ty.num_vars, value: self_ty_with_vars };
518 let substs = super::infer::unify(&self_ty_with_vars, self_ty);
519 // we only want the substs for the vars we added, not the ones from self_ty
520 let result = substs.map(|s| s.suffix(vars.len()));
521 result
515} 522}
516 523
517fn transform_receiver_ty( 524fn transform_receiver_ty(
diff --git a/crates/ra_hir_ty/src/tests/method_resolution.rs b/crates/ra_hir_ty/src/tests/method_resolution.rs
index f9b394f05..af3e5b12c 100644
--- a/crates/ra_hir_ty/src/tests/method_resolution.rs
+++ b/crates/ra_hir_ty/src/tests/method_resolution.rs
@@ -1049,6 +1049,25 @@ where
1049} 1049}
1050 1050
1051#[test] 1051#[test]
1052fn method_resolution_3373() {
1053 let t = type_at(
1054 r#"
1055//- /main.rs
1056struct A<T>(T);
1057
1058impl A<i32> {
1059 fn from(v: i32) -> A<i32> { A(v) }
1060}
1061
1062fn main() {
1063 A::from(3)<|>;
1064}
1065"#,
1066 );
1067 assert_eq!(t, "A<i32>");
1068}
1069
1070#[test]
1052fn method_resolution_slow() { 1071fn method_resolution_slow() {
1053 // this can get quite slow if we set the solver size limit too high 1072 // this can get quite slow if we set the solver size limit too high
1054 let t = type_at( 1073 let t = type_at(
diff --git a/crates/ra_hir_ty/src/tests/patterns.rs b/crates/ra_hir_ty/src/tests/patterns.rs
index 81d00c2af..76aa32024 100644
--- a/crates/ra_hir_ty/src/tests/patterns.rs
+++ b/crates/ra_hir_ty/src/tests/patterns.rs
@@ -53,8 +53,9 @@ fn test(x: &i32) {
53 [140; 141) 'g': {unknown} 53 [140; 141) 'g': {unknown}
54 [144; 145) 'e': {unknown} 54 [144; 145) 'e': {unknown}
55 [158; 205) 'if let... }': () 55 [158; 205) 'if let... }': ()
56 [165; 170) '[val]': {unknown} 56 [165; 170) '[val]': [{unknown}]
57 [173; 176) 'opt': {unknown} 57 [166; 169) 'val': {unknown}
58 [173; 176) 'opt': [{unknown}]
58 [177; 205) '{ ... }': () 59 [177; 205) '{ ... }': ()
59 [191; 192) 'h': {unknown} 60 [191; 192) 'h': {unknown}
60 [195; 198) 'val': {unknown} 61 [195; 198) 'val': {unknown}
@@ -137,6 +138,94 @@ fn test() {
137} 138}
138 139
139#[test] 140#[test]
141fn infer_pattern_match_slice() {
142 assert_snapshot!(
143 infer(r#"
144fn test() {
145 let slice: &[f64] = &[0.0];
146 match slice {
147 &[] => {},
148 &[a] => {
149 a;
150 },
151 &[b, c] => {
152 b;
153 c;
154 }
155 _ => {}
156 }
157}
158"#),
159 @r###"
160 [11; 210) '{ ... } }': ()
161 [21; 26) 'slice': &[f64]
162 [37; 43) '&[0.0]': &[f64; _]
163 [38; 43) '[0.0]': [f64; _]
164 [39; 42) '0.0': f64
165 [49; 208) 'match ... }': ()
166 [55; 60) 'slice': &[f64]
167 [71; 74) '&[]': &[f64]
168 [72; 74) '[]': [f64]
169 [78; 80) '{}': ()
170 [90; 94) '&[a]': &[f64]
171 [91; 94) '[a]': [f64]
172 [92; 93) 'a': f64
173 [98; 124) '{ ... }': ()
174 [112; 113) 'a': f64
175 [134; 141) '&[b, c]': &[f64]
176 [135; 141) '[b, c]': [f64]
177 [136; 137) 'b': f64
178 [139; 140) 'c': f64
179 [145; 186) '{ ... }': ()
180 [159; 160) 'b': f64
181 [174; 175) 'c': f64
182 [195; 196) '_': &[f64]
183 [200; 202) '{}': ()
184 "###
185 );
186}
187
188#[test]
189fn infer_pattern_match_arr() {
190 assert_snapshot!(
191 infer(r#"
192fn test() {
193 let arr: [f64; 2] = [0.0, 1.0];
194 match arr {
195 [1.0, a] => {
196 a;
197 },
198 [b, c] => {
199 b;
200 c;
201 }
202 }
203}
204"#),
205 @r###"
206 [11; 180) '{ ... } }': ()
207 [21; 24) 'arr': [f64; _]
208 [37; 47) '[0.0, 1.0]': [f64; _]
209 [38; 41) '0.0': f64
210 [43; 46) '1.0': f64
211 [53; 178) 'match ... }': ()
212 [59; 62) 'arr': [f64; _]
213 [73; 81) '[1.0, a]': [f64; _]
214 [74; 77) '1.0': f64
215 [79; 80) 'a': f64
216 [85; 111) '{ ... }': ()
217 [99; 100) 'a': f64
218 [121; 127) '[b, c]': [f64; _]
219 [122; 123) 'b': f64
220 [125; 126) 'c': f64
221 [131; 172) '{ ... }': ()
222 [145; 146) 'b': f64
223 [160; 161) 'c': f64
224 "###
225 );
226}
227
228#[test]
140fn infer_adt_pattern() { 229fn infer_adt_pattern() {
141 assert_snapshot!( 230 assert_snapshot!(
142 infer(r#" 231 infer(r#"
diff --git a/crates/ra_hir_ty/src/traits/chalk.rs b/crates/ra_hir_ty/src/traits/chalk.rs
index 4001aa941..62509bc29 100644
--- a/crates/ra_hir_ty/src/traits/chalk.rs
+++ b/crates/ra_hir_ty/src/traits/chalk.rs
@@ -18,7 +18,7 @@ use crate::{
18}; 18};
19 19
20#[derive(Debug, Copy, Clone, Hash, PartialOrd, Ord, PartialEq, Eq)] 20#[derive(Debug, Copy, Clone, Hash, PartialOrd, Ord, PartialEq, Eq)]
21pub struct Interner {} 21pub struct Interner;
22 22
23impl chalk_ir::interner::Interner for Interner { 23impl chalk_ir::interner::Interner for Interner {
24 type InternedType = Box<chalk_ir::TyData<Self>>; 24 type InternedType = Box<chalk_ir::TyData<Self>>;
@@ -27,6 +27,7 @@ impl chalk_ir::interner::Interner for Interner {
27 type InternedGoal = Arc<GoalData<Self>>; 27 type InternedGoal = Arc<GoalData<Self>>;
28 type InternedGoals = Vec<Goal<Self>>; 28 type InternedGoals = Vec<Goal<Self>>;
29 type InternedSubstitution = Vec<Parameter<Self>>; 29 type InternedSubstitution = Vec<Parameter<Self>>;
30 type Identifier = TypeAliasId;
30 type DefId = InternId; 31 type DefId = InternId;
31 32
32 // FIXME: implement these 33 // FIXME: implement these
@@ -58,7 +59,7 @@ impl chalk_ir::interner::Interner for Interner {
58 None 59 None
59 } 60 }
60 61
61 fn intern_ty(ty: chalk_ir::TyData<Self>) -> Box<chalk_ir::TyData<Self>> { 62 fn intern_ty(&self, ty: chalk_ir::TyData<Self>) -> Box<chalk_ir::TyData<Self>> {
62 Box::new(ty) 63 Box::new(ty)
63 } 64 }
64 65
@@ -121,7 +122,7 @@ pub type StructId = chalk_ir::StructId<Interner>;
121pub type StructDatum = chalk_rust_ir::StructDatum<Interner>; 122pub type StructDatum = chalk_rust_ir::StructDatum<Interner>;
122pub type ImplId = chalk_ir::ImplId<Interner>; 123pub type ImplId = chalk_ir::ImplId<Interner>;
123pub type ImplDatum = chalk_rust_ir::ImplDatum<Interner>; 124pub type ImplDatum = chalk_rust_ir::ImplDatum<Interner>;
124pub type AssociatedTyValueId = chalk_rust_ir::AssociatedTyValueId; 125pub type AssociatedTyValueId = chalk_rust_ir::AssociatedTyValueId<Interner>;
125pub type AssociatedTyValue = chalk_rust_ir::AssociatedTyValue<Interner>; 126pub type AssociatedTyValue = chalk_rust_ir::AssociatedTyValue<Interner>;
126 127
127pub(super) trait ToChalk { 128pub(super) trait ToChalk {
@@ -144,12 +145,12 @@ impl ToChalk for Ty {
144 Ty::Apply(apply_ty) => { 145 Ty::Apply(apply_ty) => {
145 let name = apply_ty.ctor.to_chalk(db); 146 let name = apply_ty.ctor.to_chalk(db);
146 let substitution = apply_ty.parameters.to_chalk(db); 147 let substitution = apply_ty.parameters.to_chalk(db);
147 chalk_ir::ApplicationTy { name, substitution }.cast().intern() 148 chalk_ir::ApplicationTy { name, substitution }.cast().intern(&Interner)
148 } 149 }
149 Ty::Projection(proj_ty) => { 150 Ty::Projection(proj_ty) => {
150 let associated_ty_id = proj_ty.associated_ty.to_chalk(db); 151 let associated_ty_id = proj_ty.associated_ty.to_chalk(db);
151 let substitution = proj_ty.parameters.to_chalk(db); 152 let substitution = proj_ty.parameters.to_chalk(db);
152 chalk_ir::AliasTy { associated_ty_id, substitution }.cast().intern() 153 chalk_ir::AliasTy { associated_ty_id, substitution }.cast().intern(&Interner)
153 } 154 }
154 Ty::Placeholder(id) => { 155 Ty::Placeholder(id) => {
155 let interned_id = db.intern_type_param_id(id); 156 let interned_id = db.intern_type_param_id(id);
@@ -157,9 +158,9 @@ impl ToChalk for Ty {
157 ui: UniverseIndex::ROOT, 158 ui: UniverseIndex::ROOT,
158 idx: interned_id.as_intern_id().as_usize(), 159 idx: interned_id.as_intern_id().as_usize(),
159 } 160 }
160 .to_ty::<Interner>() 161 .to_ty::<Interner>(&Interner)
161 } 162 }
162 Ty::Bound(idx) => chalk_ir::TyData::BoundVar(idx as usize).intern(), 163 Ty::Bound(idx) => chalk_ir::TyData::BoundVar(idx as usize).intern(&Interner),
163 Ty::Infer(_infer_ty) => panic!("uncanonicalized infer ty"), 164 Ty::Infer(_infer_ty) => panic!("uncanonicalized infer ty"),
164 Ty::Dyn(predicates) => { 165 Ty::Dyn(predicates) => {
165 let where_clauses = predicates 166 let where_clauses = predicates
@@ -169,12 +170,12 @@ impl ToChalk for Ty {
169 .map(|p| p.to_chalk(db)) 170 .map(|p| p.to_chalk(db))
170 .collect(); 171 .collect();
171 let bounded_ty = chalk_ir::DynTy { bounds: make_binders(where_clauses, 1) }; 172 let bounded_ty = chalk_ir::DynTy { bounds: make_binders(where_clauses, 1) };
172 chalk_ir::TyData::Dyn(bounded_ty).intern() 173 chalk_ir::TyData::Dyn(bounded_ty).intern(&Interner)
173 } 174 }
174 Ty::Opaque(_) | Ty::Unknown => { 175 Ty::Opaque(_) | Ty::Unknown => {
175 let substitution = chalk_ir::Substitution::empty(); 176 let substitution = chalk_ir::Substitution::empty();
176 let name = TypeName::Error; 177 let name = TypeName::Error;
177 chalk_ir::ApplicationTy { name, substitution }.cast().intern() 178 chalk_ir::ApplicationTy { name, substitution }.cast().intern(&Interner)
178 } 179 }
179 } 180 }
180 } 181 }
@@ -611,6 +612,9 @@ where
611 _ => None, 612 _ => None,
612 } 613 }
613 } 614 }
615 fn interner(&self) -> &Interner {
616 &Interner
617 }
614} 618}
615 619
616pub(crate) fn associated_ty_data_query( 620pub(crate) fn associated_ty_data_query(
@@ -632,7 +636,7 @@ pub(crate) fn associated_ty_data_query(
632 let datum = AssociatedTyDatum { 636 let datum = AssociatedTyDatum {
633 trait_id: trait_.to_chalk(db), 637 trait_id: trait_.to_chalk(db),
634 id, 638 id,
635 name: lalrpop_intern::intern(&db.type_alias_data(type_alias).name.to_string()), 639 name: type_alias,
636 binders: make_binders(bound_data, generic_params.len()), 640 binders: make_binders(bound_data, generic_params.len()),
637 }; 641 };
638 Arc::new(datum) 642 Arc::new(datum)
@@ -822,13 +826,6 @@ fn type_alias_associated_ty_value(
822 Arc::new(value) 826 Arc::new(value)
823} 827}
824 828
825fn id_from_chalk<T: InternKey>(chalk_id: chalk_ir::RawId) -> T {
826 T::from_intern_id(InternId::from(chalk_id.index))
827}
828fn id_to_chalk<T: InternKey>(salsa_id: T) -> chalk_ir::RawId {
829 chalk_ir::RawId { index: salsa_id.as_intern_id().as_u32() }
830}
831
832impl From<StructId> for crate::TypeCtorId { 829impl From<StructId> for crate::TypeCtorId {
833 fn from(struct_id: StructId) -> Self { 830 fn from(struct_id: StructId) -> Self {
834 InternKey::from_intern_id(struct_id.0) 831 InternKey::from_intern_id(struct_id.0)
@@ -853,14 +850,14 @@ impl From<crate::traits::GlobalImplId> for ImplId {
853 } 850 }
854} 851}
855 852
856impl From<chalk_rust_ir::AssociatedTyValueId> for crate::traits::AssocTyValueId { 853impl From<chalk_rust_ir::AssociatedTyValueId<Interner>> for crate::traits::AssocTyValueId {
857 fn from(id: chalk_rust_ir::AssociatedTyValueId) -> Self { 854 fn from(id: chalk_rust_ir::AssociatedTyValueId<Interner>) -> Self {
858 id_from_chalk(id.0) 855 Self::from_intern_id(id.0)
859 } 856 }
860} 857}
861 858
862impl From<crate::traits::AssocTyValueId> for chalk_rust_ir::AssociatedTyValueId { 859impl From<crate::traits::AssocTyValueId> for chalk_rust_ir::AssociatedTyValueId<Interner> {
863 fn from(assoc_ty_value_id: crate::traits::AssocTyValueId) -> Self { 860 fn from(assoc_ty_value_id: crate::traits::AssocTyValueId) -> Self {
864 chalk_rust_ir::AssociatedTyValueId(id_to_chalk(assoc_ty_value_id)) 861 chalk_rust_ir::AssociatedTyValueId(assoc_ty_value_id.as_intern_id())
865 } 862 }
866} 863}
diff --git a/crates/ra_ide/src/completion/complete_dot.rs b/crates/ra_ide/src/completion/complete_dot.rs
index a6e0158b2..9145aa183 100644
--- a/crates/ra_ide/src/completion/complete_dot.rs
+++ b/crates/ra_ide/src/completion/complete_dot.rs
@@ -545,4 +545,43 @@ mod tests {
545 "### 545 "###
546 ) 546 )
547 } 547 }
548
549 #[test]
550 fn test_super_super_completion() {
551 assert_debug_snapshot!(
552 do_ref_completion(
553 r"
554 mod a {
555 const A: usize = 0;
556
557 mod b {
558 const B: usize = 0;
559
560 mod c {
561 use super::super::<|>
562 }
563 }
564 }
565 ",
566 ),
567 @r###"
568 [
569 CompletionItem {
570 label: "A",
571 source_range: [217; 217),
572 delete: [217; 217),
573 insert: "A",
574 kind: Const,
575 },
576 CompletionItem {
577 label: "b",
578 source_range: [217; 217),
579 delete: [217; 217),
580 insert: "b",
581 kind: Module,
582 },
583 ]
584 "###
585 );
586 }
548} 587}
diff --git a/crates/ra_ide/src/goto_definition.rs b/crates/ra_ide/src/goto_definition.rs
index e67585203..76ee232a3 100644
--- a/crates/ra_ide/src/goto_definition.rs
+++ b/crates/ra_ide/src/goto_definition.rs
@@ -76,6 +76,8 @@ pub(crate) fn reference_definition(
76 76
77 let name_kind = classify_name_ref(sema, name_ref); 77 let name_kind = classify_name_ref(sema, name_ref);
78 if let Some(def) = name_kind { 78 if let Some(def) = name_kind {
79 let def = def.definition();
80
79 return match def.try_to_nav(sema.db) { 81 return match def.try_to_nav(sema.db) {
80 Some(nav) => ReferenceResult::Exact(nav), 82 Some(nav) => ReferenceResult::Exact(nav),
81 None => ReferenceResult::Approximate(Vec::new()), 83 None => ReferenceResult::Approximate(Vec::new()),
@@ -795,8 +797,8 @@ mod tests {
795 Foo { x<|> }; 797 Foo { x<|> };
796 } 798 }
797 ", 799 ",
798 "x RECORD_FIELD_DEF FileId(1) [13; 19) [13; 14)", 800 "x BIND_PAT FileId(1) [42; 43)",
799 "x: i32|x", 801 "x",
800 ) 802 )
801 } 803 }
802} 804}
diff --git a/crates/ra_ide/src/hover.rs b/crates/ra_ide/src/hover.rs
index 5073bb1cf..b31956626 100644
--- a/crates/ra_ide/src/hover.rs
+++ b/crates/ra_ide/src/hover.rs
@@ -153,7 +153,7 @@ pub(crate) fn hover(db: &RootDatabase, position: FilePosition) -> Option<RangeIn
153 if let Some((node, name_kind)) = match_ast! { 153 if let Some((node, name_kind)) = match_ast! {
154 match (token.parent()) { 154 match (token.parent()) {
155 ast::NameRef(name_ref) => { 155 ast::NameRef(name_ref) => {
156 classify_name_ref(&sema, &name_ref).map(|d| (name_ref.syntax().clone(), d)) 156 classify_name_ref(&sema, &name_ref).map(|d| (name_ref.syntax().clone(), d.definition()))
157 }, 157 },
158 ast::Name(name) => { 158 ast::Name(name) => {
159 classify_name(&sema, &name).map(|d| (name.syntax().clone(), d.definition())) 159 classify_name(&sema, &name).map(|d| (name.syntax().clone(), d.definition()))
diff --git a/crates/ra_ide/src/references.rs b/crates/ra_ide/src/references.rs
index f763013ae..2eb047c96 100644
--- a/crates/ra_ide/src/references.rs
+++ b/crates/ra_ide/src/references.rs
@@ -27,7 +27,10 @@ use test_utils::tested_by;
27 27
28use crate::{display::TryToNav, FilePosition, FileRange, NavigationTarget, RangeInfo}; 28use crate::{display::TryToNav, FilePosition, FileRange, NavigationTarget, RangeInfo};
29 29
30pub(crate) use self::{classify::classify_name_ref, rename::rename}; 30pub(crate) use self::{
31 classify::{classify_name_ref, NameRefClass},
32 rename::rename,
33};
31pub(crate) use ra_ide_db::defs::{classify_name, NameDefinition}; 34pub(crate) use ra_ide_db::defs::{classify_name, NameDefinition};
32 35
33pub use self::search_scope::SearchScope; 36pub use self::search_scope::SearchScope;
@@ -160,7 +163,7 @@ fn find_name(
160 return Some(RangeInfo::new(range, (name.text().to_string(), def))); 163 return Some(RangeInfo::new(range, (name.text().to_string(), def)));
161 } 164 }
162 let name_ref = find_node_at_offset::<ast::NameRef>(&syntax, position.offset)?; 165 let name_ref = find_node_at_offset::<ast::NameRef>(&syntax, position.offset)?;
163 let def = classify_name_ref(sema, &name_ref)?; 166 let def = classify_name_ref(sema, &name_ref)?.definition();
164 let range = name_ref.syntax().text_range(); 167 let range = name_ref.syntax().text_range();
165 Some(RangeInfo::new(range, (name_ref.text().to_string(), def))) 168 Some(RangeInfo::new(range, (name_ref.text().to_string(), def)))
166} 169}
@@ -212,6 +215,7 @@ fn process_definition(
212 // See https://github.com/rust-lang/rust/pull/68198#issuecomment-574269098 215 // See https://github.com/rust-lang/rust/pull/68198#issuecomment-574269098
213 216
214 if let Some(d) = classify_name_ref(&sema, &name_ref) { 217 if let Some(d) = classify_name_ref(&sema, &name_ref) {
218 let d = d.definition();
215 if d == def { 219 if d == def {
216 let kind = 220 let kind =
217 if is_record_lit_name_ref(&name_ref) || is_call_expr_name_ref(&name_ref) { 221 if is_record_lit_name_ref(&name_ref) || is_call_expr_name_ref(&name_ref) {
diff --git a/crates/ra_ide/src/references/classify.rs b/crates/ra_ide/src/references/classify.rs
index fdd07d8d1..571236fdc 100644
--- a/crates/ra_ide/src/references/classify.rs
+++ b/crates/ra_ide/src/references/classify.rs
@@ -1,18 +1,30 @@
1//! Functions that are used to classify an element from its definition or reference. 1//! Functions that are used to classify an element from its definition or reference.
2 2
3use hir::{PathResolution, Semantics}; 3use hir::{Local, PathResolution, Semantics};
4use ra_ide_db::defs::NameDefinition; 4use ra_ide_db::defs::NameDefinition;
5use ra_ide_db::RootDatabase; 5use ra_ide_db::RootDatabase;
6use ra_prof::profile; 6use ra_prof::profile;
7use ra_syntax::{ast, AstNode}; 7use ra_syntax::{ast, AstNode};
8use test_utils::tested_by; 8use test_utils::tested_by;
9 9
10pub use ra_ide_db::defs::{from_module_def, from_struct_field}; 10pub enum NameRefClass {
11 NameDefinition(NameDefinition),
12 FieldShorthand { local: Local, field: NameDefinition },
13}
14
15impl NameRefClass {
16 pub fn definition(self) -> NameDefinition {
17 match self {
18 NameRefClass::NameDefinition(def) => def,
19 NameRefClass::FieldShorthand { local, field: _ } => NameDefinition::Local(local),
20 }
21 }
22}
11 23
12pub(crate) fn classify_name_ref( 24pub(crate) fn classify_name_ref(
13 sema: &Semantics<RootDatabase>, 25 sema: &Semantics<RootDatabase>,
14 name_ref: &ast::NameRef, 26 name_ref: &ast::NameRef,
15) -> Option<NameDefinition> { 27) -> Option<NameRefClass> {
16 let _p = profile("classify_name_ref"); 28 let _p = profile("classify_name_ref");
17 29
18 let parent = name_ref.syntax().parent()?; 30 let parent = name_ref.syntax().parent()?;
@@ -20,48 +32,53 @@ pub(crate) fn classify_name_ref(
20 if let Some(method_call) = ast::MethodCallExpr::cast(parent.clone()) { 32 if let Some(method_call) = ast::MethodCallExpr::cast(parent.clone()) {
21 tested_by!(goto_def_for_methods); 33 tested_by!(goto_def_for_methods);
22 if let Some(func) = sema.resolve_method_call(&method_call) { 34 if let Some(func) = sema.resolve_method_call(&method_call) {
23 return Some(from_module_def(func.into())); 35 return Some(NameRefClass::NameDefinition(NameDefinition::ModuleDef(func.into())));
24 } 36 }
25 } 37 }
26 38
27 if let Some(field_expr) = ast::FieldExpr::cast(parent.clone()) { 39 if let Some(field_expr) = ast::FieldExpr::cast(parent.clone()) {
28 tested_by!(goto_def_for_fields); 40 tested_by!(goto_def_for_fields);
29 if let Some(field) = sema.resolve_field(&field_expr) { 41 if let Some(field) = sema.resolve_field(&field_expr) {
30 return Some(from_struct_field(field)); 42 return Some(NameRefClass::NameDefinition(NameDefinition::StructField(field)));
31 } 43 }
32 } 44 }
33 45
34 if let Some(record_field) = ast::RecordField::cast(parent.clone()) { 46 if let Some(record_field) = ast::RecordField::cast(parent.clone()) {
35 tested_by!(goto_def_for_record_fields); 47 tested_by!(goto_def_for_record_fields);
36 tested_by!(goto_def_for_field_init_shorthand); 48 tested_by!(goto_def_for_field_init_shorthand);
37 if let Some(field_def) = sema.resolve_record_field(&record_field) { 49 if let Some((field, local)) = sema.resolve_record_field(&record_field) {
38 return Some(from_struct_field(field_def)); 50 let field = NameDefinition::StructField(field);
51 let res = match local {
52 None => NameRefClass::NameDefinition(field),
53 Some(local) => NameRefClass::FieldShorthand { field, local },
54 };
55 return Some(res);
39 } 56 }
40 } 57 }
41 58
42 if let Some(macro_call) = parent.ancestors().find_map(ast::MacroCall::cast) { 59 if let Some(macro_call) = parent.ancestors().find_map(ast::MacroCall::cast) {
43 tested_by!(goto_def_for_macros); 60 tested_by!(goto_def_for_macros);
44 if let Some(macro_def) = sema.resolve_macro_call(&macro_call) { 61 if let Some(macro_def) = sema.resolve_macro_call(&macro_call) {
45 return Some(NameDefinition::Macro(macro_def)); 62 return Some(NameRefClass::NameDefinition(NameDefinition::Macro(macro_def)));
46 } 63 }
47 } 64 }
48 65
49 let path = name_ref.syntax().ancestors().find_map(ast::Path::cast)?; 66 let path = name_ref.syntax().ancestors().find_map(ast::Path::cast)?;
50 let resolved = sema.resolve_path(&path)?; 67 let resolved = sema.resolve_path(&path)?;
51 let res = match resolved { 68 let res = match resolved {
52 PathResolution::Def(def) => from_module_def(def), 69 PathResolution::Def(def) => NameDefinition::ModuleDef(def),
53 PathResolution::AssocItem(item) => { 70 PathResolution::AssocItem(item) => {
54 let def = match item { 71 let def = match item {
55 hir::AssocItem::Function(it) => it.into(), 72 hir::AssocItem::Function(it) => it.into(),
56 hir::AssocItem::Const(it) => it.into(), 73 hir::AssocItem::Const(it) => it.into(),
57 hir::AssocItem::TypeAlias(it) => it.into(), 74 hir::AssocItem::TypeAlias(it) => it.into(),
58 }; 75 };
59 from_module_def(def) 76 NameDefinition::ModuleDef(def)
60 } 77 }
61 PathResolution::Local(local) => NameDefinition::Local(local), 78 PathResolution::Local(local) => NameDefinition::Local(local),
62 PathResolution::TypeParam(par) => NameDefinition::TypeParam(par), 79 PathResolution::TypeParam(par) => NameDefinition::TypeParam(par),
63 PathResolution::Macro(def) => NameDefinition::Macro(def), 80 PathResolution::Macro(def) => NameDefinition::Macro(def),
64 PathResolution::SelfType(impl_def) => NameDefinition::SelfType(impl_def), 81 PathResolution::SelfType(impl_def) => NameDefinition::SelfType(impl_def),
65 }; 82 };
66 Some(res) 83 Some(NameRefClass::NameDefinition(res))
67} 84}
diff --git a/crates/ra_ide/src/syntax_highlighting.rs b/crates/ra_ide/src/syntax_highlighting.rs
index 28117b4d8..b89501aff 100644
--- a/crates/ra_ide/src/syntax_highlighting.rs
+++ b/crates/ra_ide/src/syntax_highlighting.rs
@@ -19,7 +19,11 @@ use ra_syntax::{
19}; 19};
20use rustc_hash::FxHashMap; 20use rustc_hash::FxHashMap;
21 21
22use crate::{call_info::call_info_for_token, references::classify_name_ref, Analysis, FileId}; 22use crate::{
23 call_info::call_info_for_token,
24 references::{classify_name_ref, NameRefClass},
25 Analysis, FileId,
26};
23 27
24pub(crate) use html::highlight_as_html; 28pub(crate) use html::highlight_as_html;
25pub use tags::{Highlight, HighlightModifier, HighlightModifiers, HighlightTag}; 29pub use tags::{Highlight, HighlightModifier, HighlightModifiers, HighlightTag};
@@ -186,24 +190,24 @@ fn highlight_element(
186 } 190 }
187 191
188 // Highlight references like the definitions they resolve to 192 // Highlight references like the definitions they resolve to
189
190 // Special-case field init shorthand
191 NAME_REF if element.parent().and_then(ast::RecordField::cast).is_some() => {
192 HighlightTag::Field.into()
193 }
194 NAME_REF if element.ancestors().any(|it| it.kind() == ATTR) => return None, 193 NAME_REF if element.ancestors().any(|it| it.kind() == ATTR) => return None,
195 NAME_REF => { 194 NAME_REF => {
196 let name_ref = element.into_node().and_then(ast::NameRef::cast).unwrap(); 195 let name_ref = element.into_node().and_then(ast::NameRef::cast).unwrap();
197 let name_kind = classify_name_ref(sema, &name_ref)?; 196 let name_kind = classify_name_ref(sema, &name_ref)?;
198 197
199 if let NameDefinition::Local(local) = &name_kind { 198 match name_kind {
200 if let Some(name) = local.name(db) { 199 NameRefClass::NameDefinition(def) => {
201 let shadow_count = bindings_shadow_count.entry(name.clone()).or_default(); 200 if let NameDefinition::Local(local) = &def {
202 binding_hash = Some(calc_binding_hash(&name, *shadow_count)) 201 if let Some(name) = local.name(db) {
202 let shadow_count =
203 bindings_shadow_count.entry(name.clone()).or_default();
204 binding_hash = Some(calc_binding_hash(&name, *shadow_count))
205 }
206 };
207 highlight_name(db, def)
203 } 208 }
204 }; 209 NameRefClass::FieldShorthand { .. } => HighlightTag::Field.into(),
205 210 }
206 highlight_name(db, name_kind)
207 } 211 }
208 212
209 // Simple token-based highlighting 213 // Simple token-based highlighting
diff --git a/crates/ra_ide_db/src/defs.rs b/crates/ra_ide_db/src/defs.rs
index ad4638906..7b1030a14 100644
--- a/crates/ra_ide_db/src/defs.rs
+++ b/crates/ra_ide_db/src/defs.rs
@@ -111,47 +111,47 @@ fn classify_name_inner(sema: &Semantics<RootDatabase>, name: &ast::Name) -> Opti
111 }, 111 },
112 ast::RecordFieldDef(it) => { 112 ast::RecordFieldDef(it) => {
113 let field: hir::StructField = sema.to_def(&it)?; 113 let field: hir::StructField = sema.to_def(&it)?;
114 Some(from_struct_field(field)) 114 Some(NameDefinition::StructField(field))
115 }, 115 },
116 ast::Module(it) => { 116 ast::Module(it) => {
117 let def = sema.to_def(&it)?; 117 let def = sema.to_def(&it)?;
118 Some(from_module_def(def.into())) 118 Some(NameDefinition::ModuleDef(def.into()))
119 }, 119 },
120 ast::StructDef(it) => { 120 ast::StructDef(it) => {
121 let def: hir::Struct = sema.to_def(&it)?; 121 let def: hir::Struct = sema.to_def(&it)?;
122 Some(from_module_def(def.into())) 122 Some(NameDefinition::ModuleDef(def.into()))
123 }, 123 },
124 ast::UnionDef(it) => { 124 ast::UnionDef(it) => {
125 let def: hir::Union = sema.to_def(&it)?; 125 let def: hir::Union = sema.to_def(&it)?;
126 Some(from_module_def(def.into())) 126 Some(NameDefinition::ModuleDef(def.into()))
127 }, 127 },
128 ast::EnumDef(it) => { 128 ast::EnumDef(it) => {
129 let def: hir::Enum = sema.to_def(&it)?; 129 let def: hir::Enum = sema.to_def(&it)?;
130 Some(from_module_def(def.into())) 130 Some(NameDefinition::ModuleDef(def.into()))
131 }, 131 },
132 ast::TraitDef(it) => { 132 ast::TraitDef(it) => {
133 let def: hir::Trait = sema.to_def(&it)?; 133 let def: hir::Trait = sema.to_def(&it)?;
134 Some(from_module_def(def.into())) 134 Some(NameDefinition::ModuleDef(def.into()))
135 }, 135 },
136 ast::StaticDef(it) => { 136 ast::StaticDef(it) => {
137 let def: hir::Static = sema.to_def(&it)?; 137 let def: hir::Static = sema.to_def(&it)?;
138 Some(from_module_def(def.into())) 138 Some(NameDefinition::ModuleDef(def.into()))
139 }, 139 },
140 ast::EnumVariant(it) => { 140 ast::EnumVariant(it) => {
141 let def: hir::EnumVariant = sema.to_def(&it)?; 141 let def: hir::EnumVariant = sema.to_def(&it)?;
142 Some(from_module_def(def.into())) 142 Some(NameDefinition::ModuleDef(def.into()))
143 }, 143 },
144 ast::FnDef(it) => { 144 ast::FnDef(it) => {
145 let def: hir::Function = sema.to_def(&it)?; 145 let def: hir::Function = sema.to_def(&it)?;
146 Some(from_module_def(def.into())) 146 Some(NameDefinition::ModuleDef(def.into()))
147 }, 147 },
148 ast::ConstDef(it) => { 148 ast::ConstDef(it) => {
149 let def: hir::Const = sema.to_def(&it)?; 149 let def: hir::Const = sema.to_def(&it)?;
150 Some(from_module_def(def.into())) 150 Some(NameDefinition::ModuleDef(def.into()))
151 }, 151 },
152 ast::TypeAliasDef(it) => { 152 ast::TypeAliasDef(it) => {
153 let def: hir::TypeAlias = sema.to_def(&it)?; 153 let def: hir::TypeAlias = sema.to_def(&it)?;
154 Some(from_module_def(def.into())) 154 Some(NameDefinition::ModuleDef(def.into()))
155 }, 155 },
156 ast::MacroCall(it) => { 156 ast::MacroCall(it) => {
157 let def = sema.to_def(&it)?; 157 let def = sema.to_def(&it)?;
@@ -165,11 +165,3 @@ fn classify_name_inner(sema: &Semantics<RootDatabase>, name: &ast::Name) -> Opti
165 } 165 }
166 } 166 }
167} 167}
168
169pub fn from_struct_field(field: StructField) -> NameDefinition {
170 NameDefinition::StructField(field)
171}
172
173pub fn from_module_def(def: ModuleDef) -> NameDefinition {
174 NameDefinition::ModuleDef(def)
175}
diff --git a/crates/rust-analyzer/Cargo.toml b/crates/rust-analyzer/Cargo.toml
index d00545121..b14ebb268 100644
--- a/crates/rust-analyzer/Cargo.toml
+++ b/crates/rust-analyzer/Cargo.toml
@@ -20,7 +20,7 @@ globset = "0.4.4"
20itertools = "0.8.2" 20itertools = "0.8.2"
21jod-thread = "0.1.0" 21jod-thread = "0.1.0"
22log = "0.4.8" 22log = "0.4.8"
23lsp-types = { version = "0.71.0", features = ["proposed"] } 23lsp-types = { version = "0.72.0", features = ["proposed"] }
24parking_lot = "0.10.0" 24parking_lot = "0.10.0"
25pico-args = "0.3.1" 25pico-args = "0.3.1"
26rand = { version = "0.7.3", features = ["small_rng"] } 26rand = { version = "0.7.3", features = ["small_rng"] }
diff --git a/crates/rust-analyzer/src/caps.rs b/crates/rust-analyzer/src/caps.rs
index 759bceb32..45b60768a 100644
--- a/crates/rust-analyzer/src/caps.rs
+++ b/crates/rust-analyzer/src/caps.rs
@@ -63,8 +63,8 @@ pub fn server_capabilities() -> ServerCapabilities {
63 semantic_tokens_provider: Some( 63 semantic_tokens_provider: Some(
64 SemanticTokensOptions { 64 SemanticTokensOptions {
65 legend: SemanticTokensLegend { 65 legend: SemanticTokensLegend {
66 token_types: semantic_tokens::SUPPORTED_TYPES.iter().cloned().collect(), 66 token_types: semantic_tokens::SUPPORTED_TYPES.to_vec(),
67 token_modifiers: semantic_tokens::SUPPORTED_MODIFIERS.iter().cloned().collect(), 67 token_modifiers: semantic_tokens::SUPPORTED_MODIFIERS.to_vec(),
68 }, 68 },
69 69
70 document_provider: Some(SemanticTokensDocumentProvider::Bool(true)), 70 document_provider: Some(SemanticTokensDocumentProvider::Bool(true)),
diff --git a/crates/rust-analyzer/src/main_loop/handlers.rs b/crates/rust-analyzer/src/main_loop/handlers.rs
index 6f517760f..f51263f22 100644
--- a/crates/rust-analyzer/src/main_loop/handlers.rs
+++ b/crates/rust-analyzer/src/main_loop/handlers.rs
@@ -184,6 +184,10 @@ pub fn handle_on_type_formatting(
184 // `text.char_at(position) == typed_char`. 184 // `text.char_at(position) == typed_char`.
185 position.offset -= TextUnit::of_char('.'); 185 position.offset -= TextUnit::of_char('.');
186 let char_typed = params.ch.chars().next().unwrap_or('\0'); 186 let char_typed = params.ch.chars().next().unwrap_or('\0');
187 assert!({
188 let text = world.analysis().file_text(position.file_id)?;
189 text[position.offset.to_usize()..].starts_with(char_typed)
190 });
187 191
188 // We have an assist that inserts ` ` after typing `->` in `fn foo() ->{`, 192 // We have an assist that inserts ` ` after typing `->` in `fn foo() ->{`,
189 // but it requires precise cursor positioning to work, and one can't 193 // but it requires precise cursor positioning to work, and one can't
diff --git a/crates/rust-analyzer/src/req.rs b/crates/rust-analyzer/src/req.rs
index fd6aef597..a3efe3b9f 100644
--- a/crates/rust-analyzer/src/req.rs
+++ b/crates/rust-analyzer/src/req.rs
@@ -42,14 +42,14 @@ impl Request for SyntaxTree {
42 const METHOD: &'static str = "rust-analyzer/syntaxTree"; 42 const METHOD: &'static str = "rust-analyzer/syntaxTree";
43} 43}
44 44
45#[derive(Deserialize, Debug)] 45#[derive(Deserialize, Serialize, Debug)]
46#[serde(rename_all = "camelCase")] 46#[serde(rename_all = "camelCase")]
47pub struct SyntaxTreeParams { 47pub struct SyntaxTreeParams {
48 pub text_document: TextDocumentIdentifier, 48 pub text_document: TextDocumentIdentifier,
49 pub range: Option<Range>, 49 pub range: Option<Range>,
50} 50}
51 51
52#[derive(Serialize, Debug)] 52#[derive(Deserialize, Serialize, Debug)]
53#[serde(rename_all = "camelCase")] 53#[serde(rename_all = "camelCase")]
54pub struct ExpandedMacro { 54pub struct ExpandedMacro {
55 pub name: String, 55 pub name: String,
@@ -64,7 +64,7 @@ impl Request for ExpandMacro {
64 const METHOD: &'static str = "rust-analyzer/expandMacro"; 64 const METHOD: &'static str = "rust-analyzer/expandMacro";
65} 65}
66 66
67#[derive(Deserialize, Debug)] 67#[derive(Deserialize, Serialize, Debug)]
68#[serde(rename_all = "camelCase")] 68#[serde(rename_all = "camelCase")]
69pub struct ExpandMacroParams { 69pub struct ExpandMacroParams {
70 pub text_document: TextDocumentIdentifier, 70 pub text_document: TextDocumentIdentifier,
@@ -79,7 +79,7 @@ impl Request for FindMatchingBrace {
79 const METHOD: &'static str = "rust-analyzer/findMatchingBrace"; 79 const METHOD: &'static str = "rust-analyzer/findMatchingBrace";
80} 80}
81 81
82#[derive(Deserialize, Debug)] 82#[derive(Deserialize, Serialize, Debug)]
83#[serde(rename_all = "camelCase")] 83#[serde(rename_all = "camelCase")]
84pub struct FindMatchingBraceParams { 84pub struct FindMatchingBraceParams {
85 pub text_document: TextDocumentIdentifier, 85 pub text_document: TextDocumentIdentifier,
@@ -101,14 +101,14 @@ impl Notification for PublishDecorations {
101 const METHOD: &'static str = "rust-analyzer/publishDecorations"; 101 const METHOD: &'static str = "rust-analyzer/publishDecorations";
102} 102}
103 103
104#[derive(Serialize, Debug)] 104#[derive(Deserialize, Serialize, Debug)]
105#[serde(rename_all = "camelCase")] 105#[serde(rename_all = "camelCase")]
106pub struct PublishDecorationsParams { 106pub struct PublishDecorationsParams {
107 pub uri: Url, 107 pub uri: Url,
108 pub decorations: Vec<Decoration>, 108 pub decorations: Vec<Decoration>,
109} 109}
110 110
111#[derive(Serialize, Debug)] 111#[derive(Deserialize, Serialize, Debug)]
112#[serde(rename_all = "camelCase")] 112#[serde(rename_all = "camelCase")]
113pub struct Decoration { 113pub struct Decoration {
114 pub range: Range, 114 pub range: Range,
@@ -132,7 +132,7 @@ impl Request for JoinLines {
132 const METHOD: &'static str = "rust-analyzer/joinLines"; 132 const METHOD: &'static str = "rust-analyzer/joinLines";
133} 133}
134 134
135#[derive(Deserialize, Debug)] 135#[derive(Deserialize, Serialize, Debug)]
136#[serde(rename_all = "camelCase")] 136#[serde(rename_all = "camelCase")]
137pub struct JoinLinesParams { 137pub struct JoinLinesParams {
138 pub text_document: TextDocumentIdentifier, 138 pub text_document: TextDocumentIdentifier,
@@ -162,7 +162,7 @@ pub struct RunnablesParams {
162 pub position: Option<Position>, 162 pub position: Option<Position>,
163} 163}
164 164
165#[derive(Serialize, Debug)] 165#[derive(Deserialize, Serialize, Debug)]
166#[serde(rename_all = "camelCase")] 166#[serde(rename_all = "camelCase")]
167pub struct Runnable { 167pub struct Runnable {
168 pub range: Range, 168 pub range: Range,
@@ -173,7 +173,7 @@ pub struct Runnable {
173 pub cwd: Option<String>, 173 pub cwd: Option<String>,
174} 174}
175 175
176#[derive(Serialize, Debug)] 176#[derive(Deserialize, Serialize, Debug)]
177#[serde(rename_all = "camelCase")] 177#[serde(rename_all = "camelCase")]
178pub struct SourceChange { 178pub struct SourceChange {
179 pub label: String, 179 pub label: String,
diff --git a/crates/rust-analyzer/src/semantic_tokens.rs b/crates/rust-analyzer/src/semantic_tokens.rs
index 1b146e4d8..d9ba77050 100644
--- a/crates/rust-analyzer/src/semantic_tokens.rs
+++ b/crates/rust-analyzer/src/semantic_tokens.rs
@@ -49,12 +49,9 @@ pub(crate) const SUPPORTED_MODIFIERS: &[SemanticTokenModifier] = &[
49 SemanticTokenModifier::DOCUMENTATION, 49 SemanticTokenModifier::DOCUMENTATION,
50 SemanticTokenModifier::DECLARATION, 50 SemanticTokenModifier::DECLARATION,
51 SemanticTokenModifier::DEFINITION, 51 SemanticTokenModifier::DEFINITION,
52 SemanticTokenModifier::REFERENCE,
53 SemanticTokenModifier::STATIC, 52 SemanticTokenModifier::STATIC,
54 SemanticTokenModifier::ABSTRACT, 53 SemanticTokenModifier::ABSTRACT,
55 SemanticTokenModifier::DEPRECATED, 54 SemanticTokenModifier::DEPRECATED,
56 SemanticTokenModifier::ASYNC,
57 SemanticTokenModifier::VOLATILE,
58 SemanticTokenModifier::READONLY, 55 SemanticTokenModifier::READONLY,
59 CONSTANT, 56 CONSTANT,
60 MUTABLE, 57 MUTABLE,
diff --git a/editors/code/README.md b/editors/code/README.md
new file mode 100644
index 000000000..336695d9f
--- /dev/null
+++ b/editors/code/README.md
@@ -0,0 +1,5 @@
1# rust-analyzer
2
3Provides support for rust-analyzer: novel LSP server for the Rust programming language.
4
5See https://rust-analyzer.github.io/ for more information.
diff --git a/editors/code/package-lock.json b/editors/code/package-lock.json
index 6901363fc..b07caf034 100644
--- a/editors/code/package-lock.json
+++ b/editors/code/package-lock.json
@@ -89,18 +89,19 @@
89 "dev": true 89 "dev": true
90 }, 90 },
91 "@types/node": { 91 "@types/node": {
92 "version": "12.12.27", 92 "version": "12.12.29",
93 "resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.27.tgz", 93 "resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.29.tgz",
94 "integrity": "sha512-odQFl/+B9idbdS0e8IxDl2ia/LP8KZLXhV3BUeI98TrZp0uoIzQPhGd+5EtzHmT0SMOIaPd7jfz6pOHLWTtl7A==", 94 "integrity": "sha512-yo8Qz0ygADGFptISDj3pOC9wXfln/5pQaN/ysDIzOaAWXt73cNHmtEC8zSO2Y+kse/txmwIAJzkYZ5fooaS5DQ==",
95 "dev": true 95 "dev": true
96 }, 96 },
97 "@types/node-fetch": { 97 "@types/node-fetch": {
98 "version": "2.5.4", 98 "version": "2.5.5",
99 "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.5.4.tgz", 99 "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.5.5.tgz",
100 "integrity": "sha512-Oz6id++2qAOFuOlE1j0ouk1dzl3mmI1+qINPNBhi9nt/gVOz0G+13Ao6qjhdF0Ys+eOkhu6JnFmt38bR3H0POQ==", 100 "integrity": "sha512-IWwjsyYjGw+em3xTvWVQi5MgYKbRs0du57klfTaZkv/B24AEQ/p/IopNeqIYNy3EsfHOpg8ieQSDomPcsYMHpA==",
101 "dev": true, 101 "dev": true,
102 "requires": { 102 "requires": {
103 "@types/node": "*" 103 "@types/node": "*",
104 "form-data": "^3.0.0"
104 } 105 }
105 }, 106 },
106 "@types/resolve": { 107 "@types/resolve": {
@@ -119,56 +120,45 @@
119 "dev": true 120 "dev": true
120 }, 121 },
121 "@typescript-eslint/eslint-plugin": { 122 "@typescript-eslint/eslint-plugin": {
122 "version": "2.20.0", 123 "version": "2.22.0",
123 "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-2.20.0.tgz", 124 "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-2.22.0.tgz",
124 "integrity": "sha512-cimIdVDV3MakiGJqMXw51Xci6oEDEoPkvh8ggJe2IIzcc0fYqAxOXN6Vbeanahz6dLZq64W+40iUEc9g32FLDQ==", 125 "integrity": "sha512-BvxRLaTDVQ3N+Qq8BivLiE9akQLAOUfxNHIEhedOcg8B2+jY8Rc4/D+iVprvuMX1AdezFYautuGDwr9QxqSxBQ==",
125 "dev": true, 126 "dev": true,
126 "requires": { 127 "requires": {
127 "@typescript-eslint/experimental-utils": "2.20.0", 128 "@typescript-eslint/experimental-utils": "2.22.0",
128 "eslint-utils": "^1.4.3", 129 "eslint-utils": "^1.4.3",
129 "functional-red-black-tree": "^1.0.1", 130 "functional-red-black-tree": "^1.0.1",
130 "regexpp": "^3.0.0", 131 "regexpp": "^3.0.0",
131 "tsutils": "^3.17.1" 132 "tsutils": "^3.17.1"
132 },
133 "dependencies": {
134 "tsutils": {
135 "version": "3.17.1",
136 "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.17.1.tgz",
137 "integrity": "sha512-kzeQ5B8H3w60nFY2g8cJIuH7JDpsALXySGtwGJ0p2LSjLgay3NdIpqq5SoOBe46bKDW2iq25irHCr8wjomUS2g==",
138 "dev": true,
139 "requires": {
140 "tslib": "^1.8.1"
141 }
142 }
143 } 133 }
144 }, 134 },
145 "@typescript-eslint/experimental-utils": { 135 "@typescript-eslint/experimental-utils": {
146 "version": "2.20.0", 136 "version": "2.22.0",
147 "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-2.20.0.tgz", 137 "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-2.22.0.tgz",
148 "integrity": "sha512-fEBy9xYrwG9hfBLFEwGW2lKwDRTmYzH3DwTmYbT+SMycmxAoPl0eGretnBFj/s+NfYBG63w/5c3lsvqqz5mYag==", 138 "integrity": "sha512-sJt1GYBe6yC0dWOQzXlp+tiuGglNhJC9eXZeC8GBVH98Zv9jtatccuhz0OF5kC/DwChqsNfghHx7OlIDQjNYAQ==",
149 "dev": true, 139 "dev": true,
150 "requires": { 140 "requires": {
151 "@types/json-schema": "^7.0.3", 141 "@types/json-schema": "^7.0.3",
152 "@typescript-eslint/typescript-estree": "2.20.0", 142 "@typescript-eslint/typescript-estree": "2.22.0",
153 "eslint-scope": "^5.0.0" 143 "eslint-scope": "^5.0.0"
154 } 144 }
155 }, 145 },
156 "@typescript-eslint/parser": { 146 "@typescript-eslint/parser": {
157 "version": "2.20.0", 147 "version": "2.22.0",
158 "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-2.20.0.tgz", 148 "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-2.22.0.tgz",
159 "integrity": "sha512-o8qsKaosLh2qhMZiHNtaHKTHyCHc3Triq6aMnwnWj7budm3xAY9owSZzV1uon5T9cWmJRJGzTFa90aex4m77Lw==", 149 "integrity": "sha512-FaZKC1X+nvD7qMPqKFUYHz3H0TAioSVFGvG29f796Nc5tBluoqfHgLbSFKsh7mKjRoeTm8J9WX2Wo9EyZWjG7w==",
160 "dev": true, 150 "dev": true,
161 "requires": { 151 "requires": {
162 "@types/eslint-visitor-keys": "^1.0.0", 152 "@types/eslint-visitor-keys": "^1.0.0",
163 "@typescript-eslint/experimental-utils": "2.20.0", 153 "@typescript-eslint/experimental-utils": "2.22.0",
164 "@typescript-eslint/typescript-estree": "2.20.0", 154 "@typescript-eslint/typescript-estree": "2.22.0",
165 "eslint-visitor-keys": "^1.1.0" 155 "eslint-visitor-keys": "^1.1.0"
166 } 156 }
167 }, 157 },
168 "@typescript-eslint/typescript-estree": { 158 "@typescript-eslint/typescript-estree": {
169 "version": "2.20.0", 159 "version": "2.22.0",
170 "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-2.20.0.tgz", 160 "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-2.22.0.tgz",
171 "integrity": "sha512-WlFk8QtI8pPaE7JGQGxU7nGcnk1ccKAJkhbVookv94ZcAef3m6oCE/jEDL6dGte3JcD7reKrA0o55XhBRiVT3A==", 161 "integrity": "sha512-2HFZW2FQc4MhIBB8WhDm9lVFaBDy6h9jGrJ4V2Uzxe/ON29HCHBTj3GkgcsgMWfsl2U5as+pTOr30Nibaw7qRQ==",
172 "dev": true, 162 "dev": true,
173 "requires": { 163 "requires": {
174 "debug": "^4.1.1", 164 "debug": "^4.1.1",
@@ -178,17 +168,6 @@
178 "lodash": "^4.17.15", 168 "lodash": "^4.17.15",
179 "semver": "^6.3.0", 169 "semver": "^6.3.0",
180 "tsutils": "^3.17.1" 170 "tsutils": "^3.17.1"
181 },
182 "dependencies": {
183 "tsutils": {
184 "version": "3.17.1",
185 "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.17.1.tgz",
186 "integrity": "sha512-kzeQ5B8H3w60nFY2g8cJIuH7JDpsALXySGtwGJ0p2LSjLgay3NdIpqq5SoOBe46bKDW2iq25irHCr8wjomUS2g==",
187 "dev": true,
188 "requires": {
189 "tslib": "^1.8.1"
190 }
191 }
192 } 171 }
193 }, 172 },
194 "acorn": { 173 "acorn": {
@@ -254,6 +233,12 @@
254 "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", 233 "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==",
255 "dev": true 234 "dev": true
256 }, 235 },
236 "asynckit": {
237 "version": "0.4.0",
238 "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
239 "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=",
240 "dev": true
241 },
257 "azure-devops-node-api": { 242 "azure-devops-node-api": {
258 "version": "7.2.0", 243 "version": "7.2.0",
259 "resolved": "https://registry.npmjs.org/azure-devops-node-api/-/azure-devops-node-api-7.2.0.tgz", 244 "resolved": "https://registry.npmjs.org/azure-devops-node-api/-/azure-devops-node-api-7.2.0.tgz",
@@ -367,6 +352,15 @@
367 "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", 352 "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
368 "dev": true 353 "dev": true
369 }, 354 },
355 "combined-stream": {
356 "version": "1.0.8",
357 "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
358 "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
359 "dev": true,
360 "requires": {
361 "delayed-stream": "~1.0.0"
362 }
363 },
370 "commander": { 364 "commander": {
371 "version": "2.20.3", 365 "version": "2.20.3",
372 "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", 366 "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
@@ -439,6 +433,12 @@
439 "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", 433 "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=",
440 "dev": true 434 "dev": true
441 }, 435 },
436 "delayed-stream": {
437 "version": "1.0.0",
438 "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
439 "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=",
440 "dev": true
441 },
442 "denodeify": { 442 "denodeify": {
443 "version": "1.2.1", 443 "version": "1.2.1",
444 "resolved": "https://registry.npmjs.org/denodeify/-/denodeify-1.2.1.tgz", 444 "resolved": "https://registry.npmjs.org/denodeify/-/denodeify-1.2.1.tgz",
@@ -748,6 +748,17 @@
748 "integrity": "sha512-a1hQMktqW9Nmqr5aktAux3JMNqaucxGcjtjWnZLHX7yyPCmlSV3M54nGYbqT8K+0GhF3NBgmJCc3ma+WOgX8Jg==", 748 "integrity": "sha512-a1hQMktqW9Nmqr5aktAux3JMNqaucxGcjtjWnZLHX7yyPCmlSV3M54nGYbqT8K+0GhF3NBgmJCc3ma+WOgX8Jg==",
749 "dev": true 749 "dev": true
750 }, 750 },
751 "form-data": {
752 "version": "3.0.0",
753 "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.0.tgz",
754 "integrity": "sha512-CKMFDglpbMi6PyN+brwB9Q/GOw0eAnsrEZDgcsH5Krhz5Od/haKHAX0NmQfha2zPPz0JpWzA7GJHGSnvCRLWsg==",
755 "dev": true,
756 "requires": {
757 "asynckit": "^0.4.0",
758 "combined-stream": "^1.0.8",
759 "mime-types": "^2.1.12"
760 }
761 },
751 "fs.realpath": { 762 "fs.realpath": {
752 "version": "1.0.0", 763 "version": "1.0.0",
753 "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", 764 "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
@@ -957,9 +968,9 @@
957 "dev": true 968 "dev": true
958 }, 969 },
959 "jsonc-parser": { 970 "jsonc-parser": {
960 "version": "2.2.0", 971 "version": "2.2.1",
961 "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-2.2.0.tgz", 972 "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-2.2.1.tgz",
962 "integrity": "sha512-4fLQxW1j/5fWj6p78vAlAafoCKtuBm6ghv+Ij5W2DrDx0qE+ZdEl2c6Ko1mgJNF5ftX1iEWQQ4Ap7+3GlhjkOA==" 973 "integrity": "sha512-o6/yDBYccGvTz1+QFevz6l6OBZ2+fMVu2JZ9CIhzsYRX4mjaK5IyX9eldUdCmga16zlgQxyrj5pt9kzuj2C02w=="
963 }, 974 },
964 "levn": { 975 "levn": {
965 "version": "0.3.0", 976 "version": "0.3.0",
@@ -1030,6 +1041,21 @@
1030 "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", 1041 "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
1031 "dev": true 1042 "dev": true
1032 }, 1043 },
1044 "mime-db": {
1045 "version": "1.43.0",
1046 "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.43.0.tgz",
1047 "integrity": "sha512-+5dsGEEovYbT8UY9yD7eE4XTc4UwJ1jBYlgaQQF38ENsKR3wj/8q8RFZrF9WIZpB2V1ArTVFUva8sAul1NzRzQ==",
1048 "dev": true
1049 },
1050 "mime-types": {
1051 "version": "2.1.26",
1052 "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.26.tgz",
1053 "integrity": "sha512-01paPWYgLrkqAyrlDorC1uDwl2p3qZT7yl806vW7DvDoxwXi46jsjFbg+WdwotBIk6/MbEhO/dh5aZ5sNj/dWQ==",
1054 "dev": true,
1055 "requires": {
1056 "mime-db": "1.43.0"
1057 }
1058 },
1033 "mimic-fn": { 1059 "mimic-fn": {
1034 "version": "2.1.0", 1060 "version": "2.1.0",
1035 "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", 1061 "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
@@ -1302,9 +1328,9 @@
1302 } 1328 }
1303 }, 1329 },
1304 "rollup": { 1330 "rollup": {
1305 "version": "1.31.1", 1331 "version": "1.32.0",
1306 "resolved": "https://registry.npmjs.org/rollup/-/rollup-1.31.1.tgz", 1332 "resolved": "https://registry.npmjs.org/rollup/-/rollup-1.32.0.tgz",
1307 "integrity": "sha512-2JREN1YdrS/kpPzEd33ZjtuNbOuBC3ePfuZBdKEybvqcEcszW1ckyVqzcEiEe0nE8sqHK+pbJg+PsAgRJ8+1dg==", 1333 "integrity": "sha512-ab2tF5pdDqm2zuI8j02ceyrJSScl9V2C24FgWQ1v1kTFTu1UrG5H0hpP++mDZlEFyZX4k0chtGEHU2i+pAzBgA==",
1308 "dev": true, 1334 "dev": true,
1309 "requires": { 1335 "requires": {
1310 "@types/estree": "*", 1336 "@types/estree": "*",
@@ -1527,11 +1553,20 @@
1527 } 1553 }
1528 }, 1554 },
1529 "tslib": { 1555 "tslib": {
1530 "version": "1.10.0", 1556 "version": "1.11.1",
1531 "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", 1557 "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.11.1.tgz",
1532 "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==", 1558 "integrity": "sha512-aZW88SY8kQbU7gpV19lN24LtXh/yD4ZZg6qieAJDDg+YBsJcSmLGK9QpnUjAKVG/xefmvJGd1WUmfpT/g6AJGA==",
1533 "dev": true 1559 "dev": true
1534 }, 1560 },
1561 "tsutils": {
1562 "version": "3.17.1",
1563 "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.17.1.tgz",
1564 "integrity": "sha512-kzeQ5B8H3w60nFY2g8cJIuH7JDpsALXySGtwGJ0p2LSjLgay3NdIpqq5SoOBe46bKDW2iq25irHCr8wjomUS2g==",
1565 "dev": true,
1566 "requires": {
1567 "tslib": "^1.8.1"
1568 }
1569 },
1535 "tunnel": { 1570 "tunnel": {
1536 "version": "0.0.4", 1571 "version": "0.0.4",
1537 "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.4.tgz", 1572 "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.4.tgz",
@@ -1564,9 +1599,9 @@
1564 } 1599 }
1565 }, 1600 },
1566 "typescript": { 1601 "typescript": {
1567 "version": "3.8.2", 1602 "version": "3.8.3",
1568 "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.8.2.tgz", 1603 "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.8.3.tgz",
1569 "integrity": "sha512-EgOVgL/4xfVrCMbhYKUQTdF37SQn4Iw73H5BgCrF1Abdun7Kwy/QZsE/ssAy0y4LxBbvua3PIbFsbRczWWnDdQ==", 1604 "integrity": "sha512-MYlEfn5VrLNsgudQTVJeNaQFUAI7DkhnOjdpAp4T+ku1TfQClewlbSuTVHiA+8skNBgaf02TL/kLOvig4y3G8w==",
1570 "dev": true 1605 "dev": true
1571 }, 1606 },
1572 "typescript-formatter": { 1607 "typescript-formatter": {
@@ -1619,9 +1654,9 @@
1619 "dev": true 1654 "dev": true
1620 }, 1655 },
1621 "vsce": { 1656 "vsce": {
1622 "version": "1.73.0", 1657 "version": "1.74.0",
1623 "resolved": "https://registry.npmjs.org/vsce/-/vsce-1.73.0.tgz", 1658 "resolved": "https://registry.npmjs.org/vsce/-/vsce-1.74.0.tgz",
1624 "integrity": "sha512-6W37Ebbkj3uF3WhT+SCfRtsneRQEFcGvf/XYz+b6OAgDCj4gPurWyDVrqw/HLsbP1WflGIyUfVZ8t5M7kQp6Uw==", 1659 "integrity": "sha512-8zWM9bZBNn9my40kkxAxdY4nhb9ADfazXsyDgx1thbRaLPbmPTlmqQ55vCAyWYFEi6XbJv8w599vzVUqsU1gHg==",
1625 "dev": true, 1660 "dev": true,
1626 "requires": { 1661 "requires": {
1627 "azure-devops-node-api": "^7.2.0", 1662 "azure-devops-node-api": "^7.2.0",
@@ -1631,7 +1666,7 @@
1631 "denodeify": "^1.2.1", 1666 "denodeify": "^1.2.1",
1632 "didyoumean": "^1.2.1", 1667 "didyoumean": "^1.2.1",
1633 "glob": "^7.0.6", 1668 "glob": "^7.0.6",
1634 "lodash": "^4.17.10", 1669 "lodash": "^4.17.15",
1635 "markdown-it": "^8.3.1", 1670 "markdown-it": "^8.3.1",
1636 "mime": "^1.3.4", 1671 "mime": "^1.3.4",
1637 "minimatch": "^3.0.3", 1672 "minimatch": "^3.0.3",
diff --git a/editors/code/package.json b/editors/code/package.json
index 862de3210..830358605 100644
--- a/editors/code/package.json
+++ b/editors/code/package.json
@@ -12,8 +12,13 @@
12 "url": "https://github.com/rust-analyzer/rust-analyzer.git", 12 "url": "https://github.com/rust-analyzer/rust-analyzer.git",
13 "type": "git" 13 "type": "git"
14 }, 14 },
15 "homepage": "https://rust-analyzer.github.io/",
16 "license": "MIT OR Apache-2.0",
17 "keywords": [
18 "rust"
19 ],
15 "categories": [ 20 "categories": [
16 "Other" 21 "Programming Languages"
17 ], 22 ],
18 "engines": { 23 "engines": {
19 "vscode": "^1.42.0" 24 "vscode": "^1.42.0"
@@ -27,24 +32,24 @@
27 "fix": " tsfmt -r && eslint -c .eslintrc.js --ext ts ./src --fix" 32 "fix": " tsfmt -r && eslint -c .eslintrc.js --ext ts ./src --fix"
28 }, 33 },
29 "dependencies": { 34 "dependencies": {
30 "jsonc-parser": "^2.1.0", 35 "jsonc-parser": "^2.2.1",
31 "node-fetch": "^2.6.0", 36 "node-fetch": "^2.6.0",
32 "vscode-languageclient": "^6.1.1" 37 "vscode-languageclient": "^6.1.1"
33 }, 38 },
34 "devDependencies": { 39 "devDependencies": {
35 "@rollup/plugin-commonjs": "^11.0.2", 40 "@rollup/plugin-commonjs": "^11.0.2",
36 "@rollup/plugin-node-resolve": "^7.1.1", 41 "@rollup/plugin-node-resolve": "^7.1.1",
37 "@types/node": "^12.12.27", 42 "@types/node": "^12.12.29",
38 "@types/node-fetch": "^2.5.4", 43 "@types/node-fetch": "^2.5.5",
39 "@types/vscode": "^1.42.0", 44 "@types/vscode": "^1.42.0",
40 "@typescript-eslint/eslint-plugin": "^2.20.0", 45 "@typescript-eslint/eslint-plugin": "^2.22.0",
41 "@typescript-eslint/parser": "^2.20.0", 46 "@typescript-eslint/parser": "^2.22.0",
42 "eslint": "^6.8.0", 47 "eslint": "^6.8.0",
43 "rollup": "^1.31.1", 48 "rollup": "^1.32.0",
44 "tslib": "^1.10.0", 49 "tslib": "^1.11.1",
45 "typescript": "^3.8.2", 50 "typescript": "^3.8.3",
46 "typescript-formatter": "^7.2.2", 51 "typescript-formatter": "^7.2.2",
47 "vsce": "^1.73.0" 52 "vsce": "^1.74.0"
48 }, 53 },
49 "activationEvents": [ 54 "activationEvents": [
50 "onLanguage:rust", 55 "onLanguage:rust",
diff --git a/editors/code/src/highlighting.ts b/editors/code/src/highlighting.ts
index 036183834..ea2dfc0e3 100644
--- a/editors/code/src/highlighting.ts
+++ b/editors/code/src/highlighting.ts
@@ -159,7 +159,9 @@ function initDecorations(): Map<string, vscode.TextEditorDecorationType> {
159 const theme = ColorTheme.load(); 159 const theme = ColorTheme.load();
160 const res = new Map(); 160 const res = new Map();
161 TAG_TO_SCOPES.forEach((scopes, tag) => { 161 TAG_TO_SCOPES.forEach((scopes, tag) => {
162 if (!scopes) throw `unmapped tag: ${tag}`; 162 // We are going to axe this soon, so don't try to detect unknown tags.
163 // Users should switch to the new semantic tokens implementation.
164 if (!scopes) return;
163 const rule = theme.lookup(scopes); 165 const rule = theme.lookup(scopes);
164 const decor = createDecorationFromTextmate(rule); 166 const decor = createDecorationFromTextmate(rule);
165 res.set(tag, decor); 167 res.set(tag, decor);
@@ -211,7 +213,7 @@ const TAG_TO_SCOPES = new Map<string, string[]>([
211 ["macro", ["entity.name.macro"]], 213 ["macro", ["entity.name.macro"]],
212 214
213 ["variable", ["variable"]], 215 ["variable", ["variable"]],
214 ["variable.mut", ["variable", "meta.mutable"]], 216 ["variable.mutable", ["variable", "meta.mutable"]],
215 217
216 ["type", ["entity.name.type"]], 218 ["type", ["entity.name.type"]],
217 ["type.builtin", ["entity.name.type", "support.type.primitive"]], 219 ["type.builtin", ["entity.name.type", "support.type.primitive"]],
@@ -221,10 +223,10 @@ const TAG_TO_SCOPES = new Map<string, string[]>([
221 223
222 ["literal.byte", ["constant.character.byte"]], 224 ["literal.byte", ["constant.character.byte"]],
223 ["literal.char", ["constant.character.rust"]], 225 ["literal.char", ["constant.character.rust"]],
224 ["literal.numeric", ["constant.numeric"]], 226 ["numeric_literal", ["constant.numeric"]],
225 227
226 ["comment", ["comment"]], 228 ["comment", ["comment"]],
227 ["string", ["string.quoted"]], 229 ["string_literal", ["string.quoted"]],
228 ["attribute", ["meta.attribute.rust"]], 230 ["attribute", ["meta.attribute.rust"]],
229 231
230 ["keyword", ["keyword"]], 232 ["keyword", ["keyword"]],
diff --git a/xtask/src/install.rs b/xtask/src/install.rs
index 1d13b26da..f76467cac 100644
--- a/xtask/src/install.rs
+++ b/xtask/src/install.rs
@@ -122,7 +122,8 @@ fn install_client(ClientOpt::VsCode: ClientOpt) -> Result<()> {
122 if !installed_extensions.contains("rust-analyzer") { 122 if !installed_extensions.contains("rust-analyzer") {
123 bail!( 123 bail!(
124 "Could not install the Visual Studio Code extension. \ 124 "Could not install the Visual Studio Code extension. \
125 Please make sure you have at least NodeJS 12.x together with the latest version of VS Code installed and try again." 125 Please make sure you have at least NodeJS 12.x together with the latest version of VS Code installed and try again. \
126 Note that installing via xtask install does not work for VS Code Remote, instead you’ll need to install the .vsix manually."
126 ); 127 );
127 } 128 }
128 129
diff --git a/xtask/src/lib.rs b/xtask/src/lib.rs
index e5da726ac..f48045d17 100644
--- a/xtask/src/lib.rs
+++ b/xtask/src/lib.rs
@@ -139,12 +139,15 @@ pub fn run_pre_cache() -> Result<()> {
139 } 139 }
140 140
141 fs2::remove_file("./target/.rustc_info.json")?; 141 fs2::remove_file("./target/.rustc_info.json")?;
142 let to_delete = ["ra_", "heavy_test"]; 142 let to_delete = ["ra_", "heavy_test", "xtask"];
143 for &dir in ["./target/debug/deps", "target/debug/.fingerprint"].iter() { 143 for &dir in ["./target/debug/deps", "target/debug/.fingerprint"].iter() {
144 for entry in Path::new(dir).read_dir()? { 144 for entry in Path::new(dir).read_dir()? {
145 let entry = entry?; 145 let entry = entry?;
146 if to_delete.iter().any(|&it| entry.path().display().to_string().contains(it)) { 146 if to_delete.iter().any(|&it| entry.path().display().to_string().contains(it)) {
147 rm_rf(&entry.path())? 147 // Can't delete yourself on windows :-(
148 if !entry.path().ends_with("xtask.exe") {
149 rm_rf(&entry.path())?
150 }
148 } 151 }
149 } 152 }
150 } 153 }
@@ -192,5 +195,14 @@ Release: release:{}[]
192 195
193 fs2::copy(project_root().join("./docs/user/readme.adoc"), website_root.join("manual.adoc"))?; 196 fs2::copy(project_root().join("./docs/user/readme.adoc"), website_root.join("manual.adoc"))?;
194 197
198 let tags = run!("git tag --list"; echo = false)?;
199 let prev_tag = tags.lines().filter(|line| is_release_tag(line)).last().unwrap();
200
201 println!("\n git log {}..HEAD --merges --reverse", prev_tag);
202
195 Ok(()) 203 Ok(())
196} 204}
205
206fn is_release_tag(tag: &str) -> bool {
207 tag.len() == "2020-02-24".len() && tag.starts_with(|c: char| c.is_ascii_digit())
208}