aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock56
-rw-r--r--crates/assists/src/handlers/add_lifetime_to_type.rs10
-rw-r--r--crates/assists/src/handlers/generate_derive.rs4
-rw-r--r--crates/assists/src/handlers/generate_enum_match_method.rs2
-rw-r--r--crates/assists/src/handlers/generate_impl.rs2
-rw-r--r--crates/assists/src/handlers/generate_new.rs2
-rw-r--r--crates/assists/src/utils.rs8
-rw-r--r--crates/completion/src/completions/keyword.rs8
-rw-r--r--crates/hir_ty/Cargo.toml6
-rw-r--r--crates/hir_ty/src/traits/chalk/interner.rs5
-rw-r--r--crates/ide/src/goto_implementation.rs10
-rw-r--r--crates/rust-analyzer/src/cli/analysis_bench.rs14
-rw-r--r--crates/rust-analyzer/src/cli/analysis_stats.rs13
-rw-r--r--crates/rust-analyzer/src/cli/diagnostics.rs18
-rw-r--r--crates/rust-analyzer/src/cli/load_cargo.rs26
-rw-r--r--crates/rust-analyzer/src/cli/ssr.rs19
-rw-r--r--crates/rust-analyzer/src/semantic_tokens.rs1
-rw-r--r--crates/rust-analyzer/src/to_proto.rs3
-rw-r--r--crates/syntax/Cargo.toml2
-rw-r--r--crates/syntax/src/ast/generated/nodes.rs38
-rw-r--r--docs/dev/architecture.md28
-rw-r--r--docs/user/manual.adoc90
22 files changed, 265 insertions, 100 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 1ceae965f..f958bcbf3 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -178,9 +178,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
178 178
179[[package]] 179[[package]]
180name = "chalk-derive" 180name = "chalk-derive"
181version = "0.55.0" 181version = "0.56.0"
182source = "registry+https://github.com/rust-lang/crates.io-index" 182source = "registry+https://github.com/rust-lang/crates.io-index"
183checksum = "3983193cacd81f0f924acb666b7fe5e1a0d81db9f113fa69203eda7ea8ce8b6c" 183checksum = "51f6c7a4b1a119cff6c5a17cf68056069dece7bc525c2a2e26e1117e27f48ca2"
184dependencies = [ 184dependencies = [
185 "proc-macro2", 185 "proc-macro2",
186 "quote", 186 "quote",
@@ -190,9 +190,9 @@ dependencies = [
190 190
191[[package]] 191[[package]]
192name = "chalk-ir" 192name = "chalk-ir"
193version = "0.55.0" 193version = "0.56.0"
194source = "registry+https://github.com/rust-lang/crates.io-index" 194source = "registry+https://github.com/rust-lang/crates.io-index"
195checksum = "a522f53af971e7678f472d687e053120157b3ae26e2ebd5ecbc0f5ab124f2cb6" 195checksum = "7d5f524bc3a5798fe3711c360fde350bffb938b52ef7b302d637550229995e20"
196dependencies = [ 196dependencies = [
197 "bitflags", 197 "bitflags",
198 "chalk-derive", 198 "chalk-derive",
@@ -201,9 +201,9 @@ dependencies = [
201 201
202[[package]] 202[[package]]
203name = "chalk-recursive" 203name = "chalk-recursive"
204version = "0.55.0" 204version = "0.56.0"
205source = "registry+https://github.com/rust-lang/crates.io-index" 205source = "registry+https://github.com/rust-lang/crates.io-index"
206checksum = "8b0a6bc94f16aaba1dd6d1e2350945bbb0239c3633cdabeedbed601c1354d4b4" 206checksum = "f7c0525fb9c43f8f1d7ba4fb42f9ada2a2415901a04b5c655cfe11e559085d4d"
207dependencies = [ 207dependencies = [
208 "chalk-derive", 208 "chalk-derive",
209 "chalk-ir", 209 "chalk-ir",
@@ -214,9 +214,9 @@ dependencies = [
214 214
215[[package]] 215[[package]]
216name = "chalk-solve" 216name = "chalk-solve"
217version = "0.55.0" 217version = "0.56.0"
218source = "registry+https://github.com/rust-lang/crates.io-index" 218source = "registry+https://github.com/rust-lang/crates.io-index"
219checksum = "cdf79fb77a567e456a170f7ec84ea6584163d4ba3f13660cd182013d34ca667c" 219checksum = "3c2e7b54add0f18d5ee7bb043a3108b819e60b1b409d214291bcdc97927cdc32"
220dependencies = [ 220dependencies = [
221 "chalk-derive", 221 "chalk-derive",
222 "chalk-ir", 222 "chalk-ir",
@@ -663,9 +663,9 @@ dependencies = [
663 663
664[[package]] 664[[package]]
665name = "idna" 665name = "idna"
666version = "0.2.0" 666version = "0.2.1"
667source = "registry+https://github.com/rust-lang/crates.io-index" 667source = "registry+https://github.com/rust-lang/crates.io-index"
668checksum = "02e2673c30ee86b5b96a9cb52ad15718aa1f966f5ab9ad54a8b95d5ca33120a9" 668checksum = "de910d521f7cc3135c4de8db1cb910e0b5ed1dc6f57c381cd07e8e661ce10094"
669dependencies = [ 669dependencies = [
670 "matches", 670 "matches",
671 "unicode-bidi", 671 "unicode-bidi",
@@ -785,9 +785,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
785 785
786[[package]] 786[[package]]
787name = "libc" 787name = "libc"
788version = "0.2.85" 788version = "0.2.86"
789source = "registry+https://github.com/rust-lang/crates.io-index" 789source = "registry+https://github.com/rust-lang/crates.io-index"
790checksum = "7ccac4b00700875e6a07c6cde370d44d32fa01c5a65cdd2fca6858c479d28bb3" 790checksum = "b7282d924be3275cec7f6756ff4121987bc6481325397dde6ba3e7802b1a8b1c"
791 791
792[[package]] 792[[package]]
793name = "libloading" 793name = "libloading"
@@ -801,9 +801,9 @@ dependencies = [
801 801
802[[package]] 802[[package]]
803name = "libmimalloc-sys" 803name = "libmimalloc-sys"
804version = "0.1.19" 804version = "0.1.20"
805source = "registry+https://github.com/rust-lang/crates.io-index" 805source = "registry+https://github.com/rust-lang/crates.io-index"
806checksum = "4782d78362f319e7568577c015dc0cb9c6d0fe43be120018a54ac4c6dd89888a" 806checksum = "e58f42b6424a0ed536678c65fd97cd64b4344bcf86251e284f7c0ce9eee40e64"
807dependencies = [ 807dependencies = [
808 "cmake", 808 "cmake",
809] 809]
@@ -888,9 +888,9 @@ checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525"
888 888
889[[package]] 889[[package]]
890name = "memmap2" 890name = "memmap2"
891version = "0.2.0" 891version = "0.2.1"
892source = "registry+https://github.com/rust-lang/crates.io-index" 892source = "registry+https://github.com/rust-lang/crates.io-index"
893checksum = "e73be3b7d04a0123e933fea1d50d126cc7196bbc0362c0ce426694f777194eee" 893checksum = "04e3e85b970d650e2ae6d70592474087051c11c54da7f7b4949725c5735fbcc6"
894dependencies = [ 894dependencies = [
895 "libc", 895 "libc",
896] 896]
@@ -906,9 +906,9 @@ dependencies = [
906 906
907[[package]] 907[[package]]
908name = "mimalloc" 908name = "mimalloc"
909version = "0.1.23" 909version = "0.1.24"
910source = "registry+https://github.com/rust-lang/crates.io-index" 910source = "registry+https://github.com/rust-lang/crates.io-index"
911checksum = "7857c87270957ce1d20aea0f39b383551518986b6e480a0291e3b8ec5f9ab158" 911checksum = "757efec188b3d2088949d912e01ea2fe87164ed6376b6c5d7dd4f3ce1668a93d"
912dependencies = [ 912dependencies = [
913 "libmimalloc-sys", 913 "libmimalloc-sys",
914] 914]
@@ -1377,9 +1377,9 @@ dependencies = [
1377 1377
1378[[package]] 1378[[package]]
1379name = "rustc-ap-rustc_lexer" 1379name = "rustc-ap-rustc_lexer"
1380version = "702.0.0" 1380version = "705.0.0"
1381source = "registry+https://github.com/rust-lang/crates.io-index" 1381source = "registry+https://github.com/rust-lang/crates.io-index"
1382checksum = "47cfdb02425aed8c56f85692975d262cb438ea0388e0c8cd254e73bd22bb6539" 1382checksum = "3a030d00510966cd31e13dca5e6c1bd40d303a932c54eca40e854188bca8c49e"
1383dependencies = [ 1383dependencies = [
1384 "unicode-xid", 1384 "unicode-xid",
1385] 1385]
@@ -1493,9 +1493,9 @@ dependencies = [
1493 1493
1494[[package]] 1494[[package]]
1495name = "serde_json" 1495name = "serde_json"
1496version = "1.0.61" 1496version = "1.0.62"
1497source = "registry+https://github.com/rust-lang/crates.io-index" 1497source = "registry+https://github.com/rust-lang/crates.io-index"
1498checksum = "4fceb2595057b6891a4ee808f70054bd2d12f0e97f1cbb78689b59f676df325a" 1498checksum = "ea1c6153794552ea7cf7cf63b1231a25de00ec90db326ba6264440fa08e31486"
1499dependencies = [ 1499dependencies = [
1500 "indexmap", 1500 "indexmap",
1501 "itoa", 1501 "itoa",
@@ -1712,9 +1712,9 @@ dependencies = [
1712 1712
1713[[package]] 1713[[package]]
1714name = "tracing" 1714name = "tracing"
1715version = "0.1.22" 1715version = "0.1.23"
1716source = "registry+https://github.com/rust-lang/crates.io-index" 1716source = "registry+https://github.com/rust-lang/crates.io-index"
1717checksum = "9f47026cdc4080c07e49b37087de021820269d996f581aac150ef9e5583eefe3" 1717checksum = "f7d40a22fd029e33300d8d89a5cc8ffce18bb7c587662f54629e94c9de5487f3"
1718dependencies = [ 1718dependencies = [
1719 "cfg-if", 1719 "cfg-if",
1720 "pin-project-lite", 1720 "pin-project-lite",
@@ -1724,9 +1724,9 @@ dependencies = [
1724 1724
1725[[package]] 1725[[package]]
1726name = "tracing-attributes" 1726name = "tracing-attributes"
1727version = "0.1.11" 1727version = "0.1.12"
1728source = "registry+https://github.com/rust-lang/crates.io-index" 1728source = "registry+https://github.com/rust-lang/crates.io-index"
1729checksum = "80e0ccfc3378da0cce270c946b676a376943f5cd16aeba64568e7939806f4ada" 1729checksum = "43f080ea7e4107844ef4766459426fa2d5c1ada2e47edba05dc7fa99d9629f47"
1730dependencies = [ 1730dependencies = [
1731 "proc-macro2", 1731 "proc-macro2",
1732 "quote", 1732 "quote",
@@ -1816,9 +1816,9 @@ checksum = "56dee185309b50d1f11bfedef0fe6d036842e3fb77413abef29f8f8d1c5d4c1c"
1816 1816
1817[[package]] 1817[[package]]
1818name = "ungrammar" 1818name = "ungrammar"
1819version = "1.10.0" 1819version = "1.11.0"
1820source = "registry+https://github.com/rust-lang/crates.io-index" 1820source = "registry+https://github.com/rust-lang/crates.io-index"
1821checksum = "ce24866975a8858d3a35eba845efc6b42962c5067afd2bc1a07b9ce0108d335c" 1821checksum = "84c629795d377049f2a1dc5f42cf505dc5ba8b28a5df0a03f4183a24480e4a6a"
1822 1822
1823[[package]] 1823[[package]]
1824name = "unicase" 1824name = "unicase"
diff --git a/crates/assists/src/handlers/add_lifetime_to_type.rs b/crates/assists/src/handlers/add_lifetime_to_type.rs
index c1603e972..2edf7b204 100644
--- a/crates/assists/src/handlers/add_lifetime_to_type.rs
+++ b/crates/assists/src/handlers/add_lifetime_to_type.rs
@@ -26,7 +26,7 @@ pub(crate) fn add_lifetime_to_type(acc: &mut Assists, ctx: &AssistContext) -> Op
26 return None; 26 return None;
27 } 27 }
28 28
29 let node = ctx.find_node_at_offset::<ast::AdtDef>()?; 29 let node = ctx.find_node_at_offset::<ast::Adt>()?;
30 let has_lifetime = node 30 let has_lifetime = node
31 .generic_param_list() 31 .generic_param_list()
32 .map(|gen_list| gen_list.lifetime_params().count() > 0) 32 .map(|gen_list| gen_list.lifetime_params().count() > 0)
@@ -66,9 +66,9 @@ pub(crate) fn add_lifetime_to_type(acc: &mut Assists, ctx: &AssistContext) -> Op
66 ) 66 )
67} 67}
68 68
69fn fetch_borrowed_types(node: &ast::AdtDef) -> Option<Vec<RefType>> { 69fn fetch_borrowed_types(node: &ast::Adt) -> Option<Vec<RefType>> {
70 let ref_types: Vec<RefType> = match node { 70 let ref_types: Vec<RefType> = match node {
71 ast::AdtDef::Enum(enum_) => { 71 ast::Adt::Enum(enum_) => {
72 let variant_list = enum_.variant_list()?; 72 let variant_list = enum_.variant_list()?;
73 variant_list 73 variant_list
74 .variants() 74 .variants()
@@ -80,11 +80,11 @@ fn fetch_borrowed_types(node: &ast::AdtDef) -> Option<Vec<RefType>> {
80 .flatten() 80 .flatten()
81 .collect() 81 .collect()
82 } 82 }
83 ast::AdtDef::Struct(strukt) => { 83 ast::Adt::Struct(strukt) => {
84 let field_list = strukt.field_list()?; 84 let field_list = strukt.field_list()?;
85 find_ref_types_from_field_list(&field_list)? 85 find_ref_types_from_field_list(&field_list)?
86 } 86 }
87 ast::AdtDef::Union(un) => { 87 ast::Adt::Union(un) => {
88 let record_field_list = un.record_field_list()?; 88 let record_field_list = un.record_field_list()?;
89 record_field_list 89 record_field_list
90 .fields() 90 .fields()
diff --git a/crates/assists/src/handlers/generate_derive.rs b/crates/assists/src/handlers/generate_derive.rs
index f876b7684..adae8ab7e 100644
--- a/crates/assists/src/handlers/generate_derive.rs
+++ b/crates/assists/src/handlers/generate_derive.rs
@@ -26,7 +26,7 @@ use crate::{AssistContext, AssistId, AssistKind, Assists};
26// ``` 26// ```
27pub(crate) fn generate_derive(acc: &mut Assists, ctx: &AssistContext) -> Option<()> { 27pub(crate) fn generate_derive(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
28 let cap = ctx.config.snippet_cap?; 28 let cap = ctx.config.snippet_cap?;
29 let nominal = ctx.find_node_at_offset::<ast::AdtDef>()?; 29 let nominal = ctx.find_node_at_offset::<ast::Adt>()?;
30 let node_start = derive_insertion_offset(&nominal)?; 30 let node_start = derive_insertion_offset(&nominal)?;
31 let target = nominal.syntax().text_range(); 31 let target = nominal.syntax().text_range();
32 acc.add( 32 acc.add(
@@ -58,7 +58,7 @@ pub(crate) fn generate_derive(acc: &mut Assists, ctx: &AssistContext) -> Option<
58} 58}
59 59
60// Insert `derive` after doc comments. 60// Insert `derive` after doc comments.
61fn derive_insertion_offset(nominal: &ast::AdtDef) -> Option<TextSize> { 61fn derive_insertion_offset(nominal: &ast::Adt) -> Option<TextSize> {
62 let non_ws_child = nominal 62 let non_ws_child = nominal
63 .syntax() 63 .syntax()
64 .children_with_tokens() 64 .children_with_tokens()
diff --git a/crates/assists/src/handlers/generate_enum_match_method.rs b/crates/assists/src/handlers/generate_enum_match_method.rs
index 4cf66b5d5..9d6b161c9 100644
--- a/crates/assists/src/handlers/generate_enum_match_method.rs
+++ b/crates/assists/src/handlers/generate_enum_match_method.rs
@@ -49,7 +49,7 @@ pub(crate) fn generate_enum_match_method(acc: &mut Assists, ctx: &AssistContext)
49 // Return early if we've found an existing new fn 49 // Return early if we've found an existing new fn
50 let impl_def = find_struct_impl( 50 let impl_def = find_struct_impl(
51 &ctx, 51 &ctx,
52 &ast::AdtDef::Enum(parent_enum.clone()), 52 &ast::Adt::Enum(parent_enum.clone()),
53 format!("is_{}", fn_name).as_str(), 53 format!("is_{}", fn_name).as_str(),
54 )?; 54 )?;
55 55
diff --git a/crates/assists/src/handlers/generate_impl.rs b/crates/assists/src/handlers/generate_impl.rs
index 827477272..61d1bd25c 100644
--- a/crates/assists/src/handlers/generate_impl.rs
+++ b/crates/assists/src/handlers/generate_impl.rs
@@ -27,7 +27,7 @@ use crate::{AssistContext, AssistId, AssistKind, Assists};
27// } 27// }
28// ``` 28// ```
29pub(crate) fn generate_impl(acc: &mut Assists, ctx: &AssistContext) -> Option<()> { 29pub(crate) fn generate_impl(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
30 let nominal = ctx.find_node_at_offset::<ast::AdtDef>()?; 30 let nominal = ctx.find_node_at_offset::<ast::Adt>()?;
31 let name = nominal.name()?; 31 let name = nominal.name()?;
32 let target = nominal.syntax().text_range(); 32 let target = nominal.syntax().text_range();
33 33
diff --git a/crates/assists/src/handlers/generate_new.rs b/crates/assists/src/handlers/generate_new.rs
index 307f2e228..a9203d33f 100644
--- a/crates/assists/src/handlers/generate_new.rs
+++ b/crates/assists/src/handlers/generate_new.rs
@@ -40,7 +40,7 @@ pub(crate) fn generate_new(acc: &mut Assists, ctx: &AssistContext) -> Option<()>
40 }; 40 };
41 41
42 // Return early if we've found an existing new fn 42 // Return early if we've found an existing new fn
43 let impl_def = find_struct_impl(&ctx, &ast::AdtDef::Struct(strukt.clone()), "new")?; 43 let impl_def = find_struct_impl(&ctx, &ast::Adt::Struct(strukt.clone()), "new")?;
44 44
45 let target = strukt.syntax().text_range(); 45 let target = strukt.syntax().text_range();
46 acc.add(AssistId("generate_new", AssistKind::Generate), "Generate `new`", target, |builder| { 46 acc.add(AssistId("generate_new", AssistKind::Generate), "Generate `new`", target, |builder| {
diff --git a/crates/assists/src/utils.rs b/crates/assists/src/utils.rs
index 8045aac40..cd80c2958 100644
--- a/crates/assists/src/utils.rs
+++ b/crates/assists/src/utils.rs
@@ -281,7 +281,7 @@ pub(crate) fn does_pat_match_variant(pat: &ast::Pat, var: &ast::Pat) -> bool {
281// FIXME: this partially overlaps with `find_impl_block` 281// FIXME: this partially overlaps with `find_impl_block`
282pub(crate) fn find_struct_impl( 282pub(crate) fn find_struct_impl(
283 ctx: &AssistContext, 283 ctx: &AssistContext,
284 strukt: &ast::AdtDef, 284 strukt: &ast::Adt,
285 name: &str, 285 name: &str,
286) -> Option<Option<ast::Impl>> { 286) -> Option<Option<ast::Impl>> {
287 let db = ctx.db(); 287 let db = ctx.db();
@@ -290,9 +290,9 @@ pub(crate) fn find_struct_impl(
290 })?; 290 })?;
291 291
292 let struct_def = match strukt { 292 let struct_def = match strukt {
293 ast::AdtDef::Enum(e) => Adt::Enum(ctx.sema.to_def(e)?), 293 ast::Adt::Enum(e) => Adt::Enum(ctx.sema.to_def(e)?),
294 ast::AdtDef::Struct(s) => Adt::Struct(ctx.sema.to_def(s)?), 294 ast::Adt::Struct(s) => Adt::Struct(ctx.sema.to_def(s)?),
295 ast::AdtDef::Union(u) => Adt::Union(ctx.sema.to_def(u)?), 295 ast::Adt::Union(u) => Adt::Union(ctx.sema.to_def(u)?),
296 }; 296 };
297 297
298 let block = module.descendants().filter_map(ast::Impl::cast).find_map(|impl_blk| { 298 let block = module.descendants().filter_map(ast::Impl::cast).find_map(|impl_blk| {
diff --git a/crates/completion/src/completions/keyword.rs b/crates/completion/src/completions/keyword.rs
index 47e146128..eb81f9765 100644
--- a/crates/completion/src/completions/keyword.rs
+++ b/crates/completion/src/completions/keyword.rs
@@ -88,6 +88,7 @@ pub(crate) fn complete_expr_keyword(acc: &mut Completions, ctx: &CompletionConte
88 add_keyword(ctx, acc, "loop", "loop {$0}"); 88 add_keyword(ctx, acc, "loop", "loop {$0}");
89 add_keyword(ctx, acc, "if", "if $0 {}"); 89 add_keyword(ctx, acc, "if", "if $0 {}");
90 add_keyword(ctx, acc, "if let", "if let $1 = $0 {}"); 90 add_keyword(ctx, acc, "if let", "if let $1 = $0 {}");
91 add_keyword(ctx, acc, "for", "for $1 in $0 {}");
91 } 92 }
92 93
93 if ctx.if_is_prev || ctx.block_expr_parent { 94 if ctx.if_is_prev || ctx.block_expr_parent {
@@ -258,6 +259,7 @@ mod tests {
258 kw loop 259 kw loop
259 kw if 260 kw if
260 kw if let 261 kw if let
262 kw for
261 kw let 263 kw let
262 kw mod 264 kw mod
263 kw const 265 kw const
@@ -284,6 +286,7 @@ mod tests {
284 kw loop 286 kw loop
285 kw if 287 kw if
286 kw if let 288 kw if let
289 kw for
287 kw let 290 kw let
288 kw mod 291 kw mod
289 kw const 292 kw const
@@ -310,6 +313,7 @@ mod tests {
310 kw loop 313 kw loop
311 kw if 314 kw if
312 kw if let 315 kw if let
316 kw for
313 kw let 317 kw let
314 kw else 318 kw else
315 kw else if 319 kw else if
@@ -343,6 +347,7 @@ fn quux() -> i32 {
343 kw loop 347 kw loop
344 kw if 348 kw if
345 kw if let 349 kw if let
350 kw for
346 kw unsafe 351 kw unsafe
347 kw return 352 kw return
348 "#]], 353 "#]],
@@ -391,6 +396,7 @@ fn quux() -> i32 {
391 kw loop 396 kw loop
392 kw if 397 kw if
393 kw if let 398 kw if let
399 kw for
394 kw let 400 kw let
395 kw mod 401 kw mod
396 kw const 402 kw const
@@ -549,6 +555,7 @@ pub mod future {
549 kw loop 555 kw loop
550 kw if 556 kw if
551 kw if let 557 kw if let
558 kw for
552 kw return 559 kw return
553 "#]], 560 "#]],
554 ) 561 )
@@ -607,6 +614,7 @@ fn foo() {
607 kw loop 614 kw loop
608 kw if 615 kw if
609 kw if let 616 kw if let
617 kw for
610 kw return 618 kw return
611 "#]], 619 "#]],
612 ); 620 );
diff --git a/crates/hir_ty/Cargo.toml b/crates/hir_ty/Cargo.toml
index f6bf49546..418ac8cbb 100644
--- a/crates/hir_ty/Cargo.toml
+++ b/crates/hir_ty/Cargo.toml
@@ -17,9 +17,9 @@ ena = "0.14.0"
17log = "0.4.8" 17log = "0.4.8"
18rustc-hash = "1.1.0" 18rustc-hash = "1.1.0"
19scoped-tls = "1" 19scoped-tls = "1"
20chalk-solve = { version = "0.55", default-features = false } 20chalk-solve = { version = "0.56", default-features = false }
21chalk-ir = "0.55" 21chalk-ir = "0.56"
22chalk-recursive = "0.55" 22chalk-recursive = "0.56"
23la-arena = { version = "0.2.0", path = "../../lib/arena" } 23la-arena = { version = "0.2.0", path = "../../lib/arena" }
24 24
25stdx = { path = "../stdx", version = "0.0.0" } 25stdx = { path = "../stdx", version = "0.0.0" }
diff --git a/crates/hir_ty/src/traits/chalk/interner.rs b/crates/hir_ty/src/traits/chalk/interner.rs
index 6a4aa8333..54bd1c724 100644
--- a/crates/hir_ty/src/traits/chalk/interner.rs
+++ b/crates/hir_ty/src/traits/chalk/interner.rs
@@ -193,8 +193,9 @@ impl chalk_ir::interner::Interner for Interner {
193 tls::with_current_program(|prog| Some(prog?.debug_quantified_where_clauses(clauses, fmt))) 193 tls::with_current_program(|prog| Some(prog?.debug_quantified_where_clauses(clauses, fmt)))
194 } 194 }
195 195
196 fn intern_ty(&self, ty: chalk_ir::TyData<Self>) -> Arc<chalk_ir::TyData<Self>> { 196 fn intern_ty(&self, kind: chalk_ir::TyKind<Self>) -> Arc<chalk_ir::TyData<Self>> {
197 Arc::new(ty) 197 let flags = kind.compute_flags(self);
198 Arc::new(chalk_ir::TyData { kind, flags })
198 } 199 }
199 200
200 fn ty_data<'a>(&self, ty: &'a Arc<chalk_ir::TyData<Self>>) -> &'a chalk_ir::TyData<Self> { 201 fn ty_data<'a>(&self, ty: &'a Arc<chalk_ir::TyData<Self>>) -> &'a chalk_ir::TyData<Self> {
diff --git a/crates/ide/src/goto_implementation.rs b/crates/ide/src/goto_implementation.rs
index 761a98b2c..3990305fc 100644
--- a/crates/ide/src/goto_implementation.rs
+++ b/crates/ide/src/goto_implementation.rs
@@ -23,7 +23,7 @@ pub(crate) fn goto_implementation(
23 23
24 let krate = sema.to_module_def(position.file_id)?.krate(); 24 let krate = sema.to_module_def(position.file_id)?.krate();
25 25
26 if let Some(nominal_def) = find_node_at_offset::<ast::AdtDef>(&syntax, position.offset) { 26 if let Some(nominal_def) = find_node_at_offset::<ast::Adt>(&syntax, position.offset) {
27 return Some(RangeInfo::new( 27 return Some(RangeInfo::new(
28 nominal_def.syntax().text_range(), 28 nominal_def.syntax().text_range(),
29 impls_for_def(&sema, &nominal_def, krate)?, 29 impls_for_def(&sema, &nominal_def, krate)?,
@@ -40,13 +40,13 @@ pub(crate) fn goto_implementation(
40 40
41fn impls_for_def( 41fn impls_for_def(
42 sema: &Semantics<RootDatabase>, 42 sema: &Semantics<RootDatabase>,
43 node: &ast::AdtDef, 43 node: &ast::Adt,
44 krate: Crate, 44 krate: Crate,
45) -> Option<Vec<NavigationTarget>> { 45) -> Option<Vec<NavigationTarget>> {
46 let ty = match node { 46 let ty = match node {
47 ast::AdtDef::Struct(def) => sema.to_def(def)?.ty(sema.db), 47 ast::Adt::Struct(def) => sema.to_def(def)?.ty(sema.db),
48 ast::AdtDef::Enum(def) => sema.to_def(def)?.ty(sema.db), 48 ast::Adt::Enum(def) => sema.to_def(def)?.ty(sema.db),
49 ast::AdtDef::Union(def) => sema.to_def(def)?.ty(sema.db), 49 ast::Adt::Union(def) => sema.to_def(def)?.ty(sema.db),
50 }; 50 };
51 51
52 let impls = Impl::all_in_crate(sema.db, krate); 52 let impls = Impl::all_in_crate(sema.db, krate);
diff --git a/crates/rust-analyzer/src/cli/analysis_bench.rs b/crates/rust-analyzer/src/cli/analysis_bench.rs
index a01b49822..6735b6388 100644
--- a/crates/rust-analyzer/src/cli/analysis_bench.rs
+++ b/crates/rust-analyzer/src/cli/analysis_bench.rs
@@ -16,7 +16,10 @@ use ide_db::{
16}; 16};
17use vfs::AbsPathBuf; 17use vfs::AbsPathBuf;
18 18
19use crate::cli::{load_cargo::load_cargo, print_memory_usage, Verbosity}; 19use crate::cli::{
20 load_cargo::{load_cargo, LoadCargoConfig},
21 print_memory_usage, Verbosity,
22};
20 23
21pub struct BenchCmd { 24pub struct BenchCmd {
22 pub path: PathBuf, 25 pub path: PathBuf,
@@ -59,7 +62,14 @@ impl BenchCmd {
59 62
60 let start = Instant::now(); 63 let start = Instant::now();
61 eprint!("loading: "); 64 eprint!("loading: ");
62 let (mut host, vfs) = load_cargo(&self.path, self.load_output_dirs, self.with_proc_macro)?; 65
66 let load_cargo_config = LoadCargoConfig {
67 cargo_config: Default::default(),
68 load_out_dirs_from_check: self.load_output_dirs,
69 with_proc_macro: self.with_proc_macro,
70 };
71
72 let (mut host, vfs) = load_cargo(&self.path, &load_cargo_config)?;
63 eprintln!("{:?}\n", start.elapsed()); 73 eprintln!("{:?}\n", start.elapsed());
64 74
65 let file_id = { 75 let file_id = {
diff --git a/crates/rust-analyzer/src/cli/analysis_stats.rs b/crates/rust-analyzer/src/cli/analysis_stats.rs
index 66416f709..3417af687 100644
--- a/crates/rust-analyzer/src/cli/analysis_stats.rs
+++ b/crates/rust-analyzer/src/cli/analysis_stats.rs
@@ -25,8 +25,10 @@ use stdx::format_to;
25use syntax::AstNode; 25use syntax::AstNode;
26 26
27use crate::cli::{ 27use crate::cli::{
28 load_cargo::load_cargo, print_memory_usage, progress_report::ProgressReport, report_metric, 28 load_cargo::{load_cargo, LoadCargoConfig},
29 Result, Verbosity, 29 print_memory_usage,
30 progress_report::ProgressReport,
31 report_metric, Result, Verbosity,
30}; 32};
31use profile::StopWatch; 33use profile::StopWatch;
32 34
@@ -57,7 +59,12 @@ impl AnalysisStatsCmd {
57 }; 59 };
58 60
59 let mut db_load_sw = self.stop_watch(); 61 let mut db_load_sw = self.stop_watch();
60 let (host, vfs) = load_cargo(&self.path, self.load_output_dirs, self.with_proc_macro)?; 62 let load_cargo_config = LoadCargoConfig {
63 cargo_config: Default::default(),
64 load_out_dirs_from_check: self.load_output_dirs,
65 with_proc_macro: self.with_proc_macro,
66 };
67 let (host, vfs) = load_cargo(&self.path, &load_cargo_config)?;
61 let db = host.raw_database(); 68 let db = host.raw_database();
62 eprintln!("{:<20} {}", "Database loaded:", db_load_sw.elapsed()); 69 eprintln!("{:<20} {}", "Database loaded:", db_load_sw.elapsed());
63 70
diff --git a/crates/rust-analyzer/src/cli/diagnostics.rs b/crates/rust-analyzer/src/cli/diagnostics.rs
index 0090fd2c2..c60374c24 100644
--- a/crates/rust-analyzer/src/cli/diagnostics.rs
+++ b/crates/rust-analyzer/src/cli/diagnostics.rs
@@ -10,7 +10,10 @@ use hir::{db::HirDatabase, Crate, Module};
10use ide::{DiagnosticsConfig, Severity}; 10use ide::{DiagnosticsConfig, Severity};
11use ide_db::base_db::SourceDatabaseExt; 11use ide_db::base_db::SourceDatabaseExt;
12 12
13use crate::cli::{load_cargo::load_cargo, Result}; 13use crate::cli::{
14 load_cargo::{load_cargo, LoadCargoConfig},
15 Result,
16};
14 17
15fn all_modules(db: &dyn HirDatabase) -> Vec<Module> { 18fn all_modules(db: &dyn HirDatabase) -> Vec<Module> {
16 let mut worklist: Vec<_> = 19 let mut worklist: Vec<_> =
@@ -25,8 +28,17 @@ fn all_modules(db: &dyn HirDatabase) -> Vec<Module> {
25 modules 28 modules
26} 29}
27 30
28pub fn diagnostics(path: &Path, load_output_dirs: bool, with_proc_macro: bool) -> Result<()> { 31pub fn diagnostics(
29 let (host, _vfs) = load_cargo(path, load_output_dirs, with_proc_macro)?; 32 path: &Path,
33 load_out_dirs_from_check: bool,
34 with_proc_macro: bool,
35) -> Result<()> {
36 let load_cargo_config = LoadCargoConfig {
37 cargo_config: Default::default(),
38 load_out_dirs_from_check,
39 with_proc_macro,
40 };
41 let (host, _vfs) = load_cargo(path, &load_cargo_config)?;
30 let db = host.raw_database(); 42 let db = host.raw_database();
31 let analysis = host.analysis(); 43 let analysis = host.analysis();
32 44
diff --git a/crates/rust-analyzer/src/cli/load_cargo.rs b/crates/rust-analyzer/src/cli/load_cargo.rs
index e12e87180..cc63c6cc2 100644
--- a/crates/rust-analyzer/src/cli/load_cargo.rs
+++ b/crates/rust-analyzer/src/cli/load_cargo.rs
@@ -13,14 +13,16 @@ use vfs::{loader::Handle, AbsPath, AbsPathBuf};
13 13
14use crate::reload::{ProjectFolders, SourceRootConfig}; 14use crate::reload::{ProjectFolders, SourceRootConfig};
15 15
16pub fn load_cargo( 16pub struct LoadCargoConfig {
17 root: &Path, 17 pub cargo_config: CargoConfig,
18 load_out_dirs_from_check: bool, 18 pub load_out_dirs_from_check: bool,
19 with_proc_macro: bool, 19 pub with_proc_macro: bool,
20) -> Result<(AnalysisHost, vfs::Vfs)> { 20}
21
22pub fn load_cargo(root: &Path, config: &LoadCargoConfig) -> Result<(AnalysisHost, vfs::Vfs)> {
21 let root = AbsPathBuf::assert(std::env::current_dir()?.join(root)); 23 let root = AbsPathBuf::assert(std::env::current_dir()?.join(root));
22 let root = ProjectManifest::discover_single(&root)?; 24 let root = ProjectManifest::discover_single(&root)?;
23 let ws = ProjectWorkspace::load(root, &CargoConfig::default(), &|_| {})?; 25 let ws = ProjectWorkspace::load(root, &config.cargo_config, &|_| {})?;
24 26
25 let (sender, receiver) = unbounded(); 27 let (sender, receiver) = unbounded();
26 let mut vfs = vfs::Vfs::default(); 28 let mut vfs = vfs::Vfs::default();
@@ -30,14 +32,14 @@ pub fn load_cargo(
30 Box::new(loader) 32 Box::new(loader)
31 }; 33 };
32 34
33 let proc_macro_client = if with_proc_macro { 35 let proc_macro_client = if config.with_proc_macro {
34 let path = std::env::current_exe()?; 36 let path = std::env::current_exe()?;
35 Some(ProcMacroClient::extern_process(path, &["proc-macro"]).unwrap()) 37 Some(ProcMacroClient::extern_process(path, &["proc-macro"]).unwrap())
36 } else { 38 } else {
37 None 39 None
38 }; 40 };
39 41
40 let build_data = if load_out_dirs_from_check { 42 let build_data = if config.load_out_dirs_from_check {
41 let mut collector = BuildDataCollector::default(); 43 let mut collector = BuildDataCollector::default();
42 ws.collect_build_data_configs(&mut collector); 44 ws.collect_build_data_configs(&mut collector);
43 Some(collector.collect(&|_| {})?) 45 Some(collector.collect(&|_| {})?)
@@ -116,7 +118,13 @@ mod tests {
116 #[test] 118 #[test]
117 fn test_loading_rust_analyzer() { 119 fn test_loading_rust_analyzer() {
118 let path = Path::new(env!("CARGO_MANIFEST_DIR")).parent().unwrap().parent().unwrap(); 120 let path = Path::new(env!("CARGO_MANIFEST_DIR")).parent().unwrap().parent().unwrap();
119 let (host, _vfs) = load_cargo(path, false, false).unwrap(); 121 let load_cargo_config = LoadCargoConfig {
122 cargo_config: Default::default(),
123 load_out_dirs_from_check: false,
124 with_proc_macro: false,
125 };
126
127 let (host, _vfs) = load_cargo(path, &load_cargo_config).unwrap();
120 let n_crates = Crate::all(host.raw_database()).len(); 128 let n_crates = Crate::all(host.raw_database()).len();
121 // RA has quite a few crates, but the exact count doesn't matter 129 // RA has quite a few crates, but the exact count doesn't matter
122 assert!(n_crates > 20); 130 assert!(n_crates > 20);
diff --git a/crates/rust-analyzer/src/cli/ssr.rs b/crates/rust-analyzer/src/cli/ssr.rs
index bbb550ec9..8729ff0d9 100644
--- a/crates/rust-analyzer/src/cli/ssr.rs
+++ b/crates/rust-analyzer/src/cli/ssr.rs
@@ -1,11 +1,19 @@
1//! Applies structured search replace rules from the command line. 1//! Applies structured search replace rules from the command line.
2 2
3use crate::cli::{load_cargo::load_cargo, Result}; 3use crate::cli::{
4 load_cargo::{load_cargo, LoadCargoConfig},
5 Result,
6};
4use ssr::{MatchFinder, SsrPattern, SsrRule}; 7use ssr::{MatchFinder, SsrPattern, SsrRule};
5 8
6pub fn apply_ssr_rules(rules: Vec<SsrRule>) -> Result<()> { 9pub fn apply_ssr_rules(rules: Vec<SsrRule>) -> Result<()> {
7 use ide_db::base_db::SourceDatabaseExt; 10 use ide_db::base_db::SourceDatabaseExt;
8 let (host, vfs) = load_cargo(&std::env::current_dir()?, true, true)?; 11 let load_cargo_config = LoadCargoConfig {
12 cargo_config: Default::default(),
13 load_out_dirs_from_check: true,
14 with_proc_macro: true,
15 };
16 let (host, vfs) = load_cargo(&std::env::current_dir()?, &load_cargo_config)?;
9 let db = host.raw_database(); 17 let db = host.raw_database();
10 let mut match_finder = MatchFinder::at_first_file(db)?; 18 let mut match_finder = MatchFinder::at_first_file(db)?;
11 for rule in rules { 19 for rule in rules {
@@ -28,7 +36,12 @@ pub fn apply_ssr_rules(rules: Vec<SsrRule>) -> Result<()> {
28pub fn search_for_patterns(patterns: Vec<SsrPattern>, debug_snippet: Option<String>) -> Result<()> { 36pub fn search_for_patterns(patterns: Vec<SsrPattern>, debug_snippet: Option<String>) -> Result<()> {
29 use ide_db::base_db::SourceDatabaseExt; 37 use ide_db::base_db::SourceDatabaseExt;
30 use ide_db::symbol_index::SymbolsDatabase; 38 use ide_db::symbol_index::SymbolsDatabase;
31 let (host, _vfs) = load_cargo(&std::env::current_dir()?, true, true)?; 39 let load_cargo_config = LoadCargoConfig {
40 cargo_config: Default::default(),
41 load_out_dirs_from_check: true,
42 with_proc_macro: true,
43 };
44 let (host, _vfs) = load_cargo(&std::env::current_dir()?, &load_cargo_config)?;
32 let db = host.raw_database(); 45 let db = host.raw_database();
33 let mut match_finder = MatchFinder::at_first_file(db)?; 46 let mut match_finder = MatchFinder::at_first_file(db)?;
34 for pattern in patterns { 47 for pattern in patterns {
diff --git a/crates/rust-analyzer/src/semantic_tokens.rs b/crates/rust-analyzer/src/semantic_tokens.rs
index 7ce9a4ab6..be0bea00b 100644
--- a/crates/rust-analyzer/src/semantic_tokens.rs
+++ b/crates/rust-analyzer/src/semantic_tokens.rs
@@ -44,6 +44,7 @@ define_semantic_token_types![
44 (BRACE, "brace"), 44 (BRACE, "brace"),
45 (BRACKET, "bracket"), 45 (BRACKET, "bracket"),
46 (BUILTIN_TYPE, "builtinType"), 46 (BUILTIN_TYPE, "builtinType"),
47 (CHAR_LITERAL, "characterLiteral"),
47 (COMMA, "comma"), 48 (COMMA, "comma"),
48 (COLON, "colon"), 49 (COLON, "colon"),
49 (DOT, "dot"), 50 (DOT, "dot"),
diff --git a/crates/rust-analyzer/src/to_proto.rs b/crates/rust-analyzer/src/to_proto.rs
index 96f915f1c..5236932e8 100644
--- a/crates/rust-analyzer/src/to_proto.rs
+++ b/crates/rust-analyzer/src/to_proto.rs
@@ -426,7 +426,8 @@ fn semantic_token_type_and_modifiers(
426 HlTag::None => semantic_tokens::GENERIC, 426 HlTag::None => semantic_tokens::GENERIC,
427 HlTag::ByteLiteral | HlTag::NumericLiteral => lsp_types::SemanticTokenType::NUMBER, 427 HlTag::ByteLiteral | HlTag::NumericLiteral => lsp_types::SemanticTokenType::NUMBER,
428 HlTag::BoolLiteral => semantic_tokens::BOOLEAN, 428 HlTag::BoolLiteral => semantic_tokens::BOOLEAN,
429 HlTag::CharLiteral | HlTag::StringLiteral => lsp_types::SemanticTokenType::STRING, 429 HlTag::StringLiteral => lsp_types::SemanticTokenType::STRING,
430 HlTag::CharLiteral => semantic_tokens::CHAR_LITERAL,
430 HlTag::Comment => lsp_types::SemanticTokenType::COMMENT, 431 HlTag::Comment => lsp_types::SemanticTokenType::COMMENT,
431 HlTag::Attribute => semantic_tokens::ATTRIBUTE, 432 HlTag::Attribute => semantic_tokens::ATTRIBUTE,
432 HlTag::Keyword => lsp_types::SemanticTokenType::KEYWORD, 433 HlTag::Keyword => lsp_types::SemanticTokenType::KEYWORD,
diff --git a/crates/syntax/Cargo.toml b/crates/syntax/Cargo.toml
index aa6f6e0b6..e3ef71650 100644
--- a/crates/syntax/Cargo.toml
+++ b/crates/syntax/Cargo.toml
@@ -13,7 +13,7 @@ doctest = false
13[dependencies] 13[dependencies]
14itertools = "0.10.0" 14itertools = "0.10.0"
15rowan = "0.12.2" 15rowan = "0.12.2"
16rustc_lexer = { version = "702.0.0", package = "rustc-ap-rustc_lexer" } 16rustc_lexer = { version = "705.0.0", package = "rustc-ap-rustc_lexer" }
17rustc-hash = "1.1.0" 17rustc-hash = "1.1.0"
18arrayvec = "0.5.1" 18arrayvec = "0.5.1"
19once_cell = "1.3.1" 19once_cell = "1.3.1"
diff --git a/crates/syntax/src/ast/generated/nodes.rs b/crates/syntax/src/ast/generated/nodes.rs
index 5baa54a3f..064931aec 100644
--- a/crates/syntax/src/ast/generated/nodes.rs
+++ b/crates/syntax/src/ast/generated/nodes.rs
@@ -1401,15 +1401,15 @@ pub enum FieldList {
1401 TupleFieldList(TupleFieldList), 1401 TupleFieldList(TupleFieldList),
1402} 1402}
1403#[derive(Debug, Clone, PartialEq, Eq, Hash)] 1403#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1404pub enum AdtDef { 1404pub enum Adt {
1405 Enum(Enum), 1405 Enum(Enum),
1406 Struct(Struct), 1406 Struct(Struct),
1407 Union(Union), 1407 Union(Union),
1408} 1408}
1409impl ast::AttrsOwner for AdtDef {} 1409impl ast::AttrsOwner for Adt {}
1410impl ast::GenericParamsOwner for AdtDef {} 1410impl ast::GenericParamsOwner for Adt {}
1411impl ast::NameOwner for AdtDef {} 1411impl ast::NameOwner for Adt {}
1412impl ast::VisibilityOwner for AdtDef {} 1412impl ast::VisibilityOwner for Adt {}
1413#[derive(Debug, Clone, PartialEq, Eq, Hash)] 1413#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1414pub enum AssocItem { 1414pub enum AssocItem {
1415 Const(Const), 1415 Const(Const),
@@ -3394,16 +3394,16 @@ impl AstNode for FieldList {
3394 } 3394 }
3395 } 3395 }
3396} 3396}
3397impl From<Enum> for AdtDef { 3397impl From<Enum> for Adt {
3398 fn from(node: Enum) -> AdtDef { AdtDef::Enum(node) } 3398 fn from(node: Enum) -> Adt { Adt::Enum(node) }
3399} 3399}
3400impl From<Struct> for AdtDef { 3400impl From<Struct> for Adt {
3401 fn from(node: Struct) -> AdtDef { AdtDef::Struct(node) } 3401 fn from(node: Struct) -> Adt { Adt::Struct(node) }
3402} 3402}
3403impl From<Union> for AdtDef { 3403impl From<Union> for Adt {
3404 fn from(node: Union) -> AdtDef { AdtDef::Union(node) } 3404 fn from(node: Union) -> Adt { Adt::Union(node) }
3405} 3405}
3406impl AstNode for AdtDef { 3406impl AstNode for Adt {
3407 fn can_cast(kind: SyntaxKind) -> bool { 3407 fn can_cast(kind: SyntaxKind) -> bool {
3408 match kind { 3408 match kind {
3409 ENUM | STRUCT | UNION => true, 3409 ENUM | STRUCT | UNION => true,
@@ -3412,18 +3412,18 @@ impl AstNode for AdtDef {
3412 } 3412 }
3413 fn cast(syntax: SyntaxNode) -> Option<Self> { 3413 fn cast(syntax: SyntaxNode) -> Option<Self> {
3414 let res = match syntax.kind() { 3414 let res = match syntax.kind() {
3415 ENUM => AdtDef::Enum(Enum { syntax }), 3415 ENUM => Adt::Enum(Enum { syntax }),
3416 STRUCT => AdtDef::Struct(Struct { syntax }), 3416 STRUCT => Adt::Struct(Struct { syntax }),
3417 UNION => AdtDef::Union(Union { syntax }), 3417 UNION => Adt::Union(Union { syntax }),
3418 _ => return None, 3418 _ => return None,
3419 }; 3419 };
3420 Some(res) 3420 Some(res)
3421 } 3421 }
3422 fn syntax(&self) -> &SyntaxNode { 3422 fn syntax(&self) -> &SyntaxNode {
3423 match self { 3423 match self {
3424 AdtDef::Enum(it) => &it.syntax, 3424 Adt::Enum(it) => &it.syntax,
3425 AdtDef::Struct(it) => &it.syntax, 3425 Adt::Struct(it) => &it.syntax,
3426 AdtDef::Union(it) => &it.syntax, 3426 Adt::Union(it) => &it.syntax,
3427 } 3427 }
3428 } 3428 }
3429} 3429}
@@ -3571,7 +3571,7 @@ impl std::fmt::Display for FieldList {
3571 std::fmt::Display::fmt(self.syntax(), f) 3571 std::fmt::Display::fmt(self.syntax(), f)
3572 } 3572 }
3573} 3573}
3574impl std::fmt::Display for AdtDef { 3574impl std::fmt::Display for Adt {
3575 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 3575 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3576 std::fmt::Display::fmt(self.syntax(), f) 3576 std::fmt::Display::fmt(self.syntax(), f)
3577 } 3577 }
diff --git a/docs/dev/architecture.md b/docs/dev/architecture.md
index 56ebaa3df..7a88ebc0f 100644
--- a/docs/dev/architecture.md
+++ b/docs/dev/architecture.md
@@ -21,7 +21,7 @@ See also these implementation-related blog posts:
21 21
22## Bird's Eye View 22## Bird's Eye View
23 23
24![](https://user-images.githubusercontent.com/1711539/50114578-e8a34280-0255-11e9-902c-7cfc70747966.png) 24![](https://user-images.githubusercontent.com/4789492/107129398-0ab70f00-687a-11eb-9bfc-d4eb023aec06.png)
25 25
26On the highest level, rust-analyzer is a thing which accepts input source code from the client and produces a structured semantic model of the code. 26On the highest level, rust-analyzer is a thing which accepts input source code from the client and produces a structured semantic model of the code.
27 27
@@ -39,6 +39,14 @@ The client can submit a small delta of input data (typically, a change to a sing
39 39
40The underlying engine makes sure that model is computed lazily (on-demand) and can be quickly updated for small modifications. 40The underlying engine makes sure that model is computed lazily (on-demand) and can be quickly updated for small modifications.
41 41
42## Entry Points
43
44`crates/rust-analyzer/src/bin/main.rs` contains the main function which spawns LSP.
45This is *the* entry point, but it front-loads a lot of complexity, so its fine to just skim through it.
46
47`crates/rust-analyzer/src/handlers.rs` implements all LSP requests and is a great place to start if you are already familiar with LSP.
48
49`Analysis` and `AnalysisHost` types define the main API.
42 50
43## Code Map 51## Code Map
44 52
@@ -75,7 +83,7 @@ Original [libsyntax parser](https://github.com/rust-lang/rust/blob/6b99adeb11313
75 83
76**Architecture Invariant:** the parser is independent of the particular tree structure and particular representation of the tokens. 84**Architecture Invariant:** the parser is independent of the particular tree structure and particular representation of the tokens.
77It transforms one flat stream of events into another flat stream of events. 85It transforms one flat stream of events into another flat stream of events.
78Token independence allows us to pares out both text-based source code and `tt`-based macro input. 86Token independence allows us to parse out both text-based source code and `tt`-based macro input.
79Tree independence allows us to more easily vary the syntax tree implementation. 87Tree independence allows us to more easily vary the syntax tree implementation.
80It should also unlock efficient light-parsing approaches. 88It should also unlock efficient light-parsing approaches.
81For example, you can extract the set of names defined in a file (for typo correction) without building a syntax tree. 89For example, you can extract the set of names defined in a file (for typo correction) without building a syntax tree.
@@ -254,6 +262,22 @@ A single `rust-analyzer` process can serve many projects, so it is important tha
254These crates implement macros as token tree -> token tree transforms. 262These crates implement macros as token tree -> token tree transforms.
255They are independent from the rest of the code. 263They are independent from the rest of the code.
256 264
265`tt` crate defined `TokenTree`, a single token or a delimited sequence of token trees.
266`mbe` crate contains tools for transforming between syntax trees and token tree.
267And it also handles the actual parsing and expansion of declarative macro (a-la "Macros By Example" or mbe).
268
269For proc macros, the client-server model are used.
270We pass an argument `--proc-macro` to `rust-analyzer` binary to start a separate process (`proc_macro_srv`).
271And the client (`proc_macro_api`) provides an interface to talk to that server separately.
272
273And then token trees are passed from client, and the server will load the corresponding dynamic library (which built by `cargo`).
274And due to the fact the api for getting result from proc macro are always unstable in `rustc`,
275we maintain our own copy (and paste) of that part of code to allow us to build the whole thing in stable rust.
276
277 **Architecture Invariant:**
278Bad proc macros may panic or segfault accidentally. So we run it in another process and recover it from fatal error.
279And they may be non-deterministic which conflict how `salsa` works, so special attention is required.
280
257### `crates/cfg` 281### `crates/cfg`
258 282
259This crate is responsible for parsing, evaluation and general definition of `cfg` attributes. 283This crate is responsible for parsing, evaluation and general definition of `cfg` attributes.
diff --git a/docs/user/manual.adoc b/docs/user/manual.adoc
index 10d4fd606..a2c7f56b3 100644
--- a/docs/user/manual.adoc
+++ b/docs/user/manual.adoc
@@ -194,6 +194,8 @@ $ pacman -S rust-analyzer
194 194
195=== Emacs 195=== Emacs
196 196
197Note this excellent https://robert.kra.hn/posts/2021-02-07_rust-with-emacs/[guide] from https://github.com/rksm[@rksm].
198
197Prerequisites: You have installed the <<rust-analyzer-language-server-binary,`rust-analyzer` binary>>. 199Prerequisites: You have installed the <<rust-analyzer-language-server-binary,`rust-analyzer` binary>>.
198 200
199Emacs support is maintained as part of the https://github.com/emacs-lsp/lsp-mode[Emacs-LSP] package in https://github.com/emacs-lsp/lsp-mode/blob/master/lsp-rust.el[lsp-rust.el]. 201Emacs support is maintained as part of the https://github.com/emacs-lsp/lsp-mode[Emacs-LSP] package in https://github.com/emacs-lsp/lsp-mode/blob/master/lsp-rust.el[lsp-rust.el].
@@ -307,6 +309,52 @@ EOF
307 309
308See https://sharksforarms.dev/posts/neovim-rust/ for more tips on getting started. 310See https://sharksforarms.dev/posts/neovim-rust/ for more tips on getting started.
309 311
312==== vim-lsp
313
314vim-lsp is installed by following https://github.com/prabirshrestha/vim-lsp[the plugin instructions].
315It can be as simple as adding this line to your `.vimrc`:
316
317[source,vim]
318----
319Plug 'prabirshrestha/vim-lsp'
320----
321
322Next you need to register the `rust-analyzer` binary.
323If it is available in `$PATH`, you may want to add this to your `.vimrc`:
324
325[source,vim]
326----
327if executable('rust-analyzer')
328 au User lsp_setup call lsp#register_server({
329 \ 'name': 'Rust Language Server',
330 \ 'cmd': {server_info->['rust-analyzer']},
331 \ 'whitelist': ['rust'],
332 \ })
333endif
334----
335
336There is no dedicated UI for the server configuration, so you would need to send any options as a value of the `initialization_options` field, as described in the <<_configuration,Configuration>> section.
337Here is an example of how to enable the proc-macro support:
338
339[source,vim]
340----
341if executable('rust-analyzer')
342 au User lsp_setup call lsp#register_server({
343 \ 'name': 'Rust Language Server',
344 \ 'cmd': {server_info->['rust-analyzer']},
345 \ 'whitelist': ['rust'],
346 \ 'initialization_options': {
347 \ 'cargo': {
348 \ 'loadOutDirsFromCheck': v:true,
349 \ },
350 \ 'procMacro': {
351 \ 'enable': v:true,
352 \ },
353 \ },
354 \ })
355endif
356----
357
310=== Sublime Text 3 358=== Sublime Text 3
311 359
312Prerequisites: You have installed the <<rust-analyzer-language-server-binary,`rust-analyzer` binary>>. 360Prerequisites: You have installed the <<rust-analyzer-language-server-binary,`rust-analyzer` binary>>.
@@ -331,17 +379,49 @@ If you get an error saying `No such file or directory: 'rust-analyzer'`, see the
331GNOME Builder 3.37.1 and newer has native `rust-analyzer` support. 379GNOME Builder 3.37.1 and newer has native `rust-analyzer` support.
332If the LSP binary is not available, GNOME Builder can install it when opening a Rust file. 380If the LSP binary is not available, GNOME Builder can install it when opening a Rust file.
333 381
382
383=== Eclipse IDE
384
385Prerequisites: You have installed the <<rust-analyzer-language-server-binary,`rust-analyzer` binary>>.
386
387Support for Rust development in the Eclipse IDE is provided by link:https://github.com/eclipse/corrosion[Eclipse Corrosion].
388While it currently uses RLS as default, you can successfully configure it so the IDE will use `rust-analyzer` instead.
389To do so, with an Eclipse IDE where Corrosion is installed, just go to __Window > Preferences > Rust__ and edit the __Path to Rust Language Server__ entry to reference the path to `rust-analyzer`.
390You'll need to close and reopen all .rs and Cargo files, or to restart the IDE, for this change to take effect.
391
334== Configuration 392== Configuration
335 393
336**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/rust-analyzer/src/config.rs[config.rs] 394**Source:** https://github.com/rust-analyzer/rust-analyzer/blob/master/crates/rust-analyzer/src/config.rs[config.rs]
337 395
338rust-analyzer is configured via LSP messages, which means that it's up to the editor to decide on the exact format and location of configuration files. 396The <<_installation,Installation>> section contains details on configuration for some of the editors.
339Please consult your editor's documentation to learn how to configure LSP servers. 397In general `rust-analyzer` is configured via LSP messages, which means that it's up to the editor to decide on the exact format and location of configuration files.
398
399Some clients, such as <<vs-code,VS Code>> or <<coc-rust-analyzer,COC plugin in Vim>> provide `rust-analyzer` specific configuration UIs. Others may require you to know a bit more about the interaction with `rust-analyzer`.
400
401For the later category, it might help to know that the initial configuration is specified as a value of the `intializationOptions` field of the https://microsoft.github.io/language-server-protocol/specifications/specification-current/#initialize[`InitializeParams` message, in the LSP protocol].
402The spec says that the field type is `any?`, but `rust-analyzer` is looking for a JSON object that is constructed using settings from the list below.
403Name of the setting, ignoring the `rust-analyzer.` prefix, is used as a path, and value of the setting becomes the JSON property value.
404
405For example, a very common configuration is to enable proc-macro support, can be achieved by sending this JSON:
406
407[source,json]
408----
409{
410 "cargo": {
411 "loadOutDirsFromCheck": true,
412 },
413 "procMacro": {
414 "enable": true,
415 }
416}
417----
418
419Please consult your editor's documentation to learn more about how to configure https://microsoft.github.io/language-server-protocol/[LSP servers].
340 420
341To verify which configuration is actually used by rust-analyzer, set `RA_LOG` environment variable to `rust_analyzer=info` and look for config-related messages. 421To verify which configuration is actually used by `rust-analyzer`, set `RA_LOG` environment variable to `rust_analyzer=info` and look for config-related messages.
342Logs should show both the JSON that rust-analyzer sees as well as the updated config. 422Logs should show both the JSON that `rust-analyzer` sees as well as the updated config.
343 423
344This is the list of config options rust-analyzer supports: 424This is the list of config options `rust-analyzer` supports:
345 425
346include::./generated_config.adoc[] 426include::./generated_config.adoc[]
347 427