aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/ci.yaml42
-rw-r--r--Cargo.lock117
-rw-r--r--bors.toml7
-rw-r--r--crates/ra_assists/src/assists/flip_binexpr.rs12
-rw-r--r--crates/ra_cargo_watch/src/conv/test.rs2
-rw-r--r--crates/ra_db/src/fixture.rs6
-rw-r--r--crates/ra_db/src/input.rs8
-rw-r--r--crates/ra_hir/src/code_model.rs3
-rw-r--r--crates/ra_hir/src/db.rs18
-rw-r--r--crates/ra_hir_def/src/db.rs11
-rw-r--r--crates/ra_hir_def/src/nameres.rs4
-rw-r--r--crates/ra_hir_def/src/nameres/collector.rs1
-rw-r--r--crates/ra_hir_expand/src/name.rs5
-rw-r--r--crates/ra_hir_ty/src/db.rs11
-rw-r--r--crates/ra_hir_ty/src/infer.rs4
-rw-r--r--crates/ra_hir_ty/src/lib.rs2
-rw-r--r--crates/ra_hir_ty/src/lower.rs2
-rw-r--r--crates/ra_hir_ty/src/tests/regression.rs17
-rw-r--r--crates/ra_ide/Cargo.toml1
-rw-r--r--crates/ra_ide/src/call_hierarchy.rs337
-rw-r--r--crates/ra_ide/src/call_info.rs15
-rw-r--r--crates/ra_ide/src/change.rs11
-rw-r--r--crates/ra_ide/src/diagnostics.rs36
-rw-r--r--crates/ra_ide/src/display/navigation_target.rs2
-rw-r--r--crates/ra_ide/src/expand.rs5
-rw-r--r--crates/ra_ide/src/lib.rs22
-rw-r--r--crates/ra_ide/src/references.rs205
-rw-r--r--crates/ra_ide/src/references/rename.rs8
-rw-r--r--crates/ra_lsp_server/src/caps.rs5
-rw-r--r--crates/ra_lsp_server/src/conv.rs18
-rw-r--r--crates/ra_lsp_server/src/main_loop.rs3
-rw-r--r--crates/ra_lsp_server/src/main_loop/handlers.rs113
-rw-r--r--crates/ra_lsp_server/src/req.rs16
-rw-r--r--crates/ra_parser/src/grammar/items/traits.rs5
-rw-r--r--crates/ra_parser/src/grammar/type_args.rs10
-rw-r--r--crates/ra_parser/src/syntax_kind/generated.rs271
-rw-r--r--crates/ra_prof/src/lib.rs29
-rw-r--r--crates/ra_project_model/src/sysroot.rs5
-rw-r--r--crates/ra_syntax/src/ast/expr_extensions.rs18
-rw-r--r--crates/ra_syntax/src/ast/generated.rs2989
-rw-r--r--crates/ra_syntax/src/grammar.ron736
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0039_type_arg.rs2
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0039_type_arg.txt51
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0150_impl_type_params.rs1
-rw-r--r--crates/ra_syntax/test_data/parser/inline/ok/0150_impl_type_params.txt38
-rw-r--r--docs/dev/lsp-features.md4
-rw-r--r--docs/user/README.md4
-rw-r--r--editors/code/src/client.ts4
-rw-r--r--xtask/Cargo.toml2
-rw-r--r--xtask/src/ast_src.rs621
-rw-r--r--xtask/src/boilerplate_gen.rs0
-rw-r--r--xtask/src/cmd.rs53
-rw-r--r--xtask/src/codegen.rs1
-rw-r--r--xtask/src/codegen/gen_syntax.rs234
-rw-r--r--xtask/src/help.rs46
-rw-r--r--xtask/src/install.rs178
-rw-r--r--xtask/src/lib.rs126
-rw-r--r--xtask/src/main.rs301
-rw-r--r--xtask/src/pre_commit.rs36
59 files changed, 3772 insertions, 3062 deletions
diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml
index 1d24295ec..e7e0d599e 100644
--- a/.github/workflows/ci.yaml
+++ b/.github/workflows/ci.yaml
@@ -10,16 +10,29 @@ on:
10jobs: 10jobs:
11 rust: 11 rust:
12 name: Rust 12 name: Rust
13 runs-on: ubuntu-latest 13 runs-on: ${{ matrix.os }}
14 strategy:
15 matrix:
16 os: [ubuntu-latest, windows-latest, macos-latest]
14 env: 17 env:
15 RUSTFLAGS: -D warnings 18 RUSTFLAGS: -D warnings
16 CARGO_INCREMENTAL: 0 19 CARGO_INCREMENTAL: 0
17 RUN_SLOW_TESTS: 1 20 RUN_SLOW_TESTS: 1
21 RUSTUP_MAX_RETRIES: 10
22 CARGO_NET_RETRY: 10
18 steps: 23 steps:
19 24
20 - name: Checkout repository 25 - name: Checkout repository
21 uses: actions/checkout@v1 26 uses: actions/checkout@v1
22 27
28 # We need to disable the existing toolchain to avoid updating rust-docs
29 # which takes a long time. The fastest way to do this is to rename the
30 # existing folder, as deleting it takes about as much time as not doing
31 # anything and just updating rust-docs.
32 - name: Rename existing rust toolchain (Windows)
33 if: matrix.os == 'windows-latest'
34 run: Rename-Item C:\Users\runneradmin\.rustup\toolchains\stable-x86_64-pc-windows-msvc C:\Users\runneradmin\.rustup\toolchains\stable-x86_64-pc-windows-msvc.old
35
23 - name: Install Rust toolchain 36 - name: Install Rust toolchain
24 uses: actions-rs/toolchain@v1 37 uses: actions-rs/toolchain@v1
25 with: 38 with:
@@ -28,7 +41,19 @@ jobs:
28 override: true 41 override: true
29 components: rustfmt, rust-src 42 components: rustfmt, rust-src
30 43
31 - name: Cargo target cache 44 - name: Cache cargo registry
45 uses: actions/cache@v1
46 with:
47 path: ~/.cargo/registry
48 key: ${{ runner.os }}-cargo-registry-${{ hashFiles('**/Cargo.lock') }}
49
50 - name: Cache cargo index
51 uses: actions/cache@v1
52 with:
53 path: ~/.cargo/git
54 key: ${{ runner.os }}-cargo-index-${{ hashFiles('**/Cargo.lock') }}
55
56 - name: Cache cargo target dir
32 uses: actions/cache@v1 57 uses: actions/cache@v1
33 with: 58 with:
34 path: target 59 path: target
@@ -45,12 +70,13 @@ jobs:
45 with: 70 with:
46 command: test 71 command: test
47 72
48 - name: Prepare build directory for cache 73 - name: Prepare cache
49 run: | 74 run: cargo xtask pre-cache
50 find ./target/debug -maxdepth 1 -type f -delete \ 75
51 && rm -fr ./target/debug/{deps,.fingerprint}/{*ra_*,*heavy_test*,*gen_lsp*,*thread_worker*} \ 76 - name: Prepare cache 2
52 && rm -f ./target/.rustc_info.json \ 77 if: matrix.os == 'windows-latest'
53 && rm ./target/.slow_tests_cookie 78 run: Remove-Item ./target/debug/xtask.exe
79
54 80
55 type-script: 81 type-script:
56 name: TypeScript 82 name: TypeScript
diff --git a/Cargo.lock b/Cargo.lock
index 65120c362..c570e0c3c 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -25,9 +25,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
25 25
26[[package]] 26[[package]]
27name = "atty" 27name = "atty"
28version = "0.2.13" 28version = "0.2.14"
29source = "registry+https://github.com/rust-lang/crates.io-index" 29source = "registry+https://github.com/rust-lang/crates.io-index"
30dependencies = [ 30dependencies = [
31 "hermit-abi 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
31 "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", 32 "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)",
32 "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", 33 "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
33] 34]
@@ -53,20 +54,12 @@ name = "backtrace-sys"
53version = "0.1.32" 54version = "0.1.32"
54source = "registry+https://github.com/rust-lang/crates.io-index" 55source = "registry+https://github.com/rust-lang/crates.io-index"
55dependencies = [ 56dependencies = [
56 "cc 1.0.48 (registry+https://github.com/rust-lang/crates.io-index)", 57 "cc 1.0.49 (registry+https://github.com/rust-lang/crates.io-index)",
57 "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", 58 "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)",
58] 59]
59 60
60[[package]] 61[[package]]
61name = "base64" 62name = "base64"
62version = "0.10.1"
63source = "registry+https://github.com/rust-lang/crates.io-index"
64dependencies = [
65 "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
66]
67
68[[package]]
69name = "base64"
70version = "0.11.0" 63version = "0.11.0"
71source = "registry+https://github.com/rust-lang/crates.io-index" 64source = "registry+https://github.com/rust-lang/crates.io-index"
72 65
@@ -122,7 +115,7 @@ dependencies = [
122 115
123[[package]] 116[[package]]
124name = "cc" 117name = "cc"
125version = "1.0.48" 118version = "1.0.49"
126source = "registry+https://github.com/rust-lang/crates.io-index" 119source = "registry+https://github.com/rust-lang/crates.io-index"
127 120
128[[package]] 121[[package]]
@@ -137,7 +130,7 @@ source = "git+https://github.com/rust-lang/chalk.git?rev=ff65b5ac9860f3c36bd892c
137dependencies = [ 130dependencies = [
138 "proc-macro2 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)", 131 "proc-macro2 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
139 "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", 132 "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
140 "syn 1.0.12 (registry+https://github.com/rust-lang/crates.io-index)", 133 "syn 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)",
141] 134]
142 135
143[[package]] 136[[package]]
@@ -200,7 +193,7 @@ name = "clicolors-control"
200version = "1.0.1" 193version = "1.0.1"
201source = "registry+https://github.com/rust-lang/crates.io-index" 194source = "registry+https://github.com/rust-lang/crates.io-index"
202dependencies = [ 195dependencies = [
203 "atty 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)", 196 "atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",
204 "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 197 "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
205 "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", 198 "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)",
206 "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", 199 "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -409,12 +402,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
409 402
410[[package]] 403[[package]]
411name = "getrandom" 404name = "getrandom"
412version = "0.1.13" 405version = "0.1.14"
413source = "registry+https://github.com/rust-lang/crates.io-index" 406source = "registry+https://github.com/rust-lang/crates.io-index"
414dependencies = [ 407dependencies = [
415 "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)", 408 "cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
416 "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", 409 "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)",
417 "wasi 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", 410 "wasi 0.9.0+wasi-snapshot-preview1 (registry+https://github.com/rust-lang/crates.io-index)",
418] 411]
419 412
420[[package]] 413[[package]]
@@ -439,7 +432,7 @@ dependencies = [
439 432
440[[package]] 433[[package]]
441name = "hermit-abi" 434name = "hermit-abi"
442version = "0.1.5" 435version = "0.1.6"
443source = "registry+https://github.com/rust-lang/crates.io-index" 436source = "registry+https://github.com/rust-lang/crates.io-index"
444dependencies = [ 437dependencies = [
445 "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", 438 "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -450,7 +443,7 @@ name = "humantime"
450version = "1.3.0" 443version = "1.3.0"
451source = "registry+https://github.com/rust-lang/crates.io-index" 444source = "registry+https://github.com/rust-lang/crates.io-index"
452dependencies = [ 445dependencies = [
453 "quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 446 "quick-error 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
454] 447]
455 448
456[[package]] 449[[package]]
@@ -473,7 +466,7 @@ dependencies = [
473 466
474[[package]] 467[[package]]
475name = "inotify" 468name = "inotify"
476version = "0.6.1" 469version = "0.7.0"
477source = "registry+https://github.com/rust-lang/crates.io-index" 470source = "registry+https://github.com/rust-lang/crates.io-index"
478dependencies = [ 471dependencies = [
479 "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", 472 "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -539,7 +532,7 @@ name = "jemalloc-sys"
539version = "0.3.2" 532version = "0.3.2"
540source = "registry+https://github.com/rust-lang/crates.io-index" 533source = "registry+https://github.com/rust-lang/crates.io-index"
541dependencies = [ 534dependencies = [
542 "cc 1.0.48 (registry+https://github.com/rust-lang/crates.io-index)", 535 "cc 1.0.49 (registry+https://github.com/rust-lang/crates.io-index)",
543 "fs_extra 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 536 "fs_extra 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
544 "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", 537 "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)",
545] 538]
@@ -599,7 +592,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
599 592
600[[package]] 593[[package]]
601name = "lock_api" 594name = "lock_api"
602version = "0.3.2" 595version = "0.3.3"
603source = "registry+https://github.com/rust-lang/crates.io-index" 596source = "registry+https://github.com/rust-lang/crates.io-index"
604dependencies = [ 597dependencies = [
605 "scopeguard 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", 598 "scopeguard 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -626,7 +619,7 @@ dependencies = [
626 619
627[[package]] 620[[package]]
628name = "lsp-types" 621name = "lsp-types"
629version = "0.68.0" 622version = "0.68.1"
630source = "registry+https://github.com/rust-lang/crates.io-index" 623source = "registry+https://github.com/rust-lang/crates.io-index"
631dependencies = [ 624dependencies = [
632 "base64 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", 625 "base64 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -707,15 +700,14 @@ dependencies = [
707 700
708[[package]] 701[[package]]
709name = "notify" 702name = "notify"
710version = "4.0.14" 703version = "4.0.15"
711source = "registry+https://github.com/rust-lang/crates.io-index" 704source = "registry+https://github.com/rust-lang/crates.io-index"
712dependencies = [ 705dependencies = [
713 "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", 706 "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
714 "filetime 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", 707 "filetime 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
715 "fsevent 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 708 "fsevent 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
716 "fsevent-sys 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)", 709 "fsevent-sys 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
717 "inotify 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)", 710 "inotify 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
718 "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
719 "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", 711 "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)",
720 "mio 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)", 712 "mio 0.6.21 (registry+https://github.com/rust-lang/crates.io-index)",
721 "mio-extras 2.0.6 (registry+https://github.com/rust-lang/crates.io-index)", 713 "mio-extras 2.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -736,7 +728,7 @@ name = "num_cpus"
736version = "1.11.1" 728version = "1.11.1"
737source = "registry+https://github.com/rust-lang/crates.io-index" 729source = "registry+https://github.com/rust-lang/crates.io-index"
738dependencies = [ 730dependencies = [
739 "hermit-abi 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", 731 "hermit-abi 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
740 "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", 732 "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)",
741] 733]
742 734
@@ -755,7 +747,7 @@ name = "parking_lot"
755version = "0.10.0" 747version = "0.10.0"
756source = "registry+https://github.com/rust-lang/crates.io-index" 748source = "registry+https://github.com/rust-lang/crates.io-index"
757dependencies = [ 749dependencies = [
758 "lock_api 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", 750 "lock_api 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
759 "parking_lot_core 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", 751 "parking_lot_core 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
760] 752]
761 753
@@ -789,7 +781,7 @@ dependencies = [
789 "proc-macro-hack 0.5.11 (registry+https://github.com/rust-lang/crates.io-index)", 781 "proc-macro-hack 0.5.11 (registry+https://github.com/rust-lang/crates.io-index)",
790 "proc-macro2 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)", 782 "proc-macro2 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
791 "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", 783 "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
792 "syn 1.0.12 (registry+https://github.com/rust-lang/crates.io-index)", 784 "syn 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)",
793] 785]
794 786
795[[package]] 787[[package]]
@@ -808,7 +800,7 @@ dependencies = [
808 800
809[[package]] 801[[package]]
810name = "pico-args" 802name = "pico-args"
811version = "0.3.0" 803version = "0.3.1"
812source = "registry+https://github.com/rust-lang/crates.io-index" 804source = "registry+https://github.com/rust-lang/crates.io-index"
813 805
814[[package]] 806[[package]]
@@ -823,7 +815,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
823dependencies = [ 815dependencies = [
824 "proc-macro2 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)", 816 "proc-macro2 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
825 "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", 817 "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
826 "syn 1.0.12 (registry+https://github.com/rust-lang/crates.io-index)", 818 "syn 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)",
827] 819]
828 820
829[[package]] 821[[package]]
@@ -844,7 +836,7 @@ dependencies = [
844 "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", 836 "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
845 "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 837 "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
846 "num-traits 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", 838 "num-traits 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
847 "quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 839 "quick-error 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
848 "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", 840 "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
849 "rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 841 "rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
850 "rand_xorshift 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 842 "rand_xorshift 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -853,7 +845,7 @@ dependencies = [
853 845
854[[package]] 846[[package]]
855name = "quick-error" 847name = "quick-error"
856version = "1.2.2" 848version = "1.2.3"
857source = "registry+https://github.com/rust-lang/crates.io-index" 849source = "registry+https://github.com/rust-lang/crates.io-index"
858 850
859[[package]] 851[[package]]
@@ -907,7 +899,7 @@ dependencies = [
907 "insta 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", 899 "insta 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
908 "jod-thread 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 900 "jod-thread 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
909 "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", 901 "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
910 "lsp-types 0.68.0 (registry+https://github.com/rust-lang/crates.io-index)", 902 "lsp-types 0.68.1 (registry+https://github.com/rust-lang/crates.io-index)",
911 "parking_lot 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", 903 "parking_lot 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
912 "serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)", 904 "serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)",
913] 905]
@@ -927,7 +919,7 @@ name = "ra_cli"
927version = "0.1.0" 919version = "0.1.0"
928dependencies = [ 920dependencies = [
929 "env_logger 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", 921 "env_logger 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
930 "pico-args 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", 922 "pico-args 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
931 "ra_batch 0.1.0", 923 "ra_batch 0.1.0",
932 "ra_db 0.1.0", 924 "ra_db 0.1.0",
933 "ra_hir 0.1.0", 925 "ra_hir 0.1.0",
@@ -1040,6 +1032,7 @@ dependencies = [
1040 "either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)", 1032 "either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
1041 "format-buf 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", 1033 "format-buf 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
1042 "fst 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", 1034 "fst 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
1035 "indexmap 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
1043 "insta 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", 1036 "insta 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)",
1044 "itertools 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", 1037 "itertools 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)",
1045 "join_to_string 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", 1038 "join_to_string 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1071,7 +1064,7 @@ dependencies = [
1071 "jod-thread 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 1064 "jod-thread 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
1072 "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", 1065 "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
1073 "lsp-server 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", 1066 "lsp-server 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
1074 "lsp-types 0.68.0 (registry+https://github.com/rust-lang/crates.io-index)", 1067 "lsp-types 0.68.1 (registry+https://github.com/rust-lang/crates.io-index)",
1075 "parking_lot 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", 1068 "parking_lot 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
1076 "ra_cargo_watch 0.1.0", 1069 "ra_cargo_watch 0.1.0",
1077 "ra_ide 0.1.0", 1070 "ra_ide 0.1.0",
@@ -1177,7 +1170,7 @@ dependencies = [
1177 "crossbeam-channel 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", 1170 "crossbeam-channel 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
1178 "jod-thread 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 1171 "jod-thread 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
1179 "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", 1172 "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
1180 "notify 4.0.14 (registry+https://github.com/rust-lang/crates.io-index)", 1173 "notify 4.0.15 (registry+https://github.com/rust-lang/crates.io-index)",
1181 "parking_lot 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", 1174 "parking_lot 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
1182 "relative-path 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", 1175 "relative-path 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
1183 "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)", 1176 "rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1215,7 +1208,7 @@ name = "rand"
1215version = "0.7.2" 1208version = "0.7.2"
1216source = "registry+https://github.com/rust-lang/crates.io-index" 1209source = "registry+https://github.com/rust-lang/crates.io-index"
1217dependencies = [ 1210dependencies = [
1218 "getrandom 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", 1211 "getrandom 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)",
1219 "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", 1212 "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)",
1220 "rand_chacha 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", 1213 "rand_chacha 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
1221 "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", 1214 "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1259,7 +1252,7 @@ name = "rand_core"
1259version = "0.5.1" 1252version = "0.5.1"
1260source = "registry+https://github.com/rust-lang/crates.io-index" 1253source = "registry+https://github.com/rust-lang/crates.io-index"
1261dependencies = [ 1254dependencies = [
1262 "getrandom 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)", 1255 "getrandom 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)",
1263] 1256]
1264 1257
1265[[package]] 1258[[package]]
@@ -1399,16 +1392,6 @@ dependencies = [
1399] 1392]
1400 1393
1401[[package]] 1394[[package]]
1402name = "ron"
1403version = "0.5.1"
1404source = "registry+https://github.com/rust-lang/crates.io-index"
1405dependencies = [
1406 "base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
1407 "bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
1408 "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)",
1409]
1410
1411[[package]]
1412name = "rowan" 1395name = "rowan"
1413version = "0.8.2" 1396version = "0.8.2"
1414source = "registry+https://github.com/rust-lang/crates.io-index" 1397source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1476,7 +1459,7 @@ dependencies = [
1476 "heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", 1459 "heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
1477 "proc-macro2 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)", 1460 "proc-macro2 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
1478 "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", 1461 "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
1479 "syn 1.0.12 (registry+https://github.com/rust-lang/crates.io-index)", 1462 "syn 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)",
1480] 1463]
1481 1464
1482[[package]] 1465[[package]]
@@ -1521,7 +1504,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
1521dependencies = [ 1504dependencies = [
1522 "proc-macro2 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)", 1505 "proc-macro2 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
1523 "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", 1506 "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
1524 "syn 1.0.12 (registry+https://github.com/rust-lang/crates.io-index)", 1507 "syn 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)",
1525] 1508]
1526 1509
1527[[package]] 1510[[package]]
@@ -1541,7 +1524,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
1541dependencies = [ 1524dependencies = [
1542 "proc-macro2 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)", 1525 "proc-macro2 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
1543 "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", 1526 "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
1544 "syn 1.0.12 (registry+https://github.com/rust-lang/crates.io-index)", 1527 "syn 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)",
1545] 1528]
1546 1529
1547[[package]] 1530[[package]]
@@ -1580,7 +1563,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
1580 1563
1581[[package]] 1564[[package]]
1582name = "syn" 1565name = "syn"
1583version = "1.0.12" 1566version = "1.0.13"
1584source = "registry+https://github.com/rust-lang/crates.io-index" 1567source = "registry+https://github.com/rust-lang/crates.io-index"
1585dependencies = [ 1568dependencies = [
1586 "proc-macro2 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)", 1569 "proc-macro2 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1715,7 +1698,7 @@ dependencies = [
1715 1698
1716[[package]] 1699[[package]]
1717name = "wasi" 1700name = "wasi"
1718version = "0.7.0" 1701version = "0.9.0+wasi-snapshot-preview1"
1719source = "registry+https://github.com/rust-lang/crates.io-index" 1702source = "registry+https://github.com/rust-lang/crates.io-index"
1720 1703
1721[[package]] 1704[[package]]
@@ -1769,11 +1752,9 @@ name = "xtask"
1769version = "0.1.0" 1752version = "0.1.0"
1770dependencies = [ 1753dependencies = [
1771 "anyhow 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)", 1754 "anyhow 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)",
1772 "pico-args 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", 1755 "pico-args 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
1773 "proc-macro2 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)", 1756 "proc-macro2 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
1774 "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", 1757 "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
1775 "ron 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
1776 "serde 1.0.104 (registry+https://github.com/rust-lang/crates.io-index)",
1777 "walkdir 2.2.9 (registry+https://github.com/rust-lang/crates.io-index)", 1758 "walkdir 2.2.9 (registry+https://github.com/rust-lang/crates.io-index)",
1778] 1759]
1779 1760
@@ -1790,11 +1771,10 @@ dependencies = [
1790"checksum anyhow 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)" = "7825f6833612eb2414095684fcf6c635becf3ce97fe48cf6421321e93bfbd53c" 1771"checksum anyhow 1.0.26 (registry+https://github.com/rust-lang/crates.io-index)" = "7825f6833612eb2414095684fcf6c635becf3ce97fe48cf6421321e93bfbd53c"
1791"checksum anymap 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)" = "33954243bd79057c2de7338850b85983a44588021f8a5fee574a8888c6de4344" 1772"checksum anymap 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)" = "33954243bd79057c2de7338850b85983a44588021f8a5fee574a8888c6de4344"
1792"checksum arrayvec 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cff77d8686867eceff3105329d4698d96c2391c176d5d03adc90c7389162b5b8" 1773"checksum arrayvec 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cff77d8686867eceff3105329d4698d96c2391c176d5d03adc90c7389162b5b8"
1793"checksum atty 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)" = "1803c647a3ec87095e7ae7acfca019e98de5ec9a7d01343f611cf3152ed71a90" 1774"checksum atty 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
1794"checksum autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2" 1775"checksum autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2"
1795"checksum backtrace 0.3.40 (registry+https://github.com/rust-lang/crates.io-index)" = "924c76597f0d9ca25d762c25a4d369d51267536465dc5064bdf0eb073ed477ea" 1776"checksum backtrace 0.3.40 (registry+https://github.com/rust-lang/crates.io-index)" = "924c76597f0d9ca25d762c25a4d369d51267536465dc5064bdf0eb073ed477ea"
1796"checksum backtrace-sys 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)" = "5d6575f128516de27e3ce99689419835fce9643a9b215a14d2b5b685be018491" 1777"checksum backtrace-sys 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)" = "5d6575f128516de27e3ce99689419835fce9643a9b215a14d2b5b685be018491"
1797"checksum base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0b25d992356d2eb0ed82172f5248873db5560c4721f564b13cb5193bda5e668e"
1798"checksum base64 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b41b7ea54a0c9d92199de89e20e58d49f02f8e699814ef3fdf266f6f748d15c7" 1778"checksum base64 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b41b7ea54a0c9d92199de89e20e58d49f02f8e699814ef3fdf266f6f748d15c7"
1799"checksum bit-set 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e84c238982c4b1e1ee668d136c510c67a13465279c0cb367ea6baf6310620a80" 1779"checksum bit-set 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e84c238982c4b1e1ee668d136c510c67a13465279c0cb367ea6baf6310620a80"
1800"checksum bit-vec 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f59bbe95d4e52a6398ec21238d31577f2b28a9d86807f06ca59d191d8440d0bb" 1780"checksum bit-vec 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f59bbe95d4e52a6398ec21238d31577f2b28a9d86807f06ca59d191d8440d0bb"
@@ -1803,7 +1783,7 @@ dependencies = [
1803"checksum byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a7c3dd8985a7111efc5c80b44e23ecdd8c007de8ade3b96595387e812b957cf5" 1783"checksum byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a7c3dd8985a7111efc5c80b44e23ecdd8c007de8ade3b96595387e812b957cf5"
1804"checksum c2-chacha 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "214238caa1bf3a496ec3392968969cab8549f96ff30652c9e56885329315f6bb" 1784"checksum c2-chacha 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "214238caa1bf3a496ec3392968969cab8549f96ff30652c9e56885329315f6bb"
1805"checksum cargo_metadata 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "46e3374c604fb39d1a2f35ed5e4a4e30e60d01fab49446e08f1b3e9a90aef202" 1785"checksum cargo_metadata 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "46e3374c604fb39d1a2f35ed5e4a4e30e60d01fab49446e08f1b3e9a90aef202"
1806"checksum cc 1.0.48 (registry+https://github.com/rust-lang/crates.io-index)" = "f52a465a666ca3d838ebbf08b241383421412fe7ebb463527bba275526d89f76" 1786"checksum cc 1.0.49 (registry+https://github.com/rust-lang/crates.io-index)" = "e450b8da92aa6f274e7c6437692f9f2ce6d701fb73bacfcf87897b3f89a4c20e"
1807"checksum cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" 1787"checksum cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
1808"checksum chalk-derive 0.1.0 (git+https://github.com/rust-lang/chalk.git?rev=ff65b5ac9860f3c36bd892c865ab23d5ff0bbae5)" = "<none>" 1788"checksum chalk-derive 0.1.0 (git+https://github.com/rust-lang/chalk.git?rev=ff65b5ac9860f3c36bd892c865ab23d5ff0bbae5)" = "<none>"
1809"checksum chalk-engine 0.9.0 (git+https://github.com/rust-lang/chalk.git?rev=ff65b5ac9860f3c36bd892c865ab23d5ff0bbae5)" = "<none>" 1789"checksum chalk-engine 0.9.0 (git+https://github.com/rust-lang/chalk.git?rev=ff65b5ac9860f3c36bd892c865ab23d5ff0bbae5)" = "<none>"
@@ -1838,14 +1818,14 @@ dependencies = [
1838"checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" 1818"checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba"
1839"checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82" 1819"checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82"
1840"checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7" 1820"checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7"
1841"checksum getrandom 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "e7db7ca94ed4cd01190ceee0d8a8052f08a247aa1b469a7f68c6a3b71afcf407" 1821"checksum getrandom 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)" = "7abc8dd8451921606d809ba32e95b6111925cd2906060d2dcc29c070220503eb"
1842"checksum globset 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "925aa2cac82d8834e2b2a4415b6f6879757fb5c0928fc445ae76461a12eed8f2" 1822"checksum globset 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "925aa2cac82d8834e2b2a4415b6f6879757fb5c0928fc445ae76461a12eed8f2"
1843"checksum heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205" 1823"checksum heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205"
1844"checksum hermit-abi 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "f629dc602392d3ec14bfc8a09b5e644d7ffd725102b48b81e59f90f2633621d7" 1824"checksum hermit-abi 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "eff2656d88f158ce120947499e971d743c05dbcbed62e5bd2f38f1698bbc3772"
1845"checksum humantime 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "df004cfca50ef23c36850aaaa59ad52cc70d0e90243c3c7737a4dd32dc7a3c4f" 1825"checksum humantime 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "df004cfca50ef23c36850aaaa59ad52cc70d0e90243c3c7737a4dd32dc7a3c4f"
1846"checksum idna 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "02e2673c30ee86b5b96a9cb52ad15718aa1f966f5ab9ad54a8b95d5ca33120a9" 1826"checksum idna 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "02e2673c30ee86b5b96a9cb52ad15718aa1f966f5ab9ad54a8b95d5ca33120a9"
1847"checksum indexmap 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712d7b3ea5827fcb9d4fda14bf4da5f136f0db2ae9c8f4bd4e2d1c6fde4e6db2" 1827"checksum indexmap 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712d7b3ea5827fcb9d4fda14bf4da5f136f0db2ae9c8f4bd4e2d1c6fde4e6db2"
1848"checksum inotify 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "40b54539f3910d6f84fbf9a643efd6e3aa6e4f001426c0329576128255994718" 1828"checksum inotify 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "24e40d6fd5d64e2082e0c796495c8ef5ad667a96d03e5aaa0becfd9d47bcbfb8"
1849"checksum inotify-sys 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e74a1aa87c59aeff6ef2cc2fa62d41bc43f54952f55652656b18a02fd5e356c0" 1829"checksum inotify-sys 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e74a1aa87c59aeff6ef2cc2fa62d41bc43f54952f55652656b18a02fd5e356c0"
1850"checksum insta 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0d499dc062e841590a67230d853bce62d0abeb91304927871670b7c55c461349" 1830"checksum insta 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0d499dc062e841590a67230d853bce62d0abeb91304927871670b7c55c461349"
1851"checksum iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e" 1831"checksum iovec 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e"
@@ -1862,10 +1842,10 @@ dependencies = [
1862"checksum lazycell 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b294d6fa9ee409a054354afc4352b0b9ef7ca222c69b8812cbea9e7d2bf3783f" 1842"checksum lazycell 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b294d6fa9ee409a054354afc4352b0b9ef7ca222c69b8812cbea9e7d2bf3783f"
1863"checksum libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)" = "d515b1f41455adea1313a4a2ac8a8a477634fbae63cc6100e3aebb207ce61558" 1843"checksum libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)" = "d515b1f41455adea1313a4a2ac8a8a477634fbae63cc6100e3aebb207ce61558"
1864"checksum linked-hash-map 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ae91b68aebc4ddb91978b11a1b02ddd8602a05ec19002801c5666000e05e0f83" 1844"checksum linked-hash-map 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ae91b68aebc4ddb91978b11a1b02ddd8602a05ec19002801c5666000e05e0f83"
1865"checksum lock_api 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e57b3997725d2b60dbec1297f6c2e2957cc383db1cebd6be812163f969c7d586" 1845"checksum lock_api 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "79b2de95ecb4691949fea4716ca53cdbcfccb2c612e19644a8bad05edcf9f47b"
1866"checksum log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7" 1846"checksum log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7"
1867"checksum lsp-server 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5383e043329615624bbf45e1ba27bd75c176762b2592855c659bc28ac580a06b" 1847"checksum lsp-server 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5383e043329615624bbf45e1ba27bd75c176762b2592855c659bc28ac580a06b"
1868"checksum lsp-types 0.68.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1b08121a463f43ee67f09da45c0a61d447793adc8dc23e52b009e8cf80278a16" 1848"checksum lsp-types 0.68.1 (registry+https://github.com/rust-lang/crates.io-index)" = "19b79f72914b929daa263483134b8974962cdebc731593b11508afb7f9acec80"
1869"checksum matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08" 1849"checksum matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08"
1870"checksum memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "88579771288728879b57485cc7d6b07d648c9f0141eb955f8ab7f9d45394468e" 1850"checksum memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "88579771288728879b57485cc7d6b07d648c9f0141eb955f8ab7f9d45394468e"
1871"checksum memoffset 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "75189eb85871ea5c2e2c15abbdd541185f63b408415e5051f5cac122d8c774b9" 1851"checksum memoffset 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "75189eb85871ea5c2e2c15abbdd541185f63b408415e5051f5cac122d8c774b9"
@@ -1873,7 +1853,7 @@ dependencies = [
1873"checksum mio-extras 2.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "52403fe290012ce777c4626790c8951324a2b9e3316b3143779c72b029742f19" 1853"checksum mio-extras 2.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "52403fe290012ce777c4626790c8951324a2b9e3316b3143779c72b029742f19"
1874"checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919" 1854"checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919"
1875"checksum net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "42550d9fb7b6684a6d404d9fa7250c2eb2646df731d1c06afc06dcee9e1bcf88" 1855"checksum net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "42550d9fb7b6684a6d404d9fa7250c2eb2646df731d1c06afc06dcee9e1bcf88"
1876"checksum notify 4.0.14 (registry+https://github.com/rust-lang/crates.io-index)" = "199628fc33b21bc767baa057490b00b382ecbae030803a7b36292422d15b778b" 1856"checksum notify 4.0.15 (registry+https://github.com/rust-lang/crates.io-index)" = "80ae4a7688d1fab81c5bf19c64fc8db920be8d519ce6336ed4e7efe024724dbd"
1877"checksum num-traits 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c81ffc11c212fa327657cb19dd85eb7419e163b5b076bede2bdb5c974c07e4" 1857"checksum num-traits 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c81ffc11c212fa327657cb19dd85eb7419e163b5b076bede2bdb5c974c07e4"
1878"checksum num_cpus 1.11.1 (registry+https://github.com/rust-lang/crates.io-index)" = "76dac5ed2a876980778b8b85f75a71b6cbf0db0b1232ee12f826bccb00d09d72" 1858"checksum num_cpus 1.11.1 (registry+https://github.com/rust-lang/crates.io-index)" = "76dac5ed2a876980778b8b85f75a71b6cbf0db0b1232ee12f826bccb00d09d72"
1879"checksum once_cell 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "891f486f630e5c5a4916c7e16c4b24a53e78c860b646e9f8e005e4f16847bfed" 1859"checksum once_cell 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "891f486f630e5c5a4916c7e16c4b24a53e78c860b646e9f8e005e4f16847bfed"
@@ -1884,12 +1864,12 @@ dependencies = [
1884"checksum paste-impl 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "4214c9e912ef61bf42b81ba9a47e8aad1b2ffaf739ab162bf96d1e011f54e6c5" 1864"checksum paste-impl 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "4214c9e912ef61bf42b81ba9a47e8aad1b2ffaf739ab162bf96d1e011f54e6c5"
1885"checksum percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" 1865"checksum percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e"
1886"checksum petgraph 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)" = "9c3659d1ee90221741f65dd128d9998311b0e40c5d3c23a62445938214abce4f" 1866"checksum petgraph 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)" = "9c3659d1ee90221741f65dd128d9998311b0e40c5d3c23a62445938214abce4f"
1887"checksum pico-args 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "22e32b0f3771287ebb436130477eabf0f11f934ed036099ad548bc885e708667" 1867"checksum pico-args 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3ad1f1b834a05d42dae330066e9699a173b28185b3bdc3dbf14ca239585de8cc"
1888"checksum ppv-lite86 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "74490b50b9fbe561ac330df47c08f3f33073d2d00c150f719147d7c54522fa1b" 1868"checksum ppv-lite86 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "74490b50b9fbe561ac330df47c08f3f33073d2d00c150f719147d7c54522fa1b"
1889"checksum proc-macro-hack 0.5.11 (registry+https://github.com/rust-lang/crates.io-index)" = "ecd45702f76d6d3c75a80564378ae228a85f0b59d2f3ed43c91b4a69eb2ebfc5" 1869"checksum proc-macro-hack 0.5.11 (registry+https://github.com/rust-lang/crates.io-index)" = "ecd45702f76d6d3c75a80564378ae228a85f0b59d2f3ed43c91b4a69eb2ebfc5"
1890"checksum proc-macro2 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "0319972dcae462681daf4da1adeeaa066e3ebd29c69be96c6abb1259d2ee2bcc" 1870"checksum proc-macro2 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "0319972dcae462681daf4da1adeeaa066e3ebd29c69be96c6abb1259d2ee2bcc"
1891"checksum proptest 0.9.4 (registry+https://github.com/rust-lang/crates.io-index)" = "cf147e022eacf0c8a054ab864914a7602618adba841d800a9a9868a5237a529f" 1871"checksum proptest 0.9.4 (registry+https://github.com/rust-lang/crates.io-index)" = "cf147e022eacf0c8a054ab864914a7602618adba841d800a9a9868a5237a529f"
1892"checksum quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9274b940887ce9addde99c4eee6b5c44cc494b182b97e73dc8ffdcb3397fd3f0" 1872"checksum quick-error 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0"
1893"checksum quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "053a8c8bcc71fcce321828dc897a98ab9760bef03a4fc36693c231e5b3216cfe" 1873"checksum quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "053a8c8bcc71fcce321828dc897a98ab9760bef03a4fc36693c231e5b3216cfe"
1894"checksum ra_vfs 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bc898f237e4b4498959ae0100c688793a23e77624d44ef710ba70094217f98e0" 1874"checksum ra_vfs 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bc898f237e4b4498959ae0100c688793a23e77624d44ef710ba70094217f98e0"
1895"checksum rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca" 1875"checksum rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca"
@@ -1915,7 +1895,6 @@ dependencies = [
1915"checksum regex-syntax 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)" = "11a7e20d1cce64ef2fed88b66d347f88bd9babb82845b2b858f3edbf59a4f716" 1895"checksum regex-syntax 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)" = "11a7e20d1cce64ef2fed88b66d347f88bd9babb82845b2b858f3edbf59a4f716"
1916"checksum relative-path 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bedde000f40f2921ce439ea165c9c53fd629bfa115140c72e22aceacb4a21954" 1896"checksum relative-path 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bedde000f40f2921ce439ea165c9c53fd629bfa115140c72e22aceacb4a21954"
1917"checksum remove_dir_all 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4a83fa3702a688b9359eccba92d153ac33fd2e8462f9e0e3fdf155239ea7792e" 1897"checksum remove_dir_all 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4a83fa3702a688b9359eccba92d153ac33fd2e8462f9e0e3fdf155239ea7792e"
1918"checksum ron 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2ece421e0c4129b90e4a35b6f625e472e96c552136f5093a2f4fa2bbb75a62d5"
1919"checksum rowan 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3eb10a10a48f0f809a217bcf074b85a03dcf79831bae80e7f1a043d0897463e2" 1898"checksum rowan 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3eb10a10a48f0f809a217bcf074b85a03dcf79831bae80e7f1a043d0897463e2"
1920"checksum rustc-demangle 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "4c691c0e608126e00913e33f0ccf3727d5fc84573623b8d65b2df340b5201783" 1899"checksum rustc-demangle 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "4c691c0e608126e00913e33f0ccf3727d5fc84573623b8d65b2df340b5201783"
1921"checksum rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7540fc8b0c49f096ee9c961cda096467dce8084bec6bdca2fc83895fd9b28cb8" 1900"checksum rustc-hash 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7540fc8b0c49f096ee9c961cda096467dce8084bec6bdca2fc83895fd9b28cb8"
@@ -1937,7 +1916,7 @@ dependencies = [
1937"checksum smallvec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "44e59e0c9fa00817912ae6e4e6e3c4fe04455e75699d06eedc7d85917ed8e8f4" 1916"checksum smallvec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "44e59e0c9fa00817912ae6e4e6e3c4fe04455e75699d06eedc7d85917ed8e8f4"
1938"checksum smol_str 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)" = "34836c9a295c62c2ce3514471117c5cb269891e8421b2aafdd910050576c4d8b" 1917"checksum smol_str 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)" = "34836c9a295c62c2ce3514471117c5cb269891e8421b2aafdd910050576c4d8b"
1939"checksum superslice 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ab16ced94dbd8a46c82fd81e3ed9a8727dac2977ea869d217bcc4ea1f122e81f" 1918"checksum superslice 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ab16ced94dbd8a46c82fd81e3ed9a8727dac2977ea869d217bcc4ea1f122e81f"
1940"checksum syn 1.0.12 (registry+https://github.com/rust-lang/crates.io-index)" = "ddc157159e2a7df58cd67b1cace10b8ed256a404fb0070593f137d8ba6bef4de" 1919"checksum syn 1.0.13 (registry+https://github.com/rust-lang/crates.io-index)" = "1e4ff033220a41d1a57d8125eab57bf5263783dfdcc18688b1dacc6ce9651ef8"
1941"checksum tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9" 1920"checksum tempfile 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9"
1942"checksum termios 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "72b620c5ea021d75a735c943269bb07d30c9b77d6ac6b236bc8b5c496ef05625" 1921"checksum termios 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "72b620c5ea021d75a735c943269bb07d30c9b77d6ac6b236bc8b5c496ef05625"
1943"checksum text_unit 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e08bbcb7a3adbda0eb23431206b653bdad3d8dea311e72d36bf2215e27a42579" 1922"checksum text_unit 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e08bbcb7a3adbda0eb23431206b653bdad3d8dea311e72d36bf2215e27a42579"
@@ -1953,7 +1932,7 @@ dependencies = [
1953"checksum uuid 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9fde2f6a4bea1d6e007c4ad38c6839fa71cbb63b6dbf5b595aa38dc9b1093c11" 1932"checksum uuid 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9fde2f6a4bea1d6e007c4ad38c6839fa71cbb63b6dbf5b595aa38dc9b1093c11"
1954"checksum version_check 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "078775d0255232fb988e6fccf26ddc9d1ac274299aaedcedce21c6f72cc533ce" 1933"checksum version_check 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "078775d0255232fb988e6fccf26ddc9d1ac274299aaedcedce21c6f72cc533ce"
1955"checksum walkdir 2.2.9 (registry+https://github.com/rust-lang/crates.io-index)" = "9658c94fa8b940eab2250bd5a457f9c48b748420d71293b165c8cdbe2f55f71e" 1934"checksum walkdir 2.2.9 (registry+https://github.com/rust-lang/crates.io-index)" = "9658c94fa8b940eab2250bd5a457f9c48b748420d71293b165c8cdbe2f55f71e"
1956"checksum wasi 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b89c3ce4ce14bdc6fb6beaf9ec7928ca331de5df7e5ea278375642a2f478570d" 1935"checksum wasi 0.9.0+wasi-snapshot-preview1 (registry+https://github.com/rust-lang/crates.io-index)" = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
1957"checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a" 1936"checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a"
1958"checksum winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6" 1937"checksum winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6"
1959"checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc" 1938"checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc"
diff --git a/bors.toml b/bors.toml
index 7ffbc9294..0bc71860f 100644
--- a/bors.toml
+++ b/bors.toml
@@ -1,2 +1,7 @@
1status = ["Rust", "TypeScript"] 1status = [
2 "Rust (ubuntu-latest)",
3 "Rust (windows-latest)",
4 "Rust (macos-latest)",
5 "TypeScript"
6]
2delete_merged_branches = true 7delete_merged_branches = true
diff --git a/crates/ra_assists/src/assists/flip_binexpr.rs b/crates/ra_assists/src/assists/flip_binexpr.rs
index 386045eb0..2d91b2a7e 100644
--- a/crates/ra_assists/src/assists/flip_binexpr.rs
+++ b/crates/ra_assists/src/assists/flip_binexpr.rs
@@ -56,17 +56,7 @@ enum FlipAction {
56impl From<BinOp> for FlipAction { 56impl From<BinOp> for FlipAction {
57 fn from(op_kind: BinOp) -> Self { 57 fn from(op_kind: BinOp) -> Self {
58 match op_kind { 58 match op_kind {
59 BinOp::Assignment => FlipAction::DontFlip, 59 kind if kind.is_assignment() => FlipAction::DontFlip,
60 BinOp::AddAssign => FlipAction::DontFlip,
61 BinOp::DivAssign => FlipAction::DontFlip,
62 BinOp::MulAssign => FlipAction::DontFlip,
63 BinOp::RemAssign => FlipAction::DontFlip,
64 BinOp::ShrAssign => FlipAction::DontFlip,
65 BinOp::ShlAssign => FlipAction::DontFlip,
66 BinOp::SubAssign => FlipAction::DontFlip,
67 BinOp::BitOrAssign => FlipAction::DontFlip,
68 BinOp::BitAndAssign => FlipAction::DontFlip,
69 BinOp::BitXorAssign => FlipAction::DontFlip,
70 BinOp::GreaterTest => FlipAction::FlipAndReplaceOp("<"), 60 BinOp::GreaterTest => FlipAction::FlipAndReplaceOp("<"),
71 BinOp::GreaterEqualTest => FlipAction::FlipAndReplaceOp("<="), 61 BinOp::GreaterEqualTest => FlipAction::FlipAndReplaceOp("<="),
72 BinOp::LesserTest => FlipAction::FlipAndReplaceOp(">"), 62 BinOp::LesserTest => FlipAction::FlipAndReplaceOp(">"),
diff --git a/crates/ra_cargo_watch/src/conv/test.rs b/crates/ra_cargo_watch/src/conv/test.rs
index f77ef1b4d..6b86525b8 100644
--- a/crates/ra_cargo_watch/src/conv/test.rs
+++ b/crates/ra_cargo_watch/src/conv/test.rs
@@ -1,7 +1,9 @@
1//! This module contains the large and verbose snapshot tests for the 1//! This module contains the large and verbose snapshot tests for the
2//! conversions between `cargo check` json and LSP diagnostics. 2//! conversions between `cargo check` json and LSP diagnostics.
3#[cfg(not(windows))]
3use crate::*; 4use crate::*;
4 5
6#[cfg(not(windows))]
5fn parse_diagnostic(val: &str) -> cargo_metadata::diagnostic::Diagnostic { 7fn parse_diagnostic(val: &str) -> cargo_metadata::diagnostic::Diagnostic {
6 serde_json::from_str::<cargo_metadata::diagnostic::Diagnostic>(val).unwrap() 8 serde_json::from_str::<cargo_metadata::diagnostic::Diagnostic>(val).unwrap()
7} 9}
diff --git a/crates/ra_db/src/fixture.rs b/crates/ra_db/src/fixture.rs
index e8f335e33..30b598e9a 100644
--- a/crates/ra_db/src/fixture.rs
+++ b/crates/ra_db/src/fixture.rs
@@ -49,7 +49,7 @@ fn with_single_file(db: &mut dyn SourceDatabaseExt, text: &str) -> FileId {
49 let file_id = FileId(0); 49 let file_id = FileId(0);
50 let rel_path: RelativePathBuf = "/main.rs".into(); 50 let rel_path: RelativePathBuf = "/main.rs".into();
51 51
52 let mut source_root = SourceRoot::default(); 52 let mut source_root = SourceRoot::new_local();
53 source_root.insert_file(rel_path.clone(), file_id); 53 source_root.insert_file(rel_path.clone(), file_id);
54 54
55 let mut crate_graph = CrateGraph::default(); 55 let mut crate_graph = CrateGraph::default();
@@ -77,7 +77,7 @@ fn with_files(db: &mut dyn SourceDatabaseExt, fixture: &str) -> Option<FilePosit
77 let mut crate_deps = Vec::new(); 77 let mut crate_deps = Vec::new();
78 let mut default_crate_root: Option<FileId> = None; 78 let mut default_crate_root: Option<FileId> = None;
79 79
80 let mut source_root = SourceRoot::default(); 80 let mut source_root = SourceRoot::new_local();
81 let mut source_root_id = WORKSPACE; 81 let mut source_root_id = WORKSPACE;
82 let mut source_root_prefix: RelativePathBuf = "/".into(); 82 let mut source_root_prefix: RelativePathBuf = "/".into();
83 let mut file_id = FileId(0); 83 let mut file_id = FileId(0);
@@ -87,7 +87,7 @@ fn with_files(db: &mut dyn SourceDatabaseExt, fixture: &str) -> Option<FilePosit
87 for entry in fixture.iter() { 87 for entry in fixture.iter() {
88 let meta = match parse_meta(&entry.meta) { 88 let meta = match parse_meta(&entry.meta) {
89 ParsedMeta::Root { path } => { 89 ParsedMeta::Root { path } => {
90 let source_root = std::mem::replace(&mut source_root, SourceRoot::default()); 90 let source_root = std::mem::replace(&mut source_root, SourceRoot::new_local());
91 db.set_source_root(source_root_id, Arc::new(source_root)); 91 db.set_source_root(source_root_id, Arc::new(source_root));
92 source_root_id.0 += 1; 92 source_root_id.0 += 1;
93 source_root_prefix = path; 93 source_root_prefix = path;
diff --git a/crates/ra_db/src/input.rs b/crates/ra_db/src/input.rs
index 2a7ed20d1..07269237a 100644
--- a/crates/ra_db/src/input.rs
+++ b/crates/ra_db/src/input.rs
@@ -33,7 +33,7 @@ pub struct FileId(pub u32);
33#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)] 33#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
34pub struct SourceRootId(pub u32); 34pub struct SourceRootId(pub u32);
35 35
36#[derive(Default, Clone, Debug, PartialEq, Eq)] 36#[derive(Clone, Debug, PartialEq, Eq)]
37pub struct SourceRoot { 37pub struct SourceRoot {
38 /// Sysroot or crates.io library. 38 /// Sysroot or crates.io library.
39 /// 39 ///
@@ -44,11 +44,11 @@ pub struct SourceRoot {
44} 44}
45 45
46impl SourceRoot { 46impl SourceRoot {
47 pub fn new() -> SourceRoot { 47 pub fn new_local() -> SourceRoot {
48 Default::default() 48 SourceRoot { is_library: false, files: Default::default() }
49 } 49 }
50 pub fn new_library() -> SourceRoot { 50 pub fn new_library() -> SourceRoot {
51 SourceRoot { is_library: true, ..SourceRoot::new() } 51 SourceRoot { is_library: true, files: Default::default() }
52 } 52 }
53 pub fn insert_file(&mut self, path: RelativePathBuf, file_id: FileId) { 53 pub fn insert_file(&mut self, path: RelativePathBuf, file_id: FileId) {
54 self.files.insert(path, file_id); 54 self.files.insert(path, file_id);
diff --git a/crates/ra_hir/src/code_model.rs b/crates/ra_hir/src/code_model.rs
index 488f74cfb..cc42068a1 100644
--- a/crates/ra_hir/src/code_model.rs
+++ b/crates/ra_hir/src/code_model.rs
@@ -25,6 +25,7 @@ use hir_ty::{
25 TraitEnvironment, Ty, TyDefId, TypeCtor, TypeWalk, 25 TraitEnvironment, Ty, TyDefId, TypeCtor, TypeWalk,
26}; 26};
27use ra_db::{CrateId, Edition, FileId}; 27use ra_db::{CrateId, Edition, FileId};
28use ra_prof::profile;
28use ra_syntax::ast; 29use ra_syntax::ast;
29 30
30use crate::{ 31use crate::{
@@ -189,6 +190,7 @@ impl Module {
189 } 190 }
190 191
191 pub fn diagnostics(self, db: &impl HirDatabase, sink: &mut DiagnosticSink) { 192 pub fn diagnostics(self, db: &impl HirDatabase, sink: &mut DiagnosticSink) {
193 let _p = profile("Module::diagnostics");
192 db.crate_def_map(self.id.krate).add_diagnostics(db, self.id.local_id, sink); 194 db.crate_def_map(self.id.krate).add_diagnostics(db, self.id.local_id, sink);
193 for decl in self.declarations(db) { 195 for decl in self.declarations(db) {
194 match decl { 196 match decl {
@@ -507,6 +509,7 @@ impl Function {
507 } 509 }
508 510
509 pub fn diagnostics(self, db: &impl HirDatabase, sink: &mut DiagnosticSink) { 511 pub fn diagnostics(self, db: &impl HirDatabase, sink: &mut DiagnosticSink) {
512 let _p = profile("Function::diagnostics");
510 let infer = db.infer(self.id.into()); 513 let infer = db.infer(self.id.into());
511 infer.add_diagnostics(db, self.id, sink); 514 infer.add_diagnostics(db, self.id, sink);
512 let mut validator = ExprValidator::new(self.id, infer, sink); 515 let mut validator = ExprValidator::new(self.id, infer, sink);
diff --git a/crates/ra_hir/src/db.rs b/crates/ra_hir/src/db.rs
index f5ffd64fa..e6079b88d 100644
--- a/crates/ra_hir/src/db.rs
+++ b/crates/ra_hir/src/db.rs
@@ -1,21 +1,21 @@
1//! FIXME: write short doc here 1//! FIXME: write short doc here
2 2
3pub use hir_def::db::{ 3pub use hir_def::db::{
4 BodyQuery, BodyWithSourceMapQuery, ConstDataQuery, CrateDefMapQuery, CrateLangItemsQuery, 4 BodyQuery, BodyWithSourceMapQuery, ComputeCrateDefMapQuery, ConstDataQuery,
5 DefDatabase, DefDatabaseStorage, DocumentationQuery, EnumDataQuery, ExprScopesQuery, 5 CrateLangItemsQuery, DefDatabase, DefDatabaseStorage, DocumentationQuery, EnumDataQuery,
6 FunctionDataQuery, GenericParamsQuery, ImplDataQuery, InternDatabase, InternDatabaseStorage, 6 ExprScopesQuery, FunctionDataQuery, GenericParamsQuery, ImplDataQuery, InternDatabase,
7 LangItemQuery, ModuleLangItemsQuery, RawItemsQuery, StaticDataQuery, StructDataQuery, 7 InternDatabaseStorage, LangItemQuery, ModuleLangItemsQuery, RawItemsQuery, StaticDataQuery,
8 TraitDataQuery, TypeAliasDataQuery, 8 StructDataQuery, TraitDataQuery, TypeAliasDataQuery,
9}; 9};
10pub use hir_expand::db::{ 10pub use hir_expand::db::{
11 AstDatabase, AstDatabaseStorage, AstIdMapQuery, MacroArgQuery, MacroDefQuery, MacroExpandQuery, 11 AstDatabase, AstDatabaseStorage, AstIdMapQuery, MacroArgQuery, MacroDefQuery, MacroExpandQuery,
12 ParseMacroQuery, 12 ParseMacroQuery,
13}; 13};
14pub use hir_ty::db::{ 14pub use hir_ty::db::{
15 AssociatedTyDataQuery, CallableItemSignatureQuery, FieldTypesQuery, GenericDefaultsQuery, 15 AssociatedTyDataQuery, CallableItemSignatureQuery, DoInferQuery, FieldTypesQuery,
16 GenericPredicatesQuery, HirDatabase, HirDatabaseStorage, ImplDatumQuery, ImplsForTraitQuery, 16 GenericDefaultsQuery, GenericPredicatesQuery, HirDatabase, HirDatabaseStorage, ImplDatumQuery,
17 ImplsInCrateQuery, InferQuery, StructDatumQuery, TraitDatumQuery, TraitSolveQuery, TyQuery, 17 ImplsForTraitQuery, ImplsInCrateQuery, StructDatumQuery, TraitDatumQuery, TraitSolveQuery,
18 ValueTyQuery, 18 TyQuery, ValueTyQuery,
19}; 19};
20 20
21#[test] 21#[test]
diff --git a/crates/ra_hir_def/src/db.rs b/crates/ra_hir_def/src/db.rs
index c55fd4111..da273eb11 100644
--- a/crates/ra_hir_def/src/db.rs
+++ b/crates/ra_hir_def/src/db.rs
@@ -3,6 +3,7 @@ use std::sync::Arc;
3 3
4use hir_expand::{db::AstDatabase, HirFileId}; 4use hir_expand::{db::AstDatabase, HirFileId};
5use ra_db::{salsa, CrateId, SourceDatabase}; 5use ra_db::{salsa, CrateId, SourceDatabase};
6use ra_prof::profile;
6use ra_syntax::SmolStr; 7use ra_syntax::SmolStr;
7 8
8use crate::{ 9use crate::{
@@ -46,9 +47,12 @@ pub trait DefDatabase: InternDatabase + AstDatabase {
46 #[salsa::invoke(RawItems::raw_items_query)] 47 #[salsa::invoke(RawItems::raw_items_query)]
47 fn raw_items(&self, file_id: HirFileId) -> Arc<RawItems>; 48 fn raw_items(&self, file_id: HirFileId) -> Arc<RawItems>;
48 49
49 #[salsa::invoke(CrateDefMap::crate_def_map_query)] 50 #[salsa::transparent]
50 fn crate_def_map(&self, krate: CrateId) -> Arc<CrateDefMap>; 51 fn crate_def_map(&self, krate: CrateId) -> Arc<CrateDefMap>;
51 52
53 #[salsa::invoke(CrateDefMap::compute_crate_def_map_query)]
54 fn compute_crate_def_map(&self, krate: CrateId) -> Arc<CrateDefMap>;
55
52 #[salsa::invoke(StructData::struct_data_query)] 56 #[salsa::invoke(StructData::struct_data_query)]
53 fn struct_data(&self, id: StructId) -> Arc<StructData>; 57 fn struct_data(&self, id: StructId) -> Arc<StructData>;
54 #[salsa::invoke(StructData::union_data_query)] 58 #[salsa::invoke(StructData::union_data_query)]
@@ -104,3 +108,8 @@ pub trait DefDatabase: InternDatabase + AstDatabase {
104 #[salsa::invoke(Documentation::documentation_query)] 108 #[salsa::invoke(Documentation::documentation_query)]
105 fn documentation(&self, def: AttrDefId) -> Option<Documentation>; 109 fn documentation(&self, def: AttrDefId) -> Option<Documentation>;
106} 110}
111
112fn crate_def_map(db: &impl DefDatabase, krate: CrateId) -> Arc<CrateDefMap> {
113 let _p = profile("crate_def_map");
114 db.compute_crate_def_map(krate)
115}
diff --git a/crates/ra_hir_def/src/nameres.rs b/crates/ra_hir_def/src/nameres.rs
index 5d4ca73a3..4d210eab1 100644
--- a/crates/ra_hir_def/src/nameres.rs
+++ b/crates/ra_hir_def/src/nameres.rs
@@ -172,13 +172,13 @@ pub struct ModuleData {
172} 172}
173 173
174impl CrateDefMap { 174impl CrateDefMap {
175 pub(crate) fn crate_def_map_query( 175 pub(crate) fn compute_crate_def_map_query(
176 // Note that this doesn't have `+ AstDatabase`! 176 // Note that this doesn't have `+ AstDatabase`!
177 // This gurantess that `CrateDefMap` is stable across reparses. 177 // This gurantess that `CrateDefMap` is stable across reparses.
178 db: &impl DefDatabase, 178 db: &impl DefDatabase,
179 krate: CrateId, 179 krate: CrateId,
180 ) -> Arc<CrateDefMap> { 180 ) -> Arc<CrateDefMap> {
181 let _p = profile("crate_def_map_query"); 181 let _p = profile("compute_crate_def_map");
182 let def_map = { 182 let def_map = {
183 let crate_graph = db.crate_graph(); 183 let crate_graph = db.crate_graph();
184 let edition = crate_graph.edition(krate); 184 let edition = crate_graph.edition(krate);
diff --git a/crates/ra_hir_def/src/nameres/collector.rs b/crates/ra_hir_def/src/nameres/collector.rs
index 8a22b0585..35b852ee2 100644
--- a/crates/ra_hir_def/src/nameres/collector.rs
+++ b/crates/ra_hir_def/src/nameres/collector.rs
@@ -45,7 +45,6 @@ pub(super) fn collect_defs(db: &impl DefDatabase, mut def_map: CrateDefMap) -> C
45 // If the dependency defines a prelude, we overwrite an already defined 45 // If the dependency defines a prelude, we overwrite an already defined
46 // prelude. This is necessary to import the "std" prelude if a crate 46 // prelude. This is necessary to import the "std" prelude if a crate
47 // depends on both "core" and "std". 47 // depends on both "core" and "std".
48 let dep_def_map = db.crate_def_map(dep.crate_id);
49 if dep_def_map.prelude.is_some() { 48 if dep_def_map.prelude.is_some() {
50 def_map.prelude = dep_def_map.prelude; 49 def_map.prelude = dep_def_map.prelude;
51 } 50 }
diff --git a/crates/ra_hir_expand/src/name.rs b/crates/ra_hir_expand/src/name.rs
index e62693b68..b3fa1efba 100644
--- a/crates/ra_hir_expand/src/name.rs
+++ b/crates/ra_hir_expand/src/name.rs
@@ -93,7 +93,10 @@ impl AsName for ast::FieldKind {
93 fn as_name(&self) -> Name { 93 fn as_name(&self) -> Name {
94 match self { 94 match self {
95 ast::FieldKind::Name(nr) => nr.as_name(), 95 ast::FieldKind::Name(nr) => nr.as_name(),
96 ast::FieldKind::Index(idx) => Name::new_tuple_field(idx.text().parse().unwrap()), 96 ast::FieldKind::Index(idx) => {
97 let idx = idx.text().parse::<usize>().unwrap_or(0);
98 Name::new_tuple_field(idx)
99 }
97 } 100 }
98 } 101 }
99} 102}
diff --git a/crates/ra_hir_ty/src/db.rs b/crates/ra_hir_ty/src/db.rs
index d52f65b83..eb521c7a0 100644
--- a/crates/ra_hir_ty/src/db.rs
+++ b/crates/ra_hir_ty/src/db.rs
@@ -7,6 +7,7 @@ use hir_def::{
7}; 7};
8use ra_arena::map::ArenaMap; 8use ra_arena::map::ArenaMap;
9use ra_db::{salsa, CrateId}; 9use ra_db::{salsa, CrateId};
10use ra_prof::profile;
10 11
11use crate::{ 12use crate::{
12 method_resolution::CrateImplBlocks, 13 method_resolution::CrateImplBlocks,
@@ -18,9 +19,12 @@ use crate::{
18#[salsa::query_group(HirDatabaseStorage)] 19#[salsa::query_group(HirDatabaseStorage)]
19#[salsa::requires(salsa::Database)] 20#[salsa::requires(salsa::Database)]
20pub trait HirDatabase: DefDatabase { 21pub trait HirDatabase: DefDatabase {
21 #[salsa::invoke(crate::infer_query)] 22 #[salsa::transparent]
22 fn infer(&self, def: DefWithBodyId) -> Arc<InferenceResult>; 23 fn infer(&self, def: DefWithBodyId) -> Arc<InferenceResult>;
23 24
25 #[salsa::invoke(crate::do_infer_query)]
26 fn do_infer(&self, def: DefWithBodyId) -> Arc<InferenceResult>;
27
24 #[salsa::invoke(crate::lower::ty_query)] 28 #[salsa::invoke(crate::lower::ty_query)]
25 #[salsa::cycle(crate::lower::ty_recover)] 29 #[salsa::cycle(crate::lower::ty_recover)]
26 fn ty(&self, def: TyDefId) -> Ty; 30 fn ty(&self, def: TyDefId) -> Ty;
@@ -104,6 +108,11 @@ pub trait HirDatabase: DefDatabase {
104 ) -> Option<crate::traits::Solution>; 108 ) -> Option<crate::traits::Solution>;
105} 109}
106 110
111fn infer(db: &impl HirDatabase, def: DefWithBodyId) -> Arc<InferenceResult> {
112 let _p = profile("infer");
113 db.do_infer(def)
114}
115
107#[test] 116#[test]
108fn hir_database_is_object_safe() { 117fn hir_database_is_object_safe() {
109 fn _assert_object_safe(_: &dyn HirDatabase) {} 118 fn _assert_object_safe(_: &dyn HirDatabase) {}
diff --git a/crates/ra_hir_ty/src/infer.rs b/crates/ra_hir_ty/src/infer.rs
index 37e69599d..e2eda3134 100644
--- a/crates/ra_hir_ty/src/infer.rs
+++ b/crates/ra_hir_ty/src/infer.rs
@@ -62,8 +62,8 @@ mod pat;
62mod coerce; 62mod coerce;
63 63
64/// The entry point of type inference. 64/// The entry point of type inference.
65pub fn infer_query(db: &impl HirDatabase, def: DefWithBodyId) -> Arc<InferenceResult> { 65pub fn do_infer_query(db: &impl HirDatabase, def: DefWithBodyId) -> Arc<InferenceResult> {
66 let _p = profile("infer_query"); 66 let _p = profile("do_infer");
67 let resolver = def.resolver(db); 67 let resolver = def.resolver(db);
68 let mut ctx = InferenceContext::new(db, def, resolver); 68 let mut ctx = InferenceContext::new(db, def, resolver);
69 69
diff --git a/crates/ra_hir_ty/src/lib.rs b/crates/ra_hir_ty/src/lib.rs
index 55b6dd836..d63f862dc 100644
--- a/crates/ra_hir_ty/src/lib.rs
+++ b/crates/ra_hir_ty/src/lib.rs
@@ -58,7 +58,7 @@ use crate::{
58use display::{HirDisplay, HirFormatter}; 58use display::{HirDisplay, HirFormatter};
59 59
60pub use autoderef::autoderef; 60pub use autoderef::autoderef;
61pub use infer::{infer_query, InferTy, InferenceResult}; 61pub use infer::{do_infer_query, InferTy, InferenceResult};
62pub use lower::CallableDef; 62pub use lower::CallableDef;
63pub use lower::{callable_item_sig, TyDefId, ValueTyDefId}; 63pub use lower::{callable_item_sig, TyDefId, ValueTyDefId};
64pub use traits::{InEnvironment, Obligation, ProjectionPredicate, TraitEnvironment}; 64pub use traits::{InEnvironment, Obligation, ProjectionPredicate, TraitEnvironment};
diff --git a/crates/ra_hir_ty/src/lower.rs b/crates/ra_hir_ty/src/lower.rs
index af3db2e1d..2c2ecee9c 100644
--- a/crates/ra_hir_ty/src/lower.rs
+++ b/crates/ra_hir_ty/src/lower.rs
@@ -331,7 +331,7 @@ pub(super) fn substs_from_path_segment(
331 if let Some(generic_args) = &segment.args_and_bindings { 331 if let Some(generic_args) = &segment.args_and_bindings {
332 // if args are provided, it should be all of them, but we can't rely on that 332 // if args are provided, it should be all of them, but we can't rely on that
333 let self_param_correction = if add_self_param { 1 } else { 0 }; 333 let self_param_correction = if add_self_param { 1 } else { 0 };
334 let child_len = child_len + self_param_correction; 334 let child_len = child_len - self_param_correction;
335 for arg in generic_args.args.iter().take(child_len) { 335 for arg in generic_args.args.iter().take(child_len) {
336 match arg { 336 match arg {
337 GenericArg::Type(type_ref) => { 337 GenericArg::Type(type_ref) => {
diff --git a/crates/ra_hir_ty/src/tests/regression.rs b/crates/ra_hir_ty/src/tests/regression.rs
index 8b3aa8564..13c5f62e4 100644
--- a/crates/ra_hir_ty/src/tests/regression.rs
+++ b/crates/ra_hir_ty/src/tests/regression.rs
@@ -365,3 +365,20 @@ fn issue_2669() {
365 "### 365 "###
366 ) 366 )
367} 367}
368
369#[test]
370fn issue_2705() {
371 assert_snapshot!(
372 infer(r#"
373trait Trait {}
374fn test() {
375 <Trait<u32>>::foo()
376}
377"#),
378 @r###"
379 [26; 53) '{ ...oo() }': ()
380 [32; 49) '<Trait...>::foo': {unknown}
381 [32; 51) '<Trait...:foo()': ()
382 "###
383 );
384}
diff --git a/crates/ra_ide/Cargo.toml b/crates/ra_ide/Cargo.toml
index e3439ae31..2c9f9dce0 100644
--- a/crates/ra_ide/Cargo.toml
+++ b/crates/ra_ide/Cargo.toml
@@ -13,6 +13,7 @@ wasm = []
13[dependencies] 13[dependencies]
14either = "1.5" 14either = "1.5"
15format-buf = "1.0.0" 15format-buf = "1.0.0"
16indexmap = "1.3.0"
16itertools = "0.8.0" 17itertools = "0.8.0"
17join_to_string = "0.1.3" 18join_to_string = "0.1.3"
18log = "0.4.5" 19log = "0.4.5"
diff --git a/crates/ra_ide/src/call_hierarchy.rs b/crates/ra_ide/src/call_hierarchy.rs
new file mode 100644
index 000000000..1cb712e32
--- /dev/null
+++ b/crates/ra_ide/src/call_hierarchy.rs
@@ -0,0 +1,337 @@
1//! Entry point for call-hierarchy
2
3use indexmap::IndexMap;
4
5use hir::db::AstDatabase;
6use ra_syntax::{
7 ast::{self, DocCommentsOwner},
8 match_ast, AstNode, TextRange,
9};
10
11use crate::{
12 call_info::FnCallNode,
13 db::RootDatabase,
14 display::{ShortLabel, ToNav},
15 expand::descend_into_macros,
16 goto_definition, references, FilePosition, NavigationTarget, RangeInfo,
17};
18
19#[derive(Debug, Clone)]
20pub struct CallItem {
21 pub target: NavigationTarget,
22 pub ranges: Vec<TextRange>,
23}
24
25impl CallItem {
26 #[cfg(test)]
27 pub(crate) fn assert_match(&self, expected: &str) {
28 let actual = self.debug_render();
29 test_utils::assert_eq_text!(expected.trim(), actual.trim(),);
30 }
31
32 #[cfg(test)]
33 pub(crate) fn debug_render(&self) -> String {
34 format!("{} : {:?}", self.target.debug_render(), self.ranges)
35 }
36}
37
38pub(crate) fn call_hierarchy(
39 db: &RootDatabase,
40 position: FilePosition,
41) -> Option<RangeInfo<Vec<NavigationTarget>>> {
42 goto_definition::goto_definition(db, position)
43}
44
45pub(crate) fn incoming_calls(db: &RootDatabase, position: FilePosition) -> Option<Vec<CallItem>> {
46 // 1. Find all refs
47 // 2. Loop through refs and determine unique fndef. This will become our `from: CallHierarchyItem,` in the reply.
48 // 3. Add ranges relative to the start of the fndef.
49 let refs = references::find_all_refs(db, position, None)?;
50
51 let mut calls = CallLocations::default();
52
53 for reference in refs.info.references() {
54 let file_id = reference.file_range.file_id;
55 let file = db.parse_or_expand(file_id.into())?;
56 let token = file.token_at_offset(reference.file_range.range.start()).next()?;
57 let token = descend_into_macros(db, file_id, token);
58 let syntax = token.value.parent();
59
60 // This target is the containing function
61 if let Some(nav) = syntax.ancestors().find_map(|node| {
62 match_ast! {
63 match node {
64 ast::FnDef(it) => {
65 Some(NavigationTarget::from_named(
66 db,
67 token.with_value(&it),
68 it.doc_comment_text(),
69 it.short_label(),
70 ))
71 },
72 _ => { None },
73 }
74 }
75 }) {
76 let relative_range = reference.file_range.range;
77 calls.add(&nav, relative_range);
78 }
79 }
80
81 Some(calls.into_items())
82}
83
84pub(crate) fn outgoing_calls(db: &RootDatabase, position: FilePosition) -> Option<Vec<CallItem>> {
85 let file_id = position.file_id;
86 let file = db.parse_or_expand(file_id.into())?;
87 let token = file.token_at_offset(position.offset).next()?;
88 let token = descend_into_macros(db, file_id, token);
89 let syntax = token.value.parent();
90
91 let mut calls = CallLocations::default();
92
93 syntax
94 .descendants()
95 .filter_map(|node| FnCallNode::with_node_exact(&node))
96 .filter_map(|call_node| {
97 let name_ref = call_node.name_ref()?;
98 let name_ref = token.with_value(name_ref.syntax());
99
100 let analyzer = hir::SourceAnalyzer::new(db, name_ref, None);
101
102 if let Some(func_target) = match &call_node {
103 FnCallNode::CallExpr(expr) => {
104 //FIXME: Type::as_callable is broken
105 let callable_def = analyzer.type_of(db, &expr.expr()?)?.as_callable()?;
106 match callable_def {
107 hir::CallableDef::FunctionId(it) => {
108 let fn_def: hir::Function = it.into();
109 let nav = fn_def.to_nav(db);
110 Some(nav)
111 }
112 _ => None,
113 }
114 }
115 FnCallNode::MethodCallExpr(expr) => {
116 let function = analyzer.resolve_method_call(&expr)?;
117 Some(function.to_nav(db))
118 }
119 FnCallNode::MacroCallExpr(expr) => {
120 let macro_def = analyzer.resolve_macro_call(db, name_ref.with_value(&expr))?;
121 Some(macro_def.to_nav(db))
122 }
123 } {
124 Some((func_target.clone(), name_ref.value.text_range()))
125 } else {
126 None
127 }
128 })
129 .for_each(|(nav, range)| calls.add(&nav, range));
130
131 Some(calls.into_items())
132}
133
134#[derive(Default)]
135struct CallLocations {
136 funcs: IndexMap<NavigationTarget, Vec<TextRange>>,
137}
138
139impl CallLocations {
140 fn add(&mut self, target: &NavigationTarget, range: TextRange) {
141 self.funcs.entry(target.clone()).or_default().push(range);
142 }
143
144 fn into_items(self) -> Vec<CallItem> {
145 self.funcs.into_iter().map(|(target, ranges)| CallItem { target, ranges }).collect()
146 }
147}
148
149#[cfg(test)]
150mod tests {
151 use ra_db::FilePosition;
152
153 use crate::mock_analysis::analysis_and_position;
154
155 fn check_hierarchy(
156 fixture: &str,
157 expected: &str,
158 expected_incoming: &[&str],
159 expected_outgoing: &[&str],
160 ) {
161 let (analysis, pos) = analysis_and_position(fixture);
162
163 let mut navs = analysis.call_hierarchy(pos).unwrap().unwrap().info;
164 assert_eq!(navs.len(), 1);
165 let nav = navs.pop().unwrap();
166 nav.assert_match(expected);
167
168 let item_pos = FilePosition { file_id: nav.file_id(), offset: nav.range().start() };
169 let incoming_calls = analysis.incoming_calls(item_pos).unwrap().unwrap();
170 assert_eq!(incoming_calls.len(), expected_incoming.len());
171
172 for call in 0..incoming_calls.len() {
173 incoming_calls[call].assert_match(expected_incoming[call]);
174 }
175
176 let outgoing_calls = analysis.outgoing_calls(item_pos).unwrap().unwrap();
177 assert_eq!(outgoing_calls.len(), expected_outgoing.len());
178
179 for call in 0..outgoing_calls.len() {
180 outgoing_calls[call].assert_match(expected_outgoing[call]);
181 }
182 }
183
184 #[test]
185 fn test_call_hierarchy_on_ref() {
186 check_hierarchy(
187 r#"
188 //- /lib.rs
189 fn callee() {}
190 fn caller() {
191 call<|>ee();
192 }
193 "#,
194 "callee FN_DEF FileId(1) [0; 14) [3; 9)",
195 &["caller FN_DEF FileId(1) [15; 44) [18; 24) : [[33; 39)]"],
196 &[],
197 );
198 }
199
200 #[test]
201 fn test_call_hierarchy_on_def() {
202 check_hierarchy(
203 r#"
204 //- /lib.rs
205 fn call<|>ee() {}
206 fn caller() {
207 callee();
208 }
209 "#,
210 "callee FN_DEF FileId(1) [0; 14) [3; 9)",
211 &["caller FN_DEF FileId(1) [15; 44) [18; 24) : [[33; 39)]"],
212 &[],
213 );
214 }
215
216 #[test]
217 fn test_call_hierarchy_in_same_fn() {
218 check_hierarchy(
219 r#"
220 //- /lib.rs
221 fn callee() {}
222 fn caller() {
223 call<|>ee();
224 callee();
225 }
226 "#,
227 "callee FN_DEF FileId(1) [0; 14) [3; 9)",
228 &["caller FN_DEF FileId(1) [15; 58) [18; 24) : [[33; 39), [47; 53)]"],
229 &[],
230 );
231 }
232
233 #[test]
234 fn test_call_hierarchy_in_different_fn() {
235 check_hierarchy(
236 r#"
237 //- /lib.rs
238 fn callee() {}
239 fn caller1() {
240 call<|>ee();
241 }
242
243 fn caller2() {
244 callee();
245 }
246 "#,
247 "callee FN_DEF FileId(1) [0; 14) [3; 9)",
248 &[
249 "caller1 FN_DEF FileId(1) [15; 45) [18; 25) : [[34; 40)]",
250 "caller2 FN_DEF FileId(1) [46; 76) [49; 56) : [[65; 71)]",
251 ],
252 &[],
253 );
254 }
255
256 #[test]
257 fn test_call_hierarchy_in_different_files() {
258 check_hierarchy(
259 r#"
260 //- /lib.rs
261 mod foo;
262 use foo::callee;
263
264 fn caller() {
265 call<|>ee();
266 }
267
268 //- /foo/mod.rs
269 pub fn callee() {}
270 "#,
271 "callee FN_DEF FileId(2) [0; 18) [7; 13)",
272 &["caller FN_DEF FileId(1) [26; 55) [29; 35) : [[44; 50)]"],
273 &[],
274 );
275 }
276
277 #[test]
278 fn test_call_hierarchy_outgoing() {
279 check_hierarchy(
280 r#"
281 //- /lib.rs
282 fn callee() {}
283 fn call<|>er() {
284 callee();
285 callee();
286 }
287 "#,
288 "caller FN_DEF FileId(1) [15; 58) [18; 24)",
289 &[],
290 &["callee FN_DEF FileId(1) [0; 14) [3; 9) : [[33; 39), [47; 53)]"],
291 );
292 }
293
294 #[test]
295 fn test_call_hierarchy_outgoing_in_different_files() {
296 check_hierarchy(
297 r#"
298 //- /lib.rs
299 mod foo;
300 use foo::callee;
301
302 fn call<|>er() {
303 callee();
304 }
305
306 //- /foo/mod.rs
307 pub fn callee() {}
308 "#,
309 "caller FN_DEF FileId(1) [26; 55) [29; 35)",
310 &[],
311 &["callee FN_DEF FileId(2) [0; 18) [7; 13) : [[44; 50)]"],
312 );
313 }
314
315 #[test]
316 fn test_call_hierarchy_incoming_outgoing() {
317 check_hierarchy(
318 r#"
319 //- /lib.rs
320 fn caller1() {
321 call<|>er2();
322 }
323
324 fn caller2() {
325 caller3();
326 }
327
328 fn caller3() {
329
330 }
331 "#,
332 "caller2 FN_DEF FileId(1) [32; 63) [35; 42)",
333 &["caller1 FN_DEF FileId(1) [0; 31) [3; 10) : [[19; 26)]"],
334 &["caller3 FN_DEF FileId(1) [64; 80) [67; 74) : [[51; 58)]"],
335 );
336 }
337}
diff --git a/crates/ra_ide/src/call_info.rs b/crates/ra_ide/src/call_info.rs
index 2c2b6fa48..a7023529b 100644
--- a/crates/ra_ide/src/call_info.rs
+++ b/crates/ra_ide/src/call_info.rs
@@ -88,7 +88,7 @@ pub(crate) fn call_info(db: &RootDatabase, position: FilePosition) -> Option<Cal
88} 88}
89 89
90#[derive(Debug)] 90#[derive(Debug)]
91enum FnCallNode { 91pub(crate) enum FnCallNode {
92 CallExpr(ast::CallExpr), 92 CallExpr(ast::CallExpr),
93 MethodCallExpr(ast::MethodCallExpr), 93 MethodCallExpr(ast::MethodCallExpr),
94 MacroCallExpr(ast::MacroCall), 94 MacroCallExpr(ast::MacroCall),
@@ -108,7 +108,18 @@ impl FnCallNode {
108 }) 108 })
109 } 109 }
110 110
111 fn name_ref(&self) -> Option<ast::NameRef> { 111 pub(crate) fn with_node_exact(node: &SyntaxNode) -> Option<FnCallNode> {
112 match_ast! {
113 match node {
114 ast::CallExpr(it) => { Some(FnCallNode::CallExpr(it)) },
115 ast::MethodCallExpr(it) => { Some(FnCallNode::MethodCallExpr(it)) },
116 ast::MacroCall(it) => { Some(FnCallNode::MacroCallExpr(it)) },
117 _ => { None },
118 }
119 }
120 }
121
122 pub(crate) fn name_ref(&self) -> Option<ast::NameRef> {
112 match self { 123 match self {
113 FnCallNode::CallExpr(call_expr) => Some(match call_expr.expr()? { 124 FnCallNode::CallExpr(call_expr) => Some(match call_expr.expr()? {
114 ast::Expr::PathExpr(path_expr) => path_expr.path()?.segment()?.name_ref()?, 125 ast::Expr::PathExpr(path_expr) => path_expr.path()?.segment()?.name_ref()?,
diff --git a/crates/ra_ide/src/change.rs b/crates/ra_ide/src/change.rs
index 387a9cafb..b0aa2c8e0 100644
--- a/crates/ra_ide/src/change.rs
+++ b/crates/ra_ide/src/change.rs
@@ -176,7 +176,8 @@ impl RootDatabase {
176 if !change.new_roots.is_empty() { 176 if !change.new_roots.is_empty() {
177 let mut local_roots = Vec::clone(&self.local_roots()); 177 let mut local_roots = Vec::clone(&self.local_roots());
178 for (root_id, is_local) in change.new_roots { 178 for (root_id, is_local) in change.new_roots {
179 let root = if is_local { SourceRoot::new() } else { SourceRoot::new_library() }; 179 let root =
180 if is_local { SourceRoot::new_local() } else { SourceRoot::new_library() };
180 let durability = durability(&root); 181 let durability = durability(&root);
181 self.set_source_root_with_durability(root_id, Arc::new(root), durability); 182 self.set_source_root_with_durability(root_id, Arc::new(root), durability);
182 if is_local { 183 if is_local {
@@ -201,7 +202,7 @@ impl RootDatabase {
201 libraries.push(library.root_id); 202 libraries.push(library.root_id);
202 self.set_source_root_with_durability( 203 self.set_source_root_with_durability(
203 library.root_id, 204 library.root_id,
204 Default::default(), 205 Arc::new(SourceRoot::new_library()),
205 Durability::HIGH, 206 Durability::HIGH,
206 ); 207 );
207 self.set_library_symbols_with_durability( 208 self.set_library_symbols_with_durability(
@@ -273,7 +274,7 @@ impl RootDatabase {
273 self.query(hir::db::BodyWithSourceMapQuery).sweep(sweep); 274 self.query(hir::db::BodyWithSourceMapQuery).sweep(sweep);
274 275
275 self.query(hir::db::ExprScopesQuery).sweep(sweep); 276 self.query(hir::db::ExprScopesQuery).sweep(sweep);
276 self.query(hir::db::InferQuery).sweep(sweep); 277 self.query(hir::db::DoInferQuery).sweep(sweep);
277 self.query(hir::db::BodyQuery).sweep(sweep); 278 self.query(hir::db::BodyQuery).sweep(sweep);
278 } 279 }
279 280
@@ -309,7 +310,7 @@ impl RootDatabase {
309 hir::db::EnumDataQuery 310 hir::db::EnumDataQuery
310 hir::db::TraitDataQuery 311 hir::db::TraitDataQuery
311 hir::db::RawItemsQuery 312 hir::db::RawItemsQuery
312 hir::db::CrateDefMapQuery 313 hir::db::ComputeCrateDefMapQuery
313 hir::db::GenericParamsQuery 314 hir::db::GenericParamsQuery
314 hir::db::FunctionDataQuery 315 hir::db::FunctionDataQuery
315 hir::db::TypeAliasDataQuery 316 hir::db::TypeAliasDataQuery
@@ -320,7 +321,7 @@ impl RootDatabase {
320 hir::db::LangItemQuery 321 hir::db::LangItemQuery
321 hir::db::DocumentationQuery 322 hir::db::DocumentationQuery
322 hir::db::ExprScopesQuery 323 hir::db::ExprScopesQuery
323 hir::db::InferQuery 324 hir::db::DoInferQuery
324 hir::db::TyQuery 325 hir::db::TyQuery
325 hir::db::ValueTyQuery 326 hir::db::ValueTyQuery
326 hir::db::FieldTypesQuery 327 hir::db::FieldTypesQuery
diff --git a/crates/ra_ide/src/diagnostics.rs b/crates/ra_ide/src/diagnostics.rs
index c50a70d99..478368529 100644
--- a/crates/ra_ide/src/diagnostics.rs
+++ b/crates/ra_ide/src/diagnostics.rs
@@ -64,22 +64,36 @@ pub(crate) fn diagnostics(db: &RootDatabase, file_id: FileId) -> Vec<Diagnostic>
64 }) 64 })
65 }) 65 })
66 .on::<hir::diagnostics::MissingFields, _>(|d| { 66 .on::<hir::diagnostics::MissingFields, _>(|d| {
67 let mut field_list = d.ast(db); 67 // Note that although we could add a diagnostics to
68 for f in d.missed_fields.iter() { 68 // fill the missing tuple field, e.g :
69 let field = make::record_field(make::name_ref(&f.to_string()), Some(make::expr_unit())); 69 // `struct A(usize);`
70 field_list = field_list.append_field(&field); 70 // `let a = A { 0: () }`
71 } 71 // but it is uncommon usage and it should not be encouraged.
72 72 let fix = if d.missed_fields.iter().any(|it| it.as_tuple_index().is_some()) {
73 let mut builder = TextEditBuilder::default(); 73 None
74 algo::diff(&d.ast(db).syntax(), &field_list.syntax()).into_text_edit(&mut builder); 74 } else {
75 let mut field_list = d.ast(db);
76 for f in d.missed_fields.iter() {
77 let field =
78 make::record_field(make::name_ref(&f.to_string()), Some(make::expr_unit()));
79 field_list = field_list.append_field(&field);
80 }
81
82 let mut builder = TextEditBuilder::default();
83 algo::diff(&d.ast(db).syntax(), &field_list.syntax()).into_text_edit(&mut builder);
84
85 Some(SourceChange::source_file_edit_from(
86 "fill struct fields",
87 file_id,
88 builder.finish(),
89 ))
90 };
75 91
76 let fix =
77 SourceChange::source_file_edit_from("fill struct fields", file_id, builder.finish());
78 res.borrow_mut().push(Diagnostic { 92 res.borrow_mut().push(Diagnostic {
79 range: d.highlight_range(), 93 range: d.highlight_range(),
80 message: d.message(), 94 message: d.message(),
81 severity: Severity::Error, 95 severity: Severity::Error,
82 fix: Some(fix), 96 fix,
83 }) 97 })
84 }) 98 })
85 .on::<hir::diagnostics::MissingOkInTailExpr, _>(|d| { 99 .on::<hir::diagnostics::MissingOkInTailExpr, _>(|d| {
diff --git a/crates/ra_ide/src/display/navigation_target.rs b/crates/ra_ide/src/display/navigation_target.rs
index b9ae67828..f2e45fa31 100644
--- a/crates/ra_ide/src/display/navigation_target.rs
+++ b/crates/ra_ide/src/display/navigation_target.rs
@@ -19,7 +19,7 @@ use super::short_label::ShortLabel;
19/// 19///
20/// Typically, a `NavigationTarget` corresponds to some element in the source 20/// Typically, a `NavigationTarget` corresponds to some element in the source
21/// code, like a function or a struct, but this is not strictly required. 21/// code, like a function or a struct, but this is not strictly required.
22#[derive(Debug, Clone)] 22#[derive(Debug, Clone, PartialEq, Eq, Hash)]
23pub struct NavigationTarget { 23pub struct NavigationTarget {
24 file_id: FileId, 24 file_id: FileId,
25 name: SmolStr, 25 name: SmolStr,
diff --git a/crates/ra_ide/src/expand.rs b/crates/ra_ide/src/expand.rs
index 7a22bb0a4..b82259a3d 100644
--- a/crates/ra_ide/src/expand.rs
+++ b/crates/ra_ide/src/expand.rs
@@ -76,14 +76,15 @@ pub(crate) fn descend_into_macros(
76) -> InFile<SyntaxToken> { 76) -> InFile<SyntaxToken> {
77 let src = InFile::new(file_id.into(), token); 77 let src = InFile::new(file_id.into(), token);
78 78
79 let source_analyzer =
80 hir::SourceAnalyzer::new(db, src.with_value(src.value.parent()).as_ref(), None);
81
79 successors(Some(src), |token| { 82 successors(Some(src), |token| {
80 let macro_call = token.value.ancestors().find_map(ast::MacroCall::cast)?; 83 let macro_call = token.value.ancestors().find_map(ast::MacroCall::cast)?;
81 let tt = macro_call.token_tree()?; 84 let tt = macro_call.token_tree()?;
82 if !token.value.text_range().is_subrange(&tt.syntax().text_range()) { 85 if !token.value.text_range().is_subrange(&tt.syntax().text_range()) {
83 return None; 86 return None;
84 } 87 }
85 let source_analyzer =
86 hir::SourceAnalyzer::new(db, token.with_value(token.value.parent()).as_ref(), None);
87 let exp = source_analyzer.expand(db, token.with_value(&macro_call))?; 88 let exp = source_analyzer.expand(db, token.with_value(&macro_call))?;
88 exp.map_token_down(db, token.as_ref()) 89 exp.map_token_down(db, token.as_ref())
89 }) 90 })
diff --git a/crates/ra_ide/src/lib.rs b/crates/ra_ide/src/lib.rs
index 779a81b2c..7b187eba3 100644
--- a/crates/ra_ide/src/lib.rs
+++ b/crates/ra_ide/src/lib.rs
@@ -24,6 +24,7 @@ mod goto_definition;
24mod goto_type_definition; 24mod goto_type_definition;
25mod extend_selection; 25mod extend_selection;
26mod hover; 26mod hover;
27mod call_hierarchy;
27mod call_info; 28mod call_info;
28mod syntax_highlighting; 29mod syntax_highlighting;
29mod parent_module; 30mod parent_module;
@@ -62,6 +63,7 @@ use crate::{db::LineIndexDatabase, display::ToNav, symbol_index::FileSymbol};
62 63
63pub use crate::{ 64pub use crate::{
64 assists::{Assist, AssistId}, 65 assists::{Assist, AssistId},
66 call_hierarchy::CallItem,
65 change::{AnalysisChange, LibraryData}, 67 change::{AnalysisChange, LibraryData},
66 completion::{CompletionItem, CompletionItemKind, InsertTextFormat}, 68 completion::{CompletionItem, CompletionItemKind, InsertTextFormat},
67 diagnostics::Severity, 69 diagnostics::Severity,
@@ -73,7 +75,7 @@ pub use crate::{
73 inlay_hints::{InlayHint, InlayKind}, 75 inlay_hints::{InlayHint, InlayKind},
74 line_index::{LineCol, LineIndex}, 76 line_index::{LineCol, LineIndex},
75 line_index_utils::translate_offset_with_edit, 77 line_index_utils::translate_offset_with_edit,
76 references::{ReferenceSearchResult, SearchScope}, 78 references::{Reference, ReferenceKind, ReferenceSearchResult, SearchScope},
77 runnables::{Runnable, RunnableKind}, 79 runnables::{Runnable, RunnableKind},
78 source_change::{FileSystemEdit, SourceChange, SourceFileEdit}, 80 source_change::{FileSystemEdit, SourceChange, SourceFileEdit},
79 syntax_highlighting::HighlightedRange, 81 syntax_highlighting::HighlightedRange,
@@ -412,6 +414,24 @@ impl Analysis {
412 self.with_db(|db| call_info::call_info(db, position)) 414 self.with_db(|db| call_info::call_info(db, position))
413 } 415 }
414 416
417 /// Computes call hierarchy candidates for the given file position.
418 pub fn call_hierarchy(
419 &self,
420 position: FilePosition,
421 ) -> Cancelable<Option<RangeInfo<Vec<NavigationTarget>>>> {
422 self.with_db(|db| call_hierarchy::call_hierarchy(db, position))
423 }
424
425 /// Computes incoming calls for the given file position.
426 pub fn incoming_calls(&self, position: FilePosition) -> Cancelable<Option<Vec<CallItem>>> {
427 self.with_db(|db| call_hierarchy::incoming_calls(db, position))
428 }
429
430 /// Computes incoming calls for the given file position.
431 pub fn outgoing_calls(&self, position: FilePosition) -> Cancelable<Option<Vec<CallItem>>> {
432 self.with_db(|db| call_hierarchy::outgoing_calls(db, position))
433 }
434
415 /// Returns a `mod name;` declaration which created the current module. 435 /// Returns a `mod name;` declaration which created the current module.
416 pub fn parent_module(&self, position: FilePosition) -> Cancelable<Vec<NavigationTarget>> { 436 pub fn parent_module(&self, position: FilePosition) -> Cancelable<Vec<NavigationTarget>> {
417 self.with_db(|db| parent_module::parent_module(db, position)) 437 self.with_db(|db| parent_module::parent_module(db, position))
diff --git a/crates/ra_ide/src/references.rs b/crates/ra_ide/src/references.rs
index e3ecde50d..5a3ec4eb9 100644
--- a/crates/ra_ide/src/references.rs
+++ b/crates/ra_ide/src/references.rs
@@ -18,7 +18,10 @@ use hir::InFile;
18use once_cell::unsync::Lazy; 18use once_cell::unsync::Lazy;
19use ra_db::{SourceDatabase, SourceDatabaseExt}; 19use ra_db::{SourceDatabase, SourceDatabaseExt};
20use ra_prof::profile; 20use ra_prof::profile;
21use ra_syntax::{algo::find_node_at_offset, ast, AstNode, SourceFile, SyntaxNode, TextUnit}; 21use ra_syntax::{
22 algo::find_node_at_offset, ast, AstNode, SourceFile, SyntaxKind, SyntaxNode, TextUnit,
23 TokenAtOffset,
24};
22 25
23use crate::{ 26use crate::{
24 db::RootDatabase, display::ToNav, FilePosition, FileRange, NavigationTarget, RangeInfo, 27 db::RootDatabase, display::ToNav, FilePosition, FileRange, NavigationTarget, RangeInfo,
@@ -35,7 +38,20 @@ pub use self::search_scope::SearchScope;
35#[derive(Debug, Clone)] 38#[derive(Debug, Clone)]
36pub struct ReferenceSearchResult { 39pub struct ReferenceSearchResult {
37 declaration: NavigationTarget, 40 declaration: NavigationTarget,
38 references: Vec<FileRange>, 41 declaration_kind: ReferenceKind,
42 references: Vec<Reference>,
43}
44
45#[derive(Debug, Clone)]
46pub struct Reference {
47 pub file_range: FileRange,
48 pub kind: ReferenceKind,
49}
50
51#[derive(Debug, Clone, PartialEq)]
52pub enum ReferenceKind {
53 StructLiteral,
54 Other,
39} 55}
40 56
41impl ReferenceSearchResult { 57impl ReferenceSearchResult {
@@ -43,7 +59,7 @@ impl ReferenceSearchResult {
43 &self.declaration 59 &self.declaration
44 } 60 }
45 61
46 pub fn references(&self) -> &[FileRange] { 62 pub fn references(&self) -> &[Reference] {
47 &self.references 63 &self.references
48 } 64 }
49 65
@@ -58,12 +74,18 @@ impl ReferenceSearchResult {
58// allow turning ReferenceSearchResult into an iterator 74// allow turning ReferenceSearchResult into an iterator
59// over FileRanges 75// over FileRanges
60impl IntoIterator for ReferenceSearchResult { 76impl IntoIterator for ReferenceSearchResult {
61 type Item = FileRange; 77 type Item = Reference;
62 type IntoIter = std::vec::IntoIter<FileRange>; 78 type IntoIter = std::vec::IntoIter<Reference>;
63 79
64 fn into_iter(mut self) -> Self::IntoIter { 80 fn into_iter(mut self) -> Self::IntoIter {
65 let mut v = Vec::with_capacity(self.len()); 81 let mut v = Vec::with_capacity(self.len());
66 v.push(FileRange { file_id: self.declaration.file_id(), range: self.declaration.range() }); 82 v.push(Reference {
83 file_range: FileRange {
84 file_id: self.declaration.file_id(),
85 range: self.declaration.range(),
86 },
87 kind: self.declaration_kind,
88 });
67 v.append(&mut self.references); 89 v.append(&mut self.references);
68 v.into_iter() 90 v.into_iter()
69 } 91 }
@@ -71,11 +93,24 @@ impl IntoIterator for ReferenceSearchResult {
71 93
72pub(crate) fn find_all_refs( 94pub(crate) fn find_all_refs(
73 db: &RootDatabase, 95 db: &RootDatabase,
74 position: FilePosition, 96 mut position: FilePosition,
75 search_scope: Option<SearchScope>, 97 search_scope: Option<SearchScope>,
76) -> Option<RangeInfo<ReferenceSearchResult>> { 98) -> Option<RangeInfo<ReferenceSearchResult>> {
77 let parse = db.parse(position.file_id); 99 let parse = db.parse(position.file_id);
78 let syntax = parse.tree().syntax().clone(); 100 let syntax = parse.tree().syntax().clone();
101
102 let token = syntax.token_at_offset(position.offset);
103 let mut search_kind = ReferenceKind::Other;
104
105 if let TokenAtOffset::Between(ref left, ref right) = token {
106 if (right.kind() == SyntaxKind::L_CURLY || right.kind() == SyntaxKind::L_PAREN)
107 && left.kind() != SyntaxKind::IDENT
108 {
109 position = FilePosition { offset: left.text_range().start(), ..position };
110 search_kind = ReferenceKind::StructLiteral;
111 }
112 }
113
79 let RangeInfo { range, info: (name, def) } = find_name(db, &syntax, position)?; 114 let RangeInfo { range, info: (name, def) } = find_name(db, &syntax, position)?;
80 115
81 let declaration = match def.kind { 116 let declaration = match def.kind {
@@ -96,9 +131,15 @@ pub(crate) fn find_all_refs(
96 } 131 }
97 }; 132 };
98 133
99 let references = process_definition(db, def, name, search_scope); 134 let references = process_definition(db, def, name, search_scope)
135 .into_iter()
136 .filter(|r| search_kind == ReferenceKind::Other || search_kind == r.kind)
137 .collect();
100 138
101 Some(RangeInfo::new(range, ReferenceSearchResult { declaration, references })) 139 Some(RangeInfo::new(
140 range,
141 ReferenceSearchResult { declaration, references, declaration_kind: ReferenceKind::Other },
142 ))
102} 143}
103 144
104fn find_name<'a>( 145fn find_name<'a>(
@@ -122,7 +163,7 @@ fn process_definition(
122 def: NameDefinition, 163 def: NameDefinition,
123 name: String, 164 name: String,
124 scope: SearchScope, 165 scope: SearchScope,
125) -> Vec<FileRange> { 166) -> Vec<Reference> {
126 let _p = profile("process_definition"); 167 let _p = profile("process_definition");
127 168
128 let pat = name.as_str(); 169 let pat = name.as_str();
@@ -146,7 +187,21 @@ fn process_definition(
146 } 187 }
147 if let Some(d) = classify_name_ref(db, InFile::new(file_id.into(), &name_ref)) { 188 if let Some(d) = classify_name_ref(db, InFile::new(file_id.into(), &name_ref)) {
148 if d == def { 189 if d == def {
149 refs.push(FileRange { file_id, range }); 190 let kind = if name_ref
191 .syntax()
192 .ancestors()
193 .find_map(ast::RecordLit::cast)
194 .and_then(|l| l.path())
195 .and_then(|p| p.segment())
196 .and_then(|p| p.name_ref())
197 .map(|n| n == name_ref)
198 .unwrap_or(false)
199 {
200 ReferenceKind::StructLiteral
201 } else {
202 ReferenceKind::Other
203 };
204 refs.push(Reference { file_range: FileRange { file_id, range }, kind });
150 } 205 }
151 } 206 }
152 } 207 }
@@ -159,10 +214,33 @@ fn process_definition(
159mod tests { 214mod tests {
160 use crate::{ 215 use crate::{
161 mock_analysis::{analysis_and_position, single_file_with_position, MockAnalysis}, 216 mock_analysis::{analysis_and_position, single_file_with_position, MockAnalysis},
162 ReferenceSearchResult, SearchScope, 217 Reference, ReferenceKind, ReferenceSearchResult, SearchScope,
163 }; 218 };
164 219
165 #[test] 220 #[test]
221 fn test_struct_literal() {
222 let code = r#"
223 struct Foo <|>{
224 a: i32,
225 }
226 impl Foo {
227 fn f() -> i32 { 42 }
228 }
229 fn main() {
230 let f: Foo;
231 f = Foo {a: Foo::f()};
232 }"#;
233
234 let refs = get_all_refs(code);
235 check_result(
236 refs,
237 "Foo STRUCT_DEF FileId(1) [5; 39) [12; 15)",
238 ReferenceKind::Other,
239 &["FileId(1) [142; 145) StructLiteral"],
240 );
241 }
242
243 #[test]
166 fn test_find_all_refs_for_local() { 244 fn test_find_all_refs_for_local() {
167 let code = r#" 245 let code = r#"
168 fn main() { 246 fn main() {
@@ -178,7 +256,17 @@ mod tests {
178 }"#; 256 }"#;
179 257
180 let refs = get_all_refs(code); 258 let refs = get_all_refs(code);
181 assert_eq!(refs.len(), 5); 259 check_result(
260 refs,
261 "i BIND_PAT FileId(1) [33; 34)",
262 ReferenceKind::Other,
263 &[
264 "FileId(1) [67; 68) Other",
265 "FileId(1) [71; 72) Other",
266 "FileId(1) [101; 102) Other",
267 "FileId(1) [127; 128) Other",
268 ],
269 );
182 } 270 }
183 271
184 #[test] 272 #[test]
@@ -189,7 +277,12 @@ mod tests {
189 }"#; 277 }"#;
190 278
191 let refs = get_all_refs(code); 279 let refs = get_all_refs(code);
192 assert_eq!(refs.len(), 2); 280 check_result(
281 refs,
282 "i BIND_PAT FileId(1) [12; 13)",
283 ReferenceKind::Other,
284 &["FileId(1) [38; 39) Other"],
285 );
193 } 286 }
194 287
195 #[test] 288 #[test]
@@ -200,7 +293,12 @@ mod tests {
200 }"#; 293 }"#;
201 294
202 let refs = get_all_refs(code); 295 let refs = get_all_refs(code);
203 assert_eq!(refs.len(), 2); 296 check_result(
297 refs,
298 "i BIND_PAT FileId(1) [12; 13)",
299 ReferenceKind::Other,
300 &["FileId(1) [38; 39) Other"],
301 );
204 } 302 }
205 303
206 #[test] 304 #[test]
@@ -217,7 +315,12 @@ mod tests {
217 "#; 315 "#;
218 316
219 let refs = get_all_refs(code); 317 let refs = get_all_refs(code);
220 assert_eq!(refs.len(), 2); 318 check_result(
319 refs,
320 "spam RECORD_FIELD_DEF FileId(1) [66; 79) [70; 74)",
321 ReferenceKind::Other,
322 &["FileId(1) [152; 156) Other"],
323 );
221 } 324 }
222 325
223 #[test] 326 #[test]
@@ -231,7 +334,7 @@ mod tests {
231 "#; 334 "#;
232 335
233 let refs = get_all_refs(code); 336 let refs = get_all_refs(code);
234 assert_eq!(refs.len(), 1); 337 check_result(refs, "f FN_DEF FileId(1) [88; 104) [91; 92)", ReferenceKind::Other, &[]);
235 } 338 }
236 339
237 #[test] 340 #[test]
@@ -246,7 +349,7 @@ mod tests {
246 "#; 349 "#;
247 350
248 let refs = get_all_refs(code); 351 let refs = get_all_refs(code);
249 assert_eq!(refs.len(), 1); 352 check_result(refs, "B ENUM_VARIANT FileId(1) [83; 84) [83; 84)", ReferenceKind::Other, &[]);
250 } 353 }
251 354
252 #[test] 355 #[test]
@@ -285,7 +388,12 @@ mod tests {
285 388
286 let (analysis, pos) = analysis_and_position(code); 389 let (analysis, pos) = analysis_and_position(code);
287 let refs = analysis.find_all_refs(pos, None).unwrap().unwrap(); 390 let refs = analysis.find_all_refs(pos, None).unwrap().unwrap();
288 assert_eq!(refs.len(), 3); 391 check_result(
392 refs,
393 "Foo STRUCT_DEF FileId(2) [16; 50) [27; 30)",
394 ReferenceKind::Other,
395 &["FileId(1) [52; 55) StructLiteral", "FileId(3) [77; 80) StructLiteral"],
396 );
289 } 397 }
290 398
291 // `mod foo;` is not in the results because `foo` is an `ast::Name`. 399 // `mod foo;` is not in the results because `foo` is an `ast::Name`.
@@ -311,7 +419,12 @@ mod tests {
311 419
312 let (analysis, pos) = analysis_and_position(code); 420 let (analysis, pos) = analysis_and_position(code);
313 let refs = analysis.find_all_refs(pos, None).unwrap().unwrap(); 421 let refs = analysis.find_all_refs(pos, None).unwrap().unwrap();
314 assert_eq!(refs.len(), 2); 422 check_result(
423 refs,
424 "foo SOURCE_FILE FileId(2) [0; 35)",
425 ReferenceKind::Other,
426 &["FileId(1) [13; 16) Other"],
427 );
315 } 428 }
316 429
317 #[test] 430 #[test]
@@ -336,7 +449,12 @@ mod tests {
336 449
337 let (analysis, pos) = analysis_and_position(code); 450 let (analysis, pos) = analysis_and_position(code);
338 let refs = analysis.find_all_refs(pos, None).unwrap().unwrap(); 451 let refs = analysis.find_all_refs(pos, None).unwrap().unwrap();
339 assert_eq!(refs.len(), 3); 452 check_result(
453 refs,
454 "Foo STRUCT_DEF FileId(3) [0; 41) [18; 21)",
455 ReferenceKind::Other,
456 &["FileId(2) [20; 23) Other", "FileId(2) [46; 49) StructLiteral"],
457 );
340 } 458 }
341 459
342 #[test] 460 #[test]
@@ -360,11 +478,21 @@ mod tests {
360 let analysis = mock.analysis(); 478 let analysis = mock.analysis();
361 479
362 let refs = analysis.find_all_refs(pos, None).unwrap().unwrap(); 480 let refs = analysis.find_all_refs(pos, None).unwrap().unwrap();
363 assert_eq!(refs.len(), 3); 481 check_result(
482 refs,
483 "quux FN_DEF FileId(1) [18; 34) [25; 29)",
484 ReferenceKind::Other,
485 &["FileId(2) [16; 20) Other", "FileId(3) [16; 20) Other"],
486 );
364 487
365 let refs = 488 let refs =
366 analysis.find_all_refs(pos, Some(SearchScope::single_file(bar))).unwrap().unwrap(); 489 analysis.find_all_refs(pos, Some(SearchScope::single_file(bar))).unwrap().unwrap();
367 assert_eq!(refs.len(), 2); 490 check_result(
491 refs,
492 "quux FN_DEF FileId(1) [18; 34) [25; 29)",
493 ReferenceKind::Other,
494 &["FileId(3) [16; 20) Other"],
495 );
368 } 496 }
369 497
370 #[test] 498 #[test]
@@ -379,11 +507,40 @@ mod tests {
379 }"#; 507 }"#;
380 508
381 let refs = get_all_refs(code); 509 let refs = get_all_refs(code);
382 assert_eq!(refs.len(), 3); 510 check_result(
511 refs,
512 "m1 MACRO_CALL FileId(1) [9; 63) [46; 48)",
513 ReferenceKind::Other,
514 &["FileId(1) [96; 98) Other", "FileId(1) [114; 116) Other"],
515 );
383 } 516 }
384 517
385 fn get_all_refs(text: &str) -> ReferenceSearchResult { 518 fn get_all_refs(text: &str) -> ReferenceSearchResult {
386 let (analysis, position) = single_file_with_position(text); 519 let (analysis, position) = single_file_with_position(text);
387 analysis.find_all_refs(position, None).unwrap().unwrap() 520 analysis.find_all_refs(position, None).unwrap().unwrap()
388 } 521 }
522
523 fn check_result(
524 res: ReferenceSearchResult,
525 expected_decl: &str,
526 decl_kind: ReferenceKind,
527 expected_refs: &[&str],
528 ) {
529 res.declaration().assert_match(expected_decl);
530 assert_eq!(res.declaration_kind, decl_kind);
531
532 assert_eq!(res.references.len(), expected_refs.len());
533 res.references().iter().enumerate().for_each(|(i, r)| r.assert_match(expected_refs[i]));
534 }
535
536 impl Reference {
537 fn debug_render(&self) -> String {
538 format!("{:?} {:?} {:?}", self.file_range.file_id, self.file_range.range, self.kind)
539 }
540
541 fn assert_match(&self, expected: &str) {
542 let actual = self.debug_render();
543 test_utils::assert_eq_text!(expected.trim(), actual.trim(),);
544 }
545 }
389} 546}
diff --git a/crates/ra_ide/src/references/rename.rs b/crates/ra_ide/src/references/rename.rs
index b804d5f6d..e02985dcd 100644
--- a/crates/ra_ide/src/references/rename.rs
+++ b/crates/ra_ide/src/references/rename.rs
@@ -110,7 +110,13 @@ fn rename_reference(
110 110
111 let edit = refs 111 let edit = refs
112 .into_iter() 112 .into_iter()
113 .map(|range| source_edit_from_file_id_range(range.file_id, range.range, new_name)) 113 .map(|reference| {
114 source_edit_from_file_id_range(
115 reference.file_range.file_id,
116 reference.file_range.range,
117 new_name,
118 )
119 })
114 .collect::<Vec<_>>(); 120 .collect::<Vec<_>>();
115 121
116 if edit.is_empty() { 122 if edit.is_empty() {
diff --git a/crates/ra_lsp_server/src/caps.rs b/crates/ra_lsp_server/src/caps.rs
index adfc9fb2c..c4711076c 100644
--- a/crates/ra_lsp_server/src/caps.rs
+++ b/crates/ra_lsp_server/src/caps.rs
@@ -1,8 +1,8 @@
1//! Advertizes the capabilities of the LSP Server. 1//! Advertizes the capabilities of the LSP Server.
2 2
3use lsp_types::{ 3use lsp_types::{
4 CodeActionProviderCapability, CodeLensOptions, CompletionOptions, 4 CallHierarchyServerCapability, CodeActionProviderCapability, CodeLensOptions,
5 DocumentOnTypeFormattingOptions, FoldingRangeProviderCapability, 5 CompletionOptions, DocumentOnTypeFormattingOptions, FoldingRangeProviderCapability,
6 ImplementationProviderCapability, RenameOptions, RenameProviderCapability, SaveOptions, 6 ImplementationProviderCapability, RenameOptions, RenameProviderCapability, SaveOptions,
7 SelectionRangeProviderCapability, ServerCapabilities, SignatureHelpOptions, 7 SelectionRangeProviderCapability, ServerCapabilities, SignatureHelpOptions,
8 TextDocumentSyncCapability, TextDocumentSyncKind, TextDocumentSyncOptions, 8 TextDocumentSyncCapability, TextDocumentSyncKind, TextDocumentSyncOptions,
@@ -56,6 +56,7 @@ pub fn server_capabilities() -> ServerCapabilities {
56 color_provider: None, 56 color_provider: None,
57 execute_command_provider: None, 57 execute_command_provider: None,
58 workspace: None, 58 workspace: None,
59 call_hierarchy_provider: Some(CallHierarchyServerCapability::Simple(true)),
59 experimental: Default::default(), 60 experimental: Default::default(),
60 } 61 }
61} 62}
diff --git a/crates/ra_lsp_server/src/conv.rs b/crates/ra_lsp_server/src/conv.rs
index e93d4ea33..c260b51c4 100644
--- a/crates/ra_lsp_server/src/conv.rs
+++ b/crates/ra_lsp_server/src/conv.rs
@@ -490,6 +490,24 @@ impl TryConvWith<&WorldSnapshot> for (FileId, RangeInfo<Vec<NavigationTarget>>)
490 } 490 }
491} 491}
492 492
493pub fn to_call_hierarchy_item(
494 file_id: FileId,
495 range: TextRange,
496 world: &WorldSnapshot,
497 line_index: &LineIndex,
498 nav: NavigationTarget,
499) -> Result<lsp_types::CallHierarchyItem> {
500 Ok(lsp_types::CallHierarchyItem {
501 name: nav.name().to_string(),
502 kind: nav.kind().conv(),
503 tags: None,
504 detail: nav.description().map(|it| it.to_string()),
505 uri: file_id.try_conv_with(&world)?,
506 range: nav.range().conv_with(&line_index),
507 selection_range: range.conv_with(&line_index),
508 })
509}
510
493pub fn to_location( 511pub fn to_location(
494 file_id: FileId, 512 file_id: FileId,
495 range: TextRange, 513 range: TextRange,
diff --git a/crates/ra_lsp_server/src/main_loop.rs b/crates/ra_lsp_server/src/main_loop.rs
index 53c6834d0..7a49cad86 100644
--- a/crates/ra_lsp_server/src/main_loop.rs
+++ b/crates/ra_lsp_server/src/main_loop.rs
@@ -504,6 +504,9 @@ fn on_request(
504 .on::<req::Formatting>(handlers::handle_formatting)? 504 .on::<req::Formatting>(handlers::handle_formatting)?
505 .on::<req::DocumentHighlightRequest>(handlers::handle_document_highlight)? 505 .on::<req::DocumentHighlightRequest>(handlers::handle_document_highlight)?
506 .on::<req::InlayHints>(handlers::handle_inlay_hints)? 506 .on::<req::InlayHints>(handlers::handle_inlay_hints)?
507 .on::<req::CallHierarchyPrepare>(handlers::handle_call_hierarchy_prepare)?
508 .on::<req::CallHierarchyIncomingCalls>(handlers::handle_call_hierarchy_incoming)?
509 .on::<req::CallHierarchyOutgoingCalls>(handlers::handle_call_hierarchy_outgoing)?
507 .finish(); 510 .finish();
508 Ok(()) 511 Ok(())
509} 512}
diff --git a/crates/ra_lsp_server/src/main_loop/handlers.rs b/crates/ra_lsp_server/src/main_loop/handlers.rs
index 331beab13..a5b6f48af 100644
--- a/crates/ra_lsp_server/src/main_loop/handlers.rs
+++ b/crates/ra_lsp_server/src/main_loop/handlers.rs
@@ -5,13 +5,16 @@ use std::{fmt::Write as _, io::Write as _};
5 5
6use lsp_server::ErrorCode; 6use lsp_server::ErrorCode;
7use lsp_types::{ 7use lsp_types::{
8 CallHierarchyIncomingCall, CallHierarchyIncomingCallsParams, CallHierarchyItem,
9 CallHierarchyOutgoingCall, CallHierarchyOutgoingCallsParams, CallHierarchyPrepareParams,
8 CodeAction, CodeActionResponse, CodeLens, Command, CompletionItem, Diagnostic, 10 CodeAction, CodeActionResponse, CodeLens, Command, CompletionItem, Diagnostic,
9 DocumentFormattingParams, DocumentHighlight, DocumentSymbol, FoldingRange, FoldingRangeParams, 11 DocumentFormattingParams, DocumentHighlight, DocumentSymbol, FoldingRange, FoldingRangeParams,
10 Hover, HoverContents, Location, MarkupContent, MarkupKind, Position, PrepareRenameResponse, 12 Hover, HoverContents, Location, MarkupContent, MarkupKind, Position, PrepareRenameResponse,
11 Range, RenameParams, SymbolInformation, TextDocumentIdentifier, TextEdit, WorkspaceEdit, 13 Range, RenameParams, SymbolInformation, TextDocumentIdentifier, TextEdit, WorkspaceEdit,
12}; 14};
13use ra_ide::{ 15use ra_ide::{
14 AssistId, FileId, FilePosition, FileRange, Query, Runnable, RunnableKind, SearchScope, 16 AssistId, FileId, FilePosition, FileRange, Query, RangeInfo, Runnable, RunnableKind,
17 SearchScope,
15}; 18};
16use ra_prof::profile; 19use ra_prof::profile;
17use ra_syntax::{AstNode, SyntaxKind, TextRange, TextUnit}; 20use ra_syntax::{AstNode, SyntaxKind, TextRange, TextUnit};
@@ -21,7 +24,10 @@ use serde_json::to_value;
21 24
22use crate::{ 25use crate::{
23 cargo_target_spec::{runnable_args, CargoTargetSpec}, 26 cargo_target_spec::{runnable_args, CargoTargetSpec},
24 conv::{to_location, Conv, ConvWith, FoldConvCtx, MapConvWith, TryConvWith, TryConvWithToVec}, 27 conv::{
28 to_call_hierarchy_item, to_location, Conv, ConvWith, FoldConvCtx, MapConvWith, TryConvWith,
29 TryConvWithToVec,
30 },
25 req::{self, Decoration, InlayHint, InlayHintsParams, InlayKind}, 31 req::{self, Decoration, InlayHint, InlayHintsParams, InlayKind},
26 world::WorldSnapshot, 32 world::WorldSnapshot,
27 LspError, Result, 33 LspError, Result,
@@ -531,8 +537,8 @@ pub fn handle_references(
531 let locations = if params.context.include_declaration { 537 let locations = if params.context.include_declaration {
532 refs.into_iter() 538 refs.into_iter()
533 .filter_map(|r| { 539 .filter_map(|r| {
534 let line_index = world.analysis().file_line_index(r.file_id).ok()?; 540 let line_index = world.analysis().file_line_index(r.file_range.file_id).ok()?;
535 to_location(r.file_id, r.range, &world, &line_index).ok() 541 to_location(r.file_range.file_id, r.file_range.range, &world, &line_index).ok()
536 }) 542 })
537 .collect() 543 .collect()
538 } else { 544 } else {
@@ -540,8 +546,8 @@ pub fn handle_references(
540 refs.references() 546 refs.references()
541 .iter() 547 .iter()
542 .filter_map(|r| { 548 .filter_map(|r| {
543 let line_index = world.analysis().file_line_index(r.file_id).ok()?; 549 let line_index = world.analysis().file_line_index(r.file_range.file_id).ok()?;
544 to_location(r.file_id, r.range, &world, &line_index).ok() 550 to_location(r.file_range.file_id, r.file_range.range, &world, &line_index).ok()
545 }) 551 })
546 .collect() 552 .collect()
547 }; 553 };
@@ -830,8 +836,11 @@ pub fn handle_document_highlight(
830 836
831 Ok(Some( 837 Ok(Some(
832 refs.into_iter() 838 refs.into_iter()
833 .filter(|r| r.file_id == file_id) 839 .filter(|r| r.file_range.file_id == file_id)
834 .map(|r| DocumentHighlight { range: r.range.conv_with(&line_index), kind: None }) 840 .map(|r| DocumentHighlight {
841 range: r.file_range.range.conv_with(&line_index),
842 kind: None,
843 })
835 .collect(), 844 .collect(),
836 )) 845 ))
837} 846}
@@ -933,3 +942,91 @@ pub fn handle_inlay_hints(
933 }) 942 })
934 .collect()) 943 .collect())
935} 944}
945
946pub fn handle_call_hierarchy_prepare(
947 world: WorldSnapshot,
948 params: CallHierarchyPrepareParams,
949) -> Result<Option<Vec<CallHierarchyItem>>> {
950 let _p = profile("handle_call_hierarchy_prepare");
951 let position = params.text_document_position_params.try_conv_with(&world)?;
952 let file_id = position.file_id;
953
954 let nav_info = match world.analysis().call_hierarchy(position)? {
955 None => return Ok(None),
956 Some(it) => it,
957 };
958
959 let line_index = world.analysis().file_line_index(file_id)?;
960 let RangeInfo { range, info: navs } = nav_info;
961 let res = navs
962 .into_iter()
963 .filter(|it| it.kind() == SyntaxKind::FN_DEF)
964 .filter_map(|it| to_call_hierarchy_item(file_id, range, &world, &line_index, it).ok())
965 .collect();
966
967 Ok(Some(res))
968}
969
970pub fn handle_call_hierarchy_incoming(
971 world: WorldSnapshot,
972 params: CallHierarchyIncomingCallsParams,
973) -> Result<Option<Vec<CallHierarchyIncomingCall>>> {
974 let _p = profile("handle_call_hierarchy_incoming");
975 let item = params.item;
976
977 let doc = TextDocumentIdentifier::new(item.uri);
978 let frange: FileRange = (&doc, item.range).try_conv_with(&world)?;
979 let fpos = FilePosition { file_id: frange.file_id, offset: frange.range.start() };
980
981 let call_items = match world.analysis().incoming_calls(fpos)? {
982 None => return Ok(None),
983 Some(it) => it,
984 };
985
986 let mut res = vec![];
987
988 for call_item in call_items.into_iter() {
989 let file_id = call_item.target.file_id();
990 let line_index = world.analysis().file_line_index(file_id)?;
991 let range = call_item.target.range();
992 let item = to_call_hierarchy_item(file_id, range, &world, &line_index, call_item.target)?;
993 res.push(CallHierarchyIncomingCall {
994 from: item,
995 from_ranges: call_item.ranges.iter().map(|it| it.conv_with(&line_index)).collect(),
996 });
997 }
998
999 Ok(Some(res))
1000}
1001
1002pub fn handle_call_hierarchy_outgoing(
1003 world: WorldSnapshot,
1004 params: CallHierarchyOutgoingCallsParams,
1005) -> Result<Option<Vec<CallHierarchyOutgoingCall>>> {
1006 let _p = profile("handle_call_hierarchy_outgoing");
1007 let item = params.item;
1008
1009 let doc = TextDocumentIdentifier::new(item.uri);
1010 let frange: FileRange = (&doc, item.range).try_conv_with(&world)?;
1011 let fpos = FilePosition { file_id: frange.file_id, offset: frange.range.start() };
1012
1013 let call_items = match world.analysis().outgoing_calls(fpos)? {
1014 None => return Ok(None),
1015 Some(it) => it,
1016 };
1017
1018 let mut res = vec![];
1019
1020 for call_item in call_items.into_iter() {
1021 let file_id = call_item.target.file_id();
1022 let line_index = world.analysis().file_line_index(file_id)?;
1023 let range = call_item.target.range();
1024 let item = to_call_hierarchy_item(file_id, range, &world, &line_index, call_item.target)?;
1025 res.push(CallHierarchyOutgoingCall {
1026 to: item,
1027 from_ranges: call_item.ranges.iter().map(|it| it.conv_with(&line_index)).collect(),
1028 });
1029 }
1030
1031 Ok(Some(res))
1032}
diff --git a/crates/ra_lsp_server/src/req.rs b/crates/ra_lsp_server/src/req.rs
index 40edaf677..8098ff31d 100644
--- a/crates/ra_lsp_server/src/req.rs
+++ b/crates/ra_lsp_server/src/req.rs
@@ -6,13 +6,15 @@ use serde::{Deserialize, Serialize};
6 6
7pub use lsp_types::{ 7pub use lsp_types::{
8 notification::*, request::*, ApplyWorkspaceEditParams, CodeActionParams, CodeLens, 8 notification::*, request::*, ApplyWorkspaceEditParams, CodeActionParams, CodeLens,
9 CodeLensParams, CompletionParams, CompletionResponse, DidChangeConfigurationParams, 9 CodeLensParams, CompletionParams, CompletionResponse, DiagnosticTag,
10 DidChangeWatchedFilesParams, DidChangeWatchedFilesRegistrationOptions, 10 DidChangeConfigurationParams, DidChangeWatchedFilesParams,
11 DocumentOnTypeFormattingParams, DocumentSymbolParams, DocumentSymbolResponse, 11 DidChangeWatchedFilesRegistrationOptions, DocumentOnTypeFormattingParams, DocumentSymbolParams,
12 FileSystemWatcher, Hover, InitializeResult, MessageType, ProgressParams, ProgressParamsValue, 12 DocumentSymbolResponse, FileSystemWatcher, Hover, InitializeResult, MessageType,
13 ProgressToken, PublishDiagnosticsParams, ReferenceParams, Registration, RegistrationParams, 13 PartialResultParams, ProgressParams, ProgressParamsValue, ProgressToken,
14 SelectionRange, SelectionRangeParams, ShowMessageParams, SignatureHelp, TextDocumentEdit, 14 PublishDiagnosticsParams, ReferenceParams, Registration, RegistrationParams, SelectionRange,
15 TextDocumentPositionParams, TextEdit, WorkspaceEdit, WorkspaceSymbolParams, 15 SelectionRangeParams, ServerCapabilities, ShowMessageParams, SignatureHelp, SymbolKind,
16 TextDocumentEdit, TextDocumentPositionParams, TextEdit, WorkDoneProgressParams, WorkspaceEdit,
17 WorkspaceSymbolParams,
16}; 18};
17 19
18pub enum AnalyzerStatus {} 20pub enum AnalyzerStatus {}
diff --git a/crates/ra_parser/src/grammar/items/traits.rs b/crates/ra_parser/src/grammar/items/traits.rs
index 2c560e824..964fd3041 100644
--- a/crates/ra_parser/src/grammar/items/traits.rs
+++ b/crates/ra_parser/src/grammar/items/traits.rs
@@ -100,6 +100,8 @@ pub(crate) fn impl_item_list(p: &mut Parser) {
100 m.complete(p, ITEM_LIST); 100 m.complete(p, ITEM_LIST);
101} 101}
102 102
103// test impl_type_params
104// impl<const N: u32> Bar<N> {}
103fn choose_type_params_over_qpath(p: &Parser) -> bool { 105fn choose_type_params_over_qpath(p: &Parser) -> bool {
104 // There's an ambiguity between generic parameters and qualified paths in impls. 106 // There's an ambiguity between generic parameters and qualified paths in impls.
105 // If we see `<` it may start both, so we have to inspect some following tokens. 107 // If we see `<` it may start both, so we have to inspect some following tokens.
@@ -107,6 +109,7 @@ fn choose_type_params_over_qpath(p: &Parser) -> bool {
107 // but not qualified paths (with one exception): 109 // but not qualified paths (with one exception):
108 // `<` `>` - empty generic parameters 110 // `<` `>` - empty generic parameters
109 // `<` `#` - generic parameters with attributes 111 // `<` `#` - generic parameters with attributes
112 // `<` `const` - const generic parameters
110 // `<` (LIFETIME|IDENT) `>` - single generic parameter 113 // `<` (LIFETIME|IDENT) `>` - single generic parameter
111 // `<` (LIFETIME|IDENT) `,` - first generic parameter in a list 114 // `<` (LIFETIME|IDENT) `,` - first generic parameter in a list
112 // `<` (LIFETIME|IDENT) `:` - generic parameter with bounds 115 // `<` (LIFETIME|IDENT) `:` - generic parameter with bounds
@@ -119,7 +122,7 @@ fn choose_type_params_over_qpath(p: &Parser) -> bool {
119 if !p.at(T![<]) { 122 if !p.at(T![<]) {
120 return false; 123 return false;
121 } 124 }
122 if p.nth(1) == T![#] || p.nth(1) == T![>] { 125 if p.nth(1) == T![#] || p.nth(1) == T![>] || p.nth(1) == CONST_KW {
123 return true; 126 return true;
124 } 127 }
125 (p.nth(1) == LIFETIME || p.nth(1) == IDENT) 128 (p.nth(1) == LIFETIME || p.nth(1) == IDENT)
diff --git a/crates/ra_parser/src/grammar/type_args.rs b/crates/ra_parser/src/grammar/type_args.rs
index 7256c2697..33d9973e9 100644
--- a/crates/ra_parser/src/grammar/type_args.rs
+++ b/crates/ra_parser/src/grammar/type_args.rs
@@ -26,7 +26,7 @@ pub(super) fn opt_type_arg_list(p: &mut Parser, colon_colon_required: bool) {
26} 26}
27 27
28// test type_arg 28// test type_arg
29// type A = B<'static, i32, Item=u64>; 29// type A = B<'static, i32, 1, { 2 }, Item=u64>;
30fn type_arg(p: &mut Parser) { 30fn type_arg(p: &mut Parser) {
31 let m = p.start(); 31 let m = p.start();
32 match p.current() { 32 match p.current() {
@@ -47,6 +47,14 @@ fn type_arg(p: &mut Parser) {
47 types::type_(p); 47 types::type_(p);
48 m.complete(p, ASSOC_TYPE_ARG); 48 m.complete(p, ASSOC_TYPE_ARG);
49 } 49 }
50 T!['{'] => {
51 expressions::block(p);
52 m.complete(p, CONST_ARG);
53 }
54 k if k.is_literal() => {
55 p.bump(k);
56 m.complete(p, CONST_ARG);
57 }
50 _ => { 58 _ => {
51 types::type_(p); 59 types::type_(p);
52 m.complete(p, TYPE_ARG); 60 m.complete(p, TYPE_ARG);
diff --git a/crates/ra_parser/src/syntax_kind/generated.rs b/crates/ra_parser/src/syntax_kind/generated.rs
index af2945f57..4b301d67a 100644
--- a/crates/ra_parser/src/syntax_kind/generated.rs
+++ b/crates/ra_parser/src/syntax_kind/generated.rs
@@ -61,46 +61,46 @@ pub enum SyntaxKind {
61 SHR, 61 SHR,
62 SHLEQ, 62 SHLEQ,
63 SHREQ, 63 SHREQ,
64 AS_KW,
64 ASYNC_KW, 65 ASYNC_KW,
65 USE_KW, 66 AWAIT_KW,
66 FN_KW, 67 BOX_KW,
67 STRUCT_KW, 68 BREAK_KW,
68 ENUM_KW, 69 CONST_KW,
69 TRAIT_KW, 70 CONTINUE_KW,
70 IMPL_KW, 71 CRATE_KW,
71 DYN_KW, 72 DYN_KW,
72 TRUE_KW, 73 ELSE_KW,
73 FALSE_KW, 74 ENUM_KW,
74 AS_KW,
75 EXTERN_KW, 75 EXTERN_KW,
76 CRATE_KW, 76 FALSE_KW,
77 MOD_KW, 77 FN_KW,
78 PUB_KW,
79 SELF_KW,
80 SUPER_KW,
81 IN_KW,
82 WHERE_KW,
83 FOR_KW, 78 FOR_KW,
84 LOOP_KW,
85 WHILE_KW,
86 CONTINUE_KW,
87 BREAK_KW,
88 IF_KW, 79 IF_KW,
89 ELSE_KW, 80 IMPL_KW,
81 IN_KW,
82 LET_KW,
83 LOOP_KW,
84 MACRO_KW,
90 MATCH_KW, 85 MATCH_KW,
91 CONST_KW, 86 MOD_KW,
92 STATIC_KW, 87 MOVE_KW,
93 MUT_KW, 88 MUT_KW,
94 UNSAFE_KW, 89 PUB_KW,
95 TYPE_KW,
96 REF_KW, 90 REF_KW,
97 LET_KW,
98 MOVE_KW,
99 RETURN_KW, 91 RETURN_KW,
92 SELF_KW,
93 STATIC_KW,
94 STRUCT_KW,
95 SUPER_KW,
96 TRAIT_KW,
97 TRUE_KW,
100 TRY_KW, 98 TRY_KW,
101 BOX_KW, 99 TYPE_KW,
102 AWAIT_KW, 100 UNSAFE_KW,
103 MACRO_KW, 101 USE_KW,
102 WHERE_KW,
103 WHILE_KW,
104 AUTO_KW, 104 AUTO_KW,
105 DEFAULT_KW, 105 DEFAULT_KW,
106 EXISTENTIAL_KW, 106 EXISTENTIAL_KW,
@@ -234,6 +234,7 @@ pub enum SyntaxKind {
234 LIFETIME_ARG, 234 LIFETIME_ARG,
235 TYPE_ARG, 235 TYPE_ARG,
236 ASSOC_TYPE_ARG, 236 ASSOC_TYPE_ARG,
237 CONST_ARG,
237 PARAM_LIST, 238 PARAM_LIST,
238 PARAM, 239 PARAM,
239 SELF_PARAM, 240 SELF_PARAM,
@@ -249,12 +250,12 @@ use self::SyntaxKind::*;
249impl SyntaxKind { 250impl SyntaxKind {
250 pub fn is_keyword(self) -> bool { 251 pub fn is_keyword(self) -> bool {
251 match self { 252 match self {
252 ASYNC_KW | USE_KW | FN_KW | STRUCT_KW | ENUM_KW | TRAIT_KW | IMPL_KW | DYN_KW 253 AS_KW | ASYNC_KW | AWAIT_KW | BOX_KW | BREAK_KW | CONST_KW | CONTINUE_KW | CRATE_KW
253 | TRUE_KW | FALSE_KW | AS_KW | EXTERN_KW | CRATE_KW | MOD_KW | PUB_KW | SELF_KW 254 | DYN_KW | ELSE_KW | ENUM_KW | EXTERN_KW | FALSE_KW | FN_KW | FOR_KW | IF_KW
254 | SUPER_KW | IN_KW | WHERE_KW | FOR_KW | LOOP_KW | WHILE_KW | CONTINUE_KW 255 | IMPL_KW | IN_KW | LET_KW | LOOP_KW | MACRO_KW | MATCH_KW | MOD_KW | MOVE_KW
255 | BREAK_KW | IF_KW | ELSE_KW | MATCH_KW | CONST_KW | STATIC_KW | MUT_KW | UNSAFE_KW 256 | MUT_KW | PUB_KW | REF_KW | RETURN_KW | SELF_KW | STATIC_KW | STRUCT_KW | SUPER_KW
256 | TYPE_KW | REF_KW | LET_KW | MOVE_KW | RETURN_KW | TRY_KW | BOX_KW | AWAIT_KW 257 | TRAIT_KW | TRUE_KW | TRY_KW | TYPE_KW | UNSAFE_KW | USE_KW | WHERE_KW | WHILE_KW
257 | MACRO_KW | AUTO_KW | DEFAULT_KW | EXISTENTIAL_KW | UNION_KW => true, 258 | AUTO_KW | DEFAULT_KW | EXISTENTIAL_KW | UNION_KW => true,
258 _ => false, 259 _ => false,
259 } 260 }
260 } 261 }
@@ -278,46 +279,46 @@ impl SyntaxKind {
278 } 279 }
279 pub fn from_keyword(ident: &str) -> Option<SyntaxKind> { 280 pub fn from_keyword(ident: &str) -> Option<SyntaxKind> {
280 let kw = match ident { 281 let kw = match ident {
282 "as" => AS_KW,
281 "async" => ASYNC_KW, 283 "async" => ASYNC_KW,
282 "use" => USE_KW, 284 "await" => AWAIT_KW,
283 "fn" => FN_KW, 285 "box" => BOX_KW,
284 "struct" => STRUCT_KW, 286 "break" => BREAK_KW,
285 "enum" => ENUM_KW, 287 "const" => CONST_KW,
286 "trait" => TRAIT_KW, 288 "continue" => CONTINUE_KW,
287 "impl" => IMPL_KW, 289 "crate" => CRATE_KW,
288 "dyn" => DYN_KW, 290 "dyn" => DYN_KW,
289 "true" => TRUE_KW, 291 "else" => ELSE_KW,
290 "false" => FALSE_KW, 292 "enum" => ENUM_KW,
291 "as" => AS_KW,
292 "extern" => EXTERN_KW, 293 "extern" => EXTERN_KW,
293 "crate" => CRATE_KW, 294 "false" => FALSE_KW,
294 "mod" => MOD_KW, 295 "fn" => FN_KW,
295 "pub" => PUB_KW,
296 "self" => SELF_KW,
297 "super" => SUPER_KW,
298 "in" => IN_KW,
299 "where" => WHERE_KW,
300 "for" => FOR_KW, 296 "for" => FOR_KW,
301 "loop" => LOOP_KW,
302 "while" => WHILE_KW,
303 "continue" => CONTINUE_KW,
304 "break" => BREAK_KW,
305 "if" => IF_KW, 297 "if" => IF_KW,
306 "else" => ELSE_KW, 298 "impl" => IMPL_KW,
299 "in" => IN_KW,
300 "let" => LET_KW,
301 "loop" => LOOP_KW,
302 "macro" => MACRO_KW,
307 "match" => MATCH_KW, 303 "match" => MATCH_KW,
308 "const" => CONST_KW, 304 "mod" => MOD_KW,
309 "static" => STATIC_KW, 305 "move" => MOVE_KW,
310 "mut" => MUT_KW, 306 "mut" => MUT_KW,
311 "unsafe" => UNSAFE_KW, 307 "pub" => PUB_KW,
312 "type" => TYPE_KW,
313 "ref" => REF_KW, 308 "ref" => REF_KW,
314 "let" => LET_KW,
315 "move" => MOVE_KW,
316 "return" => RETURN_KW, 309 "return" => RETURN_KW,
310 "self" => SELF_KW,
311 "static" => STATIC_KW,
312 "struct" => STRUCT_KW,
313 "super" => SUPER_KW,
314 "trait" => TRAIT_KW,
315 "true" => TRUE_KW,
317 "try" => TRY_KW, 316 "try" => TRY_KW,
318 "box" => BOX_KW, 317 "type" => TYPE_KW,
319 "await" => AWAIT_KW, 318 "unsafe" => UNSAFE_KW,
320 "macro" => MACRO_KW, 319 "use" => USE_KW,
320 "where" => WHERE_KW,
321 "while" => WHILE_KW,
321 _ => return None, 322 _ => return None,
322 }; 323 };
323 Some(kw) 324 Some(kw)
@@ -515,125 +516,125 @@ macro_rules! T {
515 ( >>= ) => { 516 ( >>= ) => {
516 $crate::SyntaxKind::SHREQ 517 $crate::SyntaxKind::SHREQ
517 }; 518 };
519 ( as ) => {
520 $crate::SyntaxKind::AS_KW
521 };
518 ( async ) => { 522 ( async ) => {
519 $crate::SyntaxKind::ASYNC_KW 523 $crate::SyntaxKind::ASYNC_KW
520 }; 524 };
521 ( use ) => { 525 ( await ) => {
522 $crate::SyntaxKind::USE_KW 526 $crate::SyntaxKind::AWAIT_KW
523 }; 527 };
524 ( fn ) => { 528 ( box ) => {
525 $crate::SyntaxKind::FN_KW 529 $crate::SyntaxKind::BOX_KW
526 }; 530 };
527 ( struct ) => { 531 ( break ) => {
528 $crate::SyntaxKind::STRUCT_KW 532 $crate::SyntaxKind::BREAK_KW
529 }; 533 };
530 ( enum ) => { 534 ( const ) => {
531 $crate::SyntaxKind::ENUM_KW 535 $crate::SyntaxKind::CONST_KW
532 }; 536 };
533 ( trait ) => { 537 ( continue ) => {
534 $crate::SyntaxKind::TRAIT_KW 538 $crate::SyntaxKind::CONTINUE_KW
535 }; 539 };
536 ( impl ) => { 540 ( crate ) => {
537 $crate::SyntaxKind::IMPL_KW 541 $crate::SyntaxKind::CRATE_KW
538 }; 542 };
539 ( dyn ) => { 543 ( dyn ) => {
540 $crate::SyntaxKind::DYN_KW 544 $crate::SyntaxKind::DYN_KW
541 }; 545 };
542 ( true ) => { 546 ( else ) => {
543 $crate::SyntaxKind::TRUE_KW 547 $crate::SyntaxKind::ELSE_KW
544 };
545 ( false ) => {
546 $crate::SyntaxKind::FALSE_KW
547 }; 548 };
548 ( as ) => { 549 ( enum ) => {
549 $crate::SyntaxKind::AS_KW 550 $crate::SyntaxKind::ENUM_KW
550 }; 551 };
551 ( extern ) => { 552 ( extern ) => {
552 $crate::SyntaxKind::EXTERN_KW 553 $crate::SyntaxKind::EXTERN_KW
553 }; 554 };
554 ( crate ) => { 555 ( false ) => {
555 $crate::SyntaxKind::CRATE_KW 556 $crate::SyntaxKind::FALSE_KW
556 }; 557 };
557 ( mod ) => { 558 ( fn ) => {
558 $crate::SyntaxKind::MOD_KW 559 $crate::SyntaxKind::FN_KW
559 }; 560 };
560 ( pub ) => { 561 ( for ) => {
561 $crate::SyntaxKind::PUB_KW 562 $crate::SyntaxKind::FOR_KW
562 }; 563 };
563 ( self ) => { 564 ( if ) => {
564 $crate::SyntaxKind::SELF_KW 565 $crate::SyntaxKind::IF_KW
565 }; 566 };
566 ( super ) => { 567 ( impl ) => {
567 $crate::SyntaxKind::SUPER_KW 568 $crate::SyntaxKind::IMPL_KW
568 }; 569 };
569 ( in ) => { 570 ( in ) => {
570 $crate::SyntaxKind::IN_KW 571 $crate::SyntaxKind::IN_KW
571 }; 572 };
572 ( where ) => { 573 ( let ) => {
573 $crate::SyntaxKind::WHERE_KW 574 $crate::SyntaxKind::LET_KW
574 };
575 ( for ) => {
576 $crate::SyntaxKind::FOR_KW
577 }; 575 };
578 ( loop ) => { 576 ( loop ) => {
579 $crate::SyntaxKind::LOOP_KW 577 $crate::SyntaxKind::LOOP_KW
580 }; 578 };
581 ( while ) => { 579 ( macro ) => {
582 $crate::SyntaxKind::WHILE_KW 580 $crate::SyntaxKind::MACRO_KW
583 };
584 ( continue ) => {
585 $crate::SyntaxKind::CONTINUE_KW
586 };
587 ( break ) => {
588 $crate::SyntaxKind::BREAK_KW
589 };
590 ( if ) => {
591 $crate::SyntaxKind::IF_KW
592 };
593 ( else ) => {
594 $crate::SyntaxKind::ELSE_KW
595 }; 581 };
596 ( match ) => { 582 ( match ) => {
597 $crate::SyntaxKind::MATCH_KW 583 $crate::SyntaxKind::MATCH_KW
598 }; 584 };
599 ( const ) => { 585 ( mod ) => {
600 $crate::SyntaxKind::CONST_KW 586 $crate::SyntaxKind::MOD_KW
601 }; 587 };
602 ( static ) => { 588 ( move ) => {
603 $crate::SyntaxKind::STATIC_KW 589 $crate::SyntaxKind::MOVE_KW
604 }; 590 };
605 ( mut ) => { 591 ( mut ) => {
606 $crate::SyntaxKind::MUT_KW 592 $crate::SyntaxKind::MUT_KW
607 }; 593 };
608 ( unsafe ) => { 594 ( pub ) => {
609 $crate::SyntaxKind::UNSAFE_KW 595 $crate::SyntaxKind::PUB_KW
610 };
611 ( type ) => {
612 $crate::SyntaxKind::TYPE_KW
613 }; 596 };
614 ( ref ) => { 597 ( ref ) => {
615 $crate::SyntaxKind::REF_KW 598 $crate::SyntaxKind::REF_KW
616 }; 599 };
617 ( let ) => {
618 $crate::SyntaxKind::LET_KW
619 };
620 ( move ) => {
621 $crate::SyntaxKind::MOVE_KW
622 };
623 ( return ) => { 600 ( return ) => {
624 $crate::SyntaxKind::RETURN_KW 601 $crate::SyntaxKind::RETURN_KW
625 }; 602 };
603 ( self ) => {
604 $crate::SyntaxKind::SELF_KW
605 };
606 ( static ) => {
607 $crate::SyntaxKind::STATIC_KW
608 };
609 ( struct ) => {
610 $crate::SyntaxKind::STRUCT_KW
611 };
612 ( super ) => {
613 $crate::SyntaxKind::SUPER_KW
614 };
615 ( trait ) => {
616 $crate::SyntaxKind::TRAIT_KW
617 };
618 ( true ) => {
619 $crate::SyntaxKind::TRUE_KW
620 };
626 ( try ) => { 621 ( try ) => {
627 $crate::SyntaxKind::TRY_KW 622 $crate::SyntaxKind::TRY_KW
628 }; 623 };
629 ( box ) => { 624 ( type ) => {
630 $crate::SyntaxKind::BOX_KW 625 $crate::SyntaxKind::TYPE_KW
631 }; 626 };
632 ( await ) => { 627 ( unsafe ) => {
633 $crate::SyntaxKind::AWAIT_KW 628 $crate::SyntaxKind::UNSAFE_KW
634 }; 629 };
635 ( macro ) => { 630 ( use ) => {
636 $crate::SyntaxKind::MACRO_KW 631 $crate::SyntaxKind::USE_KW
632 };
633 ( where ) => {
634 $crate::SyntaxKind::WHERE_KW
635 };
636 ( while ) => {
637 $crate::SyntaxKind::WHILE_KW
637 }; 638 };
638 ( auto ) => { 639 ( auto ) => {
639 $crate::SyntaxKind::AUTO_KW 640 $crate::SyntaxKind::AUTO_KW
diff --git a/crates/ra_prof/src/lib.rs b/crates/ra_prof/src/lib.rs
index f260c40a3..6dde304b1 100644
--- a/crates/ra_prof/src/lib.rs
+++ b/crates/ra_prof/src/lib.rs
@@ -197,7 +197,10 @@ impl Drop for Profiler {
197 if level == 0 { 197 if level == 0 {
198 let stdout = stderr(); 198 let stdout = stderr();
199 let longer_than = stack.filter_data.longer_than; 199 let longer_than = stack.filter_data.longer_than;
200 if duration >= longer_than { 200 // Convert to millis for comparison to avoid problems with rounding
201 // (otherwise we could print `0ms` despite user's `>0` filter when
202 // `duration` is just a few nanos).
203 if duration.as_millis() > longer_than.as_millis() {
201 print(0, &stack.messages, &mut stdout.lock(), longer_than, None); 204 print(0, &stack.messages, &mut stdout.lock(), longer_than, None);
202 } 205 }
203 stack.messages.clear(); 206 stack.messages.clear();
@@ -226,7 +229,7 @@ fn print(
226 continue; 229 continue;
227 } 230 }
228 accounted_for += duration; 231 accounted_for += duration;
229 if duration >= longer_than { 232 if duration.as_millis() > longer_than.as_millis() {
230 writeln!(out, "{}{:5}ms - {}", indent, duration.as_millis(), msg) 233 writeln!(out, "{}{:5}ms - {}", indent, duration.as_millis(), msg)
231 .expect("printing profiling info to stdout"); 234 .expect("printing profiling info to stdout");
232 235
@@ -251,8 +254,9 @@ fn print(
251 254
252 if let Some(total) = total { 255 if let Some(total) = total {
253 if let Some(unaccounted) = total.checked_sub(accounted_for) { 256 if let Some(unaccounted) = total.checked_sub(accounted_for) {
254 if unaccounted >= longer_than && last > 0 { 257 let unaccounted_millis = unaccounted.as_millis();
255 writeln!(out, "{}{:5}ms - ???", indent, unaccounted.as_millis()) 258 if unaccounted_millis > longer_than.as_millis() && unaccounted_millis > 0 && last > 0 {
259 writeln!(out, "{}{:5}ms - ???", indent, unaccounted_millis)
256 .expect("printing profiling info to stdout"); 260 .expect("printing profiling info to stdout");
257 } 261 }
258 } 262 }
@@ -356,4 +360,21 @@ mod tests {
356 fn profiling_function2() { 360 fn profiling_function2() {
357 let _p = profile("profile2"); 361 let _p = profile("profile2");
358 } 362 }
363
364 #[test]
365 fn test_longer_than() {
366 let mut result = vec![];
367 let msgs = vec![
368 Message { level: 1, duration: Duration::from_nanos(3), message: "bar".to_owned() },
369 Message { level: 1, duration: Duration::from_nanos(2), message: "bar".to_owned() },
370 Message { level: 0, duration: Duration::from_millis(1), message: "foo".to_owned() },
371 ];
372 print(0, &msgs, &mut result, Duration::from_millis(0), Some(Duration::from_millis(1)));
373 // The calls to `bar` are so short that they'll be rounded to 0ms and should get collapsed
374 // when printing.
375 assert_eq!(
376 std::str::from_utf8(&result).unwrap(),
377 " 1ms - foo\n 0ms - bar (2 calls)\n"
378 );
379 }
359} 380}
diff --git a/crates/ra_project_model/src/sysroot.rs b/crates/ra_project_model/src/sysroot.rs
index 10ca391b6..34d066b1e 100644
--- a/crates/ra_project_model/src/sysroot.rs
+++ b/crates/ra_project_model/src/sysroot.rs
@@ -53,9 +53,10 @@ impl Sysroot {
53 if !src.exists() { 53 if !src.exists() {
54 Err(format!( 54 Err(format!(
55 "can't load standard library from sysroot\n\ 55 "can't load standard library from sysroot\n\
56 {:?}\n\ 56 {}\n\
57 (discovered via `rustc --print sysroot`)\n\
57 try running `rustup component add rust-src` or set `RUST_SRC_PATH`", 58 try running `rustup component add rust-src` or set `RUST_SRC_PATH`",
58 src, 59 src.display(),
59 ))?; 60 ))?;
60 } 61 }
61 62
diff --git a/crates/ra_syntax/src/ast/expr_extensions.rs b/crates/ra_syntax/src/ast/expr_extensions.rs
index 2fd039837..23b6aa901 100644
--- a/crates/ra_syntax/src/ast/expr_extensions.rs
+++ b/crates/ra_syntax/src/ast/expr_extensions.rs
@@ -126,6 +126,24 @@ pub enum BinOp {
126 BitXorAssign, 126 BitXorAssign,
127} 127}
128 128
129impl BinOp {
130 pub fn is_assignment(&self) -> bool {
131 match *self {
132 BinOp::Assignment
133 | BinOp::AddAssign
134 | BinOp::DivAssign
135 | BinOp::MulAssign
136 | BinOp::RemAssign
137 | BinOp::ShrAssign
138 | BinOp::ShlAssign
139 | BinOp::SubAssign
140 | BinOp::BitOrAssign
141 | BinOp::BitAndAssign
142 | BinOp::BitXorAssign => true,
143 _ => false,
144 }
145 }
146}
129impl ast::BinExpr { 147impl ast::BinExpr {
130 pub fn op_details(&self) -> Option<(SyntaxToken, BinOp)> { 148 pub fn op_details(&self) -> Option<(SyntaxToken, BinOp)> {
131 self.syntax().children_with_tokens().filter_map(|it| it.into_token()).find_map(|c| { 149 self.syntax().children_with_tokens().filter_map(|it| it.into_token()).find_map(|c| {
diff --git a/crates/ra_syntax/src/ast/generated.rs b/crates/ra_syntax/src/ast/generated.rs
index e64c83d33..33d5578e7 100644
--- a/crates/ra_syntax/src/ast/generated.rs
+++ b/crates/ra_syntax/src/ast/generated.rs
@@ -6,13 +6,13 @@ use crate::{
6 SyntaxNode, 6 SyntaxNode,
7}; 7};
8#[derive(Debug, Clone, PartialEq, Eq, Hash)] 8#[derive(Debug, Clone, PartialEq, Eq, Hash)]
9pub struct Alias { 9pub struct SourceFile {
10 pub(crate) syntax: SyntaxNode, 10 pub(crate) syntax: SyntaxNode,
11} 11}
12impl AstNode for Alias { 12impl AstNode for SourceFile {
13 fn can_cast(kind: SyntaxKind) -> bool { 13 fn can_cast(kind: SyntaxKind) -> bool {
14 match kind { 14 match kind {
15 ALIAS => true, 15 SOURCE_FILE => true,
16 _ => false, 16 _ => false,
17 } 17 }
18 } 18 }
@@ -27,16 +27,21 @@ impl AstNode for Alias {
27 &self.syntax 27 &self.syntax
28 } 28 }
29} 29}
30impl ast::NameOwner for Alias {} 30impl ast::ModuleItemOwner for SourceFile {}
31impl Alias {} 31impl ast::FnDefOwner for SourceFile {}
32impl SourceFile {
33 pub fn modules(&self) -> AstChildren<Module> {
34 AstChildren::new(&self.syntax)
35 }
36}
32#[derive(Debug, Clone, PartialEq, Eq, Hash)] 37#[derive(Debug, Clone, PartialEq, Eq, Hash)]
33pub struct ArgList { 38pub struct FnDef {
34 pub(crate) syntax: SyntaxNode, 39 pub(crate) syntax: SyntaxNode,
35} 40}
36impl AstNode for ArgList { 41impl AstNode for FnDef {
37 fn can_cast(kind: SyntaxKind) -> bool { 42 fn can_cast(kind: SyntaxKind) -> bool {
38 match kind { 43 match kind {
39 ARG_LIST => true, 44 FN_DEF => true,
40 _ => false, 45 _ => false,
41 } 46 }
42 } 47 }
@@ -51,19 +56,30 @@ impl AstNode for ArgList {
51 &self.syntax 56 &self.syntax
52 } 57 }
53} 58}
54impl ArgList { 59impl ast::VisibilityOwner for FnDef {}
55 pub fn args(&self) -> AstChildren<Expr> { 60impl ast::NameOwner for FnDef {}
56 AstChildren::new(&self.syntax) 61impl ast::TypeParamsOwner for FnDef {}
62impl ast::DocCommentsOwner for FnDef {}
63impl ast::AttrsOwner for FnDef {}
64impl FnDef {
65 pub fn param_list(&self) -> Option<ParamList> {
66 AstChildren::new(&self.syntax).next()
67 }
68 pub fn ret_type(&self) -> Option<RetType> {
69 AstChildren::new(&self.syntax).next()
70 }
71 pub fn body(&self) -> Option<BlockExpr> {
72 AstChildren::new(&self.syntax).next()
57 } 73 }
58} 74}
59#[derive(Debug, Clone, PartialEq, Eq, Hash)] 75#[derive(Debug, Clone, PartialEq, Eq, Hash)]
60pub struct ArrayExpr { 76pub struct RetType {
61 pub(crate) syntax: SyntaxNode, 77 pub(crate) syntax: SyntaxNode,
62} 78}
63impl AstNode for ArrayExpr { 79impl AstNode for RetType {
64 fn can_cast(kind: SyntaxKind) -> bool { 80 fn can_cast(kind: SyntaxKind) -> bool {
65 match kind { 81 match kind {
66 ARRAY_EXPR => true, 82 RET_TYPE => true,
67 _ => false, 83 _ => false,
68 } 84 }
69 } 85 }
@@ -78,19 +94,19 @@ impl AstNode for ArrayExpr {
78 &self.syntax 94 &self.syntax
79 } 95 }
80} 96}
81impl ArrayExpr { 97impl RetType {
82 pub fn exprs(&self) -> AstChildren<Expr> { 98 pub fn type_ref(&self) -> Option<TypeRef> {
83 AstChildren::new(&self.syntax) 99 AstChildren::new(&self.syntax).next()
84 } 100 }
85} 101}
86#[derive(Debug, Clone, PartialEq, Eq, Hash)] 102#[derive(Debug, Clone, PartialEq, Eq, Hash)]
87pub struct ArrayType { 103pub struct StructDef {
88 pub(crate) syntax: SyntaxNode, 104 pub(crate) syntax: SyntaxNode,
89} 105}
90impl AstNode for ArrayType { 106impl AstNode for StructDef {
91 fn can_cast(kind: SyntaxKind) -> bool { 107 fn can_cast(kind: SyntaxKind) -> bool {
92 match kind { 108 match kind {
93 ARRAY_TYPE => true, 109 STRUCT_DEF => true,
94 _ => false, 110 _ => false,
95 } 111 }
96 } 112 }
@@ -105,22 +121,20 @@ impl AstNode for ArrayType {
105 &self.syntax 121 &self.syntax
106 } 122 }
107} 123}
108impl ArrayType { 124impl ast::VisibilityOwner for StructDef {}
109 pub fn type_ref(&self) -> Option<TypeRef> { 125impl ast::NameOwner for StructDef {}
110 AstChildren::new(&self.syntax).next() 126impl ast::TypeParamsOwner for StructDef {}
111 } 127impl ast::AttrsOwner for StructDef {}
112 pub fn expr(&self) -> Option<Expr> { 128impl ast::DocCommentsOwner for StructDef {}
113 AstChildren::new(&self.syntax).next() 129impl StructDef {}
114 }
115}
116#[derive(Debug, Clone, PartialEq, Eq, Hash)] 130#[derive(Debug, Clone, PartialEq, Eq, Hash)]
117pub struct AssocTypeArg { 131pub struct UnionDef {
118 pub(crate) syntax: SyntaxNode, 132 pub(crate) syntax: SyntaxNode,
119} 133}
120impl AstNode for AssocTypeArg { 134impl AstNode for UnionDef {
121 fn can_cast(kind: SyntaxKind) -> bool { 135 fn can_cast(kind: SyntaxKind) -> bool {
122 match kind { 136 match kind {
123 ASSOC_TYPE_ARG => true, 137 UNION_DEF => true,
124 _ => false, 138 _ => false,
125 } 139 }
126 } 140 }
@@ -135,22 +149,24 @@ impl AstNode for AssocTypeArg {
135 &self.syntax 149 &self.syntax
136 } 150 }
137} 151}
138impl AssocTypeArg { 152impl ast::VisibilityOwner for UnionDef {}
139 pub fn name_ref(&self) -> Option<NameRef> { 153impl ast::NameOwner for UnionDef {}
140 AstChildren::new(&self.syntax).next() 154impl ast::TypeParamsOwner for UnionDef {}
141 } 155impl ast::AttrsOwner for UnionDef {}
142 pub fn type_ref(&self) -> Option<TypeRef> { 156impl ast::DocCommentsOwner for UnionDef {}
157impl UnionDef {
158 pub fn record_field_def_list(&self) -> Option<RecordFieldDefList> {
143 AstChildren::new(&self.syntax).next() 159 AstChildren::new(&self.syntax).next()
144 } 160 }
145} 161}
146#[derive(Debug, Clone, PartialEq, Eq, Hash)] 162#[derive(Debug, Clone, PartialEq, Eq, Hash)]
147pub struct Attr { 163pub struct RecordFieldDefList {
148 pub(crate) syntax: SyntaxNode, 164 pub(crate) syntax: SyntaxNode,
149} 165}
150impl AstNode for Attr { 166impl AstNode for RecordFieldDefList {
151 fn can_cast(kind: SyntaxKind) -> bool { 167 fn can_cast(kind: SyntaxKind) -> bool {
152 match kind { 168 match kind {
153 ATTR => true, 169 RECORD_FIELD_DEF_LIST => true,
154 _ => false, 170 _ => false,
155 } 171 }
156 } 172 }
@@ -165,60 +181,47 @@ impl AstNode for Attr {
165 &self.syntax 181 &self.syntax
166 } 182 }
167} 183}
168impl Attr { 184impl RecordFieldDefList {
169 pub fn path(&self) -> Option<Path> { 185 pub fn fields(&self) -> AstChildren<RecordFieldDef> {
170 AstChildren::new(&self.syntax).next() 186 AstChildren::new(&self.syntax)
171 }
172 pub fn input(&self) -> Option<AttrInput> {
173 AstChildren::new(&self.syntax).next()
174 } 187 }
175} 188}
176#[derive(Debug, Clone, PartialEq, Eq, Hash)] 189#[derive(Debug, Clone, PartialEq, Eq, Hash)]
177pub enum AttrInput { 190pub struct RecordFieldDef {
178 Literal(Literal), 191 pub(crate) syntax: SyntaxNode,
179 TokenTree(TokenTree),
180}
181impl From<Literal> for AttrInput {
182 fn from(node: Literal) -> AttrInput {
183 AttrInput::Literal(node)
184 }
185}
186impl From<TokenTree> for AttrInput {
187 fn from(node: TokenTree) -> AttrInput {
188 AttrInput::TokenTree(node)
189 }
190} 192}
191impl AstNode for AttrInput { 193impl AstNode for RecordFieldDef {
192 fn can_cast(kind: SyntaxKind) -> bool { 194 fn can_cast(kind: SyntaxKind) -> bool {
193 match kind { 195 match kind {
194 LITERAL | TOKEN_TREE => true, 196 RECORD_FIELD_DEF => true,
195 _ => false, 197 _ => false,
196 } 198 }
197 } 199 }
198 fn cast(syntax: SyntaxNode) -> Option<Self> { 200 fn cast(syntax: SyntaxNode) -> Option<Self> {
199 let res = match syntax.kind() { 201 if Self::can_cast(syntax.kind()) {
200 LITERAL => AttrInput::Literal(Literal { syntax }), 202 Some(Self { syntax })
201 TOKEN_TREE => AttrInput::TokenTree(TokenTree { syntax }), 203 } else {
202 _ => return None, 204 None
203 }; 205 }
204 Some(res)
205 } 206 }
206 fn syntax(&self) -> &SyntaxNode { 207 fn syntax(&self) -> &SyntaxNode {
207 match self { 208 &self.syntax
208 AttrInput::Literal(it) => &it.syntax,
209 AttrInput::TokenTree(it) => &it.syntax,
210 }
211 } 209 }
212} 210}
213impl AttrInput {} 211impl ast::VisibilityOwner for RecordFieldDef {}
212impl ast::NameOwner for RecordFieldDef {}
213impl ast::AttrsOwner for RecordFieldDef {}
214impl ast::DocCommentsOwner for RecordFieldDef {}
215impl ast::TypeAscriptionOwner for RecordFieldDef {}
216impl RecordFieldDef {}
214#[derive(Debug, Clone, PartialEq, Eq, Hash)] 217#[derive(Debug, Clone, PartialEq, Eq, Hash)]
215pub struct AwaitExpr { 218pub struct TupleFieldDefList {
216 pub(crate) syntax: SyntaxNode, 219 pub(crate) syntax: SyntaxNode,
217} 220}
218impl AstNode for AwaitExpr { 221impl AstNode for TupleFieldDefList {
219 fn can_cast(kind: SyntaxKind) -> bool { 222 fn can_cast(kind: SyntaxKind) -> bool {
220 match kind { 223 match kind {
221 AWAIT_EXPR => true, 224 TUPLE_FIELD_DEF_LIST => true,
222 _ => false, 225 _ => false,
223 } 226 }
224 } 227 }
@@ -233,19 +236,19 @@ impl AstNode for AwaitExpr {
233 &self.syntax 236 &self.syntax
234 } 237 }
235} 238}
236impl AwaitExpr { 239impl TupleFieldDefList {
237 pub fn expr(&self) -> Option<Expr> { 240 pub fn fields(&self) -> AstChildren<TupleFieldDef> {
238 AstChildren::new(&self.syntax).next() 241 AstChildren::new(&self.syntax)
239 } 242 }
240} 243}
241#[derive(Debug, Clone, PartialEq, Eq, Hash)] 244#[derive(Debug, Clone, PartialEq, Eq, Hash)]
242pub struct BinExpr { 245pub struct TupleFieldDef {
243 pub(crate) syntax: SyntaxNode, 246 pub(crate) syntax: SyntaxNode,
244} 247}
245impl AstNode for BinExpr { 248impl AstNode for TupleFieldDef {
246 fn can_cast(kind: SyntaxKind) -> bool { 249 fn can_cast(kind: SyntaxKind) -> bool {
247 match kind { 250 match kind {
248 BIN_EXPR => true, 251 TUPLE_FIELD_DEF => true,
249 _ => false, 252 _ => false,
250 } 253 }
251 } 254 }
@@ -260,15 +263,21 @@ impl AstNode for BinExpr {
260 &self.syntax 263 &self.syntax
261 } 264 }
262} 265}
263impl BinExpr {} 266impl ast::VisibilityOwner for TupleFieldDef {}
267impl ast::AttrsOwner for TupleFieldDef {}
268impl TupleFieldDef {
269 pub fn type_ref(&self) -> Option<TypeRef> {
270 AstChildren::new(&self.syntax).next()
271 }
272}
264#[derive(Debug, Clone, PartialEq, Eq, Hash)] 273#[derive(Debug, Clone, PartialEq, Eq, Hash)]
265pub struct BindPat { 274pub struct EnumDef {
266 pub(crate) syntax: SyntaxNode, 275 pub(crate) syntax: SyntaxNode,
267} 276}
268impl AstNode for BindPat { 277impl AstNode for EnumDef {
269 fn can_cast(kind: SyntaxKind) -> bool { 278 fn can_cast(kind: SyntaxKind) -> bool {
270 match kind { 279 match kind {
271 BIND_PAT => true, 280 ENUM_DEF => true,
272 _ => false, 281 _ => false,
273 } 282 }
274 } 283 }
@@ -283,20 +292,24 @@ impl AstNode for BindPat {
283 &self.syntax 292 &self.syntax
284 } 293 }
285} 294}
286impl ast::NameOwner for BindPat {} 295impl ast::VisibilityOwner for EnumDef {}
287impl BindPat { 296impl ast::NameOwner for EnumDef {}
288 pub fn pat(&self) -> Option<Pat> { 297impl ast::TypeParamsOwner for EnumDef {}
298impl ast::AttrsOwner for EnumDef {}
299impl ast::DocCommentsOwner for EnumDef {}
300impl EnumDef {
301 pub fn variant_list(&self) -> Option<EnumVariantList> {
289 AstChildren::new(&self.syntax).next() 302 AstChildren::new(&self.syntax).next()
290 } 303 }
291} 304}
292#[derive(Debug, Clone, PartialEq, Eq, Hash)] 305#[derive(Debug, Clone, PartialEq, Eq, Hash)]
293pub struct Block { 306pub struct EnumVariantList {
294 pub(crate) syntax: SyntaxNode, 307 pub(crate) syntax: SyntaxNode,
295} 308}
296impl AstNode for Block { 309impl AstNode for EnumVariantList {
297 fn can_cast(kind: SyntaxKind) -> bool { 310 fn can_cast(kind: SyntaxKind) -> bool {
298 match kind { 311 match kind {
299 BLOCK => true, 312 ENUM_VARIANT_LIST => true,
300 _ => false, 313 _ => false,
301 } 314 }
302 } 315 }
@@ -311,24 +324,19 @@ impl AstNode for Block {
311 &self.syntax 324 &self.syntax
312 } 325 }
313} 326}
314impl ast::AttrsOwner for Block {} 327impl EnumVariantList {
315impl ast::ModuleItemOwner for Block {} 328 pub fn variants(&self) -> AstChildren<EnumVariant> {
316impl Block {
317 pub fn statements(&self) -> AstChildren<Stmt> {
318 AstChildren::new(&self.syntax) 329 AstChildren::new(&self.syntax)
319 } 330 }
320 pub fn expr(&self) -> Option<Expr> {
321 AstChildren::new(&self.syntax).next()
322 }
323} 331}
324#[derive(Debug, Clone, PartialEq, Eq, Hash)] 332#[derive(Debug, Clone, PartialEq, Eq, Hash)]
325pub struct BlockExpr { 333pub struct EnumVariant {
326 pub(crate) syntax: SyntaxNode, 334 pub(crate) syntax: SyntaxNode,
327} 335}
328impl AstNode for BlockExpr { 336impl AstNode for EnumVariant {
329 fn can_cast(kind: SyntaxKind) -> bool { 337 fn can_cast(kind: SyntaxKind) -> bool {
330 match kind { 338 match kind {
331 BLOCK_EXPR => true, 339 ENUM_VARIANT => true,
332 _ => false, 340 _ => false,
333 } 341 }
334 } 342 }
@@ -343,19 +351,22 @@ impl AstNode for BlockExpr {
343 &self.syntax 351 &self.syntax
344 } 352 }
345} 353}
346impl BlockExpr { 354impl ast::NameOwner for EnumVariant {}
347 pub fn block(&self) -> Option<Block> { 355impl ast::DocCommentsOwner for EnumVariant {}
356impl ast::AttrsOwner for EnumVariant {}
357impl EnumVariant {
358 pub fn expr(&self) -> Option<Expr> {
348 AstChildren::new(&self.syntax).next() 359 AstChildren::new(&self.syntax).next()
349 } 360 }
350} 361}
351#[derive(Debug, Clone, PartialEq, Eq, Hash)] 362#[derive(Debug, Clone, PartialEq, Eq, Hash)]
352pub struct BoxExpr { 363pub struct TraitDef {
353 pub(crate) syntax: SyntaxNode, 364 pub(crate) syntax: SyntaxNode,
354} 365}
355impl AstNode for BoxExpr { 366impl AstNode for TraitDef {
356 fn can_cast(kind: SyntaxKind) -> bool { 367 fn can_cast(kind: SyntaxKind) -> bool {
357 match kind { 368 match kind {
358 BOX_EXPR => true, 369 TRAIT_DEF => true,
359 _ => false, 370 _ => false,
360 } 371 }
361 } 372 }
@@ -370,19 +381,25 @@ impl AstNode for BoxExpr {
370 &self.syntax 381 &self.syntax
371 } 382 }
372} 383}
373impl BoxExpr { 384impl ast::VisibilityOwner for TraitDef {}
374 pub fn expr(&self) -> Option<Expr> { 385impl ast::NameOwner for TraitDef {}
386impl ast::AttrsOwner for TraitDef {}
387impl ast::DocCommentsOwner for TraitDef {}
388impl ast::TypeParamsOwner for TraitDef {}
389impl ast::TypeBoundsOwner for TraitDef {}
390impl TraitDef {
391 pub fn item_list(&self) -> Option<ItemList> {
375 AstChildren::new(&self.syntax).next() 392 AstChildren::new(&self.syntax).next()
376 } 393 }
377} 394}
378#[derive(Debug, Clone, PartialEq, Eq, Hash)] 395#[derive(Debug, Clone, PartialEq, Eq, Hash)]
379pub struct BoxPat { 396pub struct Module {
380 pub(crate) syntax: SyntaxNode, 397 pub(crate) syntax: SyntaxNode,
381} 398}
382impl AstNode for BoxPat { 399impl AstNode for Module {
383 fn can_cast(kind: SyntaxKind) -> bool { 400 fn can_cast(kind: SyntaxKind) -> bool {
384 match kind { 401 match kind {
385 BOX_PAT => true, 402 MODULE => true,
386 _ => false, 403 _ => false,
387 } 404 }
388 } 405 }
@@ -397,19 +414,23 @@ impl AstNode for BoxPat {
397 &self.syntax 414 &self.syntax
398 } 415 }
399} 416}
400impl BoxPat { 417impl ast::VisibilityOwner for Module {}
401 pub fn pat(&self) -> Option<Pat> { 418impl ast::NameOwner for Module {}
419impl ast::AttrsOwner for Module {}
420impl ast::DocCommentsOwner for Module {}
421impl Module {
422 pub fn item_list(&self) -> Option<ItemList> {
402 AstChildren::new(&self.syntax).next() 423 AstChildren::new(&self.syntax).next()
403 } 424 }
404} 425}
405#[derive(Debug, Clone, PartialEq, Eq, Hash)] 426#[derive(Debug, Clone, PartialEq, Eq, Hash)]
406pub struct BreakExpr { 427pub struct ItemList {
407 pub(crate) syntax: SyntaxNode, 428 pub(crate) syntax: SyntaxNode,
408} 429}
409impl AstNode for BreakExpr { 430impl AstNode for ItemList {
410 fn can_cast(kind: SyntaxKind) -> bool { 431 fn can_cast(kind: SyntaxKind) -> bool {
411 match kind { 432 match kind {
412 BREAK_EXPR => true, 433 ITEM_LIST => true,
413 _ => false, 434 _ => false,
414 } 435 }
415 } 436 }
@@ -424,19 +445,21 @@ impl AstNode for BreakExpr {
424 &self.syntax 445 &self.syntax
425 } 446 }
426} 447}
427impl BreakExpr { 448impl ast::FnDefOwner for ItemList {}
428 pub fn expr(&self) -> Option<Expr> { 449impl ast::ModuleItemOwner for ItemList {}
429 AstChildren::new(&self.syntax).next() 450impl ItemList {
451 pub fn impl_items(&self) -> AstChildren<ImplItem> {
452 AstChildren::new(&self.syntax)
430 } 453 }
431} 454}
432#[derive(Debug, Clone, PartialEq, Eq, Hash)] 455#[derive(Debug, Clone, PartialEq, Eq, Hash)]
433pub struct CallExpr { 456pub struct ConstDef {
434 pub(crate) syntax: SyntaxNode, 457 pub(crate) syntax: SyntaxNode,
435} 458}
436impl AstNode for CallExpr { 459impl AstNode for ConstDef {
437 fn can_cast(kind: SyntaxKind) -> bool { 460 fn can_cast(kind: SyntaxKind) -> bool {
438 match kind { 461 match kind {
439 CALL_EXPR => true, 462 CONST_DEF => true,
440 _ => false, 463 _ => false,
441 } 464 }
442 } 465 }
@@ -451,20 +474,25 @@ impl AstNode for CallExpr {
451 &self.syntax 474 &self.syntax
452 } 475 }
453} 476}
454impl ast::ArgListOwner for CallExpr {} 477impl ast::VisibilityOwner for ConstDef {}
455impl CallExpr { 478impl ast::NameOwner for ConstDef {}
456 pub fn expr(&self) -> Option<Expr> { 479impl ast::TypeParamsOwner for ConstDef {}
480impl ast::AttrsOwner for ConstDef {}
481impl ast::DocCommentsOwner for ConstDef {}
482impl ast::TypeAscriptionOwner for ConstDef {}
483impl ConstDef {
484 pub fn body(&self) -> Option<Expr> {
457 AstChildren::new(&self.syntax).next() 485 AstChildren::new(&self.syntax).next()
458 } 486 }
459} 487}
460#[derive(Debug, Clone, PartialEq, Eq, Hash)] 488#[derive(Debug, Clone, PartialEq, Eq, Hash)]
461pub struct CastExpr { 489pub struct StaticDef {
462 pub(crate) syntax: SyntaxNode, 490 pub(crate) syntax: SyntaxNode,
463} 491}
464impl AstNode for CastExpr { 492impl AstNode for StaticDef {
465 fn can_cast(kind: SyntaxKind) -> bool { 493 fn can_cast(kind: SyntaxKind) -> bool {
466 match kind { 494 match kind {
467 CAST_EXPR => true, 495 STATIC_DEF => true,
468 _ => false, 496 _ => false,
469 } 497 }
470 } 498 }
@@ -479,22 +507,25 @@ impl AstNode for CastExpr {
479 &self.syntax 507 &self.syntax
480 } 508 }
481} 509}
482impl CastExpr { 510impl ast::VisibilityOwner for StaticDef {}
483 pub fn expr(&self) -> Option<Expr> { 511impl ast::NameOwner for StaticDef {}
484 AstChildren::new(&self.syntax).next() 512impl ast::TypeParamsOwner for StaticDef {}
485 } 513impl ast::AttrsOwner for StaticDef {}
486 pub fn type_ref(&self) -> Option<TypeRef> { 514impl ast::DocCommentsOwner for StaticDef {}
515impl ast::TypeAscriptionOwner for StaticDef {}
516impl StaticDef {
517 pub fn body(&self) -> Option<Expr> {
487 AstChildren::new(&self.syntax).next() 518 AstChildren::new(&self.syntax).next()
488 } 519 }
489} 520}
490#[derive(Debug, Clone, PartialEq, Eq, Hash)] 521#[derive(Debug, Clone, PartialEq, Eq, Hash)]
491pub struct Condition { 522pub struct TypeAliasDef {
492 pub(crate) syntax: SyntaxNode, 523 pub(crate) syntax: SyntaxNode,
493} 524}
494impl AstNode for Condition { 525impl AstNode for TypeAliasDef {
495 fn can_cast(kind: SyntaxKind) -> bool { 526 fn can_cast(kind: SyntaxKind) -> bool {
496 match kind { 527 match kind {
497 CONDITION => true, 528 TYPE_ALIAS_DEF => true,
498 _ => false, 529 _ => false,
499 } 530 }
500 } 531 }
@@ -509,22 +540,25 @@ impl AstNode for Condition {
509 &self.syntax 540 &self.syntax
510 } 541 }
511} 542}
512impl Condition { 543impl ast::VisibilityOwner for TypeAliasDef {}
513 pub fn pat(&self) -> Option<Pat> { 544impl ast::NameOwner for TypeAliasDef {}
514 AstChildren::new(&self.syntax).next() 545impl ast::TypeParamsOwner for TypeAliasDef {}
515 } 546impl ast::AttrsOwner for TypeAliasDef {}
516 pub fn expr(&self) -> Option<Expr> { 547impl ast::DocCommentsOwner for TypeAliasDef {}
548impl ast::TypeBoundsOwner for TypeAliasDef {}
549impl TypeAliasDef {
550 pub fn type_ref(&self) -> Option<TypeRef> {
517 AstChildren::new(&self.syntax).next() 551 AstChildren::new(&self.syntax).next()
518 } 552 }
519} 553}
520#[derive(Debug, Clone, PartialEq, Eq, Hash)] 554#[derive(Debug, Clone, PartialEq, Eq, Hash)]
521pub struct ConstDef { 555pub struct ImplBlock {
522 pub(crate) syntax: SyntaxNode, 556 pub(crate) syntax: SyntaxNode,
523} 557}
524impl AstNode for ConstDef { 558impl AstNode for ImplBlock {
525 fn can_cast(kind: SyntaxKind) -> bool { 559 fn can_cast(kind: SyntaxKind) -> bool {
526 match kind { 560 match kind {
527 CONST_DEF => true, 561 IMPL_BLOCK => true,
528 _ => false, 562 _ => false,
529 } 563 }
530 } 564 }
@@ -539,25 +573,21 @@ impl AstNode for ConstDef {
539 &self.syntax 573 &self.syntax
540 } 574 }
541} 575}
542impl ast::VisibilityOwner for ConstDef {} 576impl ast::TypeParamsOwner for ImplBlock {}
543impl ast::NameOwner for ConstDef {} 577impl ast::AttrsOwner for ImplBlock {}
544impl ast::TypeParamsOwner for ConstDef {} 578impl ImplBlock {
545impl ast::AttrsOwner for ConstDef {} 579 pub fn item_list(&self) -> Option<ItemList> {
546impl ast::DocCommentsOwner for ConstDef {}
547impl ast::TypeAscriptionOwner for ConstDef {}
548impl ConstDef {
549 pub fn body(&self) -> Option<Expr> {
550 AstChildren::new(&self.syntax).next() 580 AstChildren::new(&self.syntax).next()
551 } 581 }
552} 582}
553#[derive(Debug, Clone, PartialEq, Eq, Hash)] 583#[derive(Debug, Clone, PartialEq, Eq, Hash)]
554pub struct ConstParam { 584pub struct ParenType {
555 pub(crate) syntax: SyntaxNode, 585 pub(crate) syntax: SyntaxNode,
556} 586}
557impl AstNode for ConstParam { 587impl AstNode for ParenType {
558 fn can_cast(kind: SyntaxKind) -> bool { 588 fn can_cast(kind: SyntaxKind) -> bool {
559 match kind { 589 match kind {
560 CONST_PARAM => true, 590 PAREN_TYPE => true,
561 _ => false, 591 _ => false,
562 } 592 }
563 } 593 }
@@ -572,22 +602,19 @@ impl AstNode for ConstParam {
572 &self.syntax 602 &self.syntax
573 } 603 }
574} 604}
575impl ast::NameOwner for ConstParam {} 605impl ParenType {
576impl ast::AttrsOwner for ConstParam {} 606 pub fn type_ref(&self) -> Option<TypeRef> {
577impl ast::TypeAscriptionOwner for ConstParam {}
578impl ConstParam {
579 pub fn default_val(&self) -> Option<Expr> {
580 AstChildren::new(&self.syntax).next() 607 AstChildren::new(&self.syntax).next()
581 } 608 }
582} 609}
583#[derive(Debug, Clone, PartialEq, Eq, Hash)] 610#[derive(Debug, Clone, PartialEq, Eq, Hash)]
584pub struct ContinueExpr { 611pub struct TupleType {
585 pub(crate) syntax: SyntaxNode, 612 pub(crate) syntax: SyntaxNode,
586} 613}
587impl AstNode for ContinueExpr { 614impl AstNode for TupleType {
588 fn can_cast(kind: SyntaxKind) -> bool { 615 fn can_cast(kind: SyntaxKind) -> bool {
589 match kind { 616 match kind {
590 CONTINUE_EXPR => true, 617 TUPLE_TYPE => true,
591 _ => false, 618 _ => false,
592 } 619 }
593 } 620 }
@@ -602,15 +629,19 @@ impl AstNode for ContinueExpr {
602 &self.syntax 629 &self.syntax
603 } 630 }
604} 631}
605impl ContinueExpr {} 632impl TupleType {
633 pub fn fields(&self) -> AstChildren<TypeRef> {
634 AstChildren::new(&self.syntax)
635 }
636}
606#[derive(Debug, Clone, PartialEq, Eq, Hash)] 637#[derive(Debug, Clone, PartialEq, Eq, Hash)]
607pub struct DotDotPat { 638pub struct NeverType {
608 pub(crate) syntax: SyntaxNode, 639 pub(crate) syntax: SyntaxNode,
609} 640}
610impl AstNode for DotDotPat { 641impl AstNode for NeverType {
611 fn can_cast(kind: SyntaxKind) -> bool { 642 fn can_cast(kind: SyntaxKind) -> bool {
612 match kind { 643 match kind {
613 DOT_DOT_PAT => true, 644 NEVER_TYPE => true,
614 _ => false, 645 _ => false,
615 } 646 }
616 } 647 }
@@ -625,15 +656,15 @@ impl AstNode for DotDotPat {
625 &self.syntax 656 &self.syntax
626 } 657 }
627} 658}
628impl DotDotPat {} 659impl NeverType {}
629#[derive(Debug, Clone, PartialEq, Eq, Hash)] 660#[derive(Debug, Clone, PartialEq, Eq, Hash)]
630pub struct DynTraitType { 661pub struct PathType {
631 pub(crate) syntax: SyntaxNode, 662 pub(crate) syntax: SyntaxNode,
632} 663}
633impl AstNode for DynTraitType { 664impl AstNode for PathType {
634 fn can_cast(kind: SyntaxKind) -> bool { 665 fn can_cast(kind: SyntaxKind) -> bool {
635 match kind { 666 match kind {
636 DYN_TRAIT_TYPE => true, 667 PATH_TYPE => true,
637 _ => false, 668 _ => false,
638 } 669 }
639 } 670 }
@@ -648,16 +679,19 @@ impl AstNode for DynTraitType {
648 &self.syntax 679 &self.syntax
649 } 680 }
650} 681}
651impl ast::TypeBoundsOwner for DynTraitType {} 682impl PathType {
652impl DynTraitType {} 683 pub fn path(&self) -> Option<Path> {
684 AstChildren::new(&self.syntax).next()
685 }
686}
653#[derive(Debug, Clone, PartialEq, Eq, Hash)] 687#[derive(Debug, Clone, PartialEq, Eq, Hash)]
654pub struct EnumDef { 688pub struct PointerType {
655 pub(crate) syntax: SyntaxNode, 689 pub(crate) syntax: SyntaxNode,
656} 690}
657impl AstNode for EnumDef { 691impl AstNode for PointerType {
658 fn can_cast(kind: SyntaxKind) -> bool { 692 fn can_cast(kind: SyntaxKind) -> bool {
659 match kind { 693 match kind {
660 ENUM_DEF => true, 694 POINTER_TYPE => true,
661 _ => false, 695 _ => false,
662 } 696 }
663 } 697 }
@@ -672,24 +706,19 @@ impl AstNode for EnumDef {
672 &self.syntax 706 &self.syntax
673 } 707 }
674} 708}
675impl ast::VisibilityOwner for EnumDef {} 709impl PointerType {
676impl ast::NameOwner for EnumDef {} 710 pub fn type_ref(&self) -> Option<TypeRef> {
677impl ast::TypeParamsOwner for EnumDef {}
678impl ast::AttrsOwner for EnumDef {}
679impl ast::DocCommentsOwner for EnumDef {}
680impl EnumDef {
681 pub fn variant_list(&self) -> Option<EnumVariantList> {
682 AstChildren::new(&self.syntax).next() 711 AstChildren::new(&self.syntax).next()
683 } 712 }
684} 713}
685#[derive(Debug, Clone, PartialEq, Eq, Hash)] 714#[derive(Debug, Clone, PartialEq, Eq, Hash)]
686pub struct EnumVariant { 715pub struct ArrayType {
687 pub(crate) syntax: SyntaxNode, 716 pub(crate) syntax: SyntaxNode,
688} 717}
689impl AstNode for EnumVariant { 718impl AstNode for ArrayType {
690 fn can_cast(kind: SyntaxKind) -> bool { 719 fn can_cast(kind: SyntaxKind) -> bool {
691 match kind { 720 match kind {
692 ENUM_VARIANT => true, 721 ARRAY_TYPE => true,
693 _ => false, 722 _ => false,
694 } 723 }
695 } 724 }
@@ -704,22 +733,22 @@ impl AstNode for EnumVariant {
704 &self.syntax 733 &self.syntax
705 } 734 }
706} 735}
707impl ast::NameOwner for EnumVariant {} 736impl ArrayType {
708impl ast::DocCommentsOwner for EnumVariant {} 737 pub fn type_ref(&self) -> Option<TypeRef> {
709impl ast::AttrsOwner for EnumVariant {} 738 AstChildren::new(&self.syntax).next()
710impl EnumVariant { 739 }
711 pub fn expr(&self) -> Option<Expr> { 740 pub fn expr(&self) -> Option<Expr> {
712 AstChildren::new(&self.syntax).next() 741 AstChildren::new(&self.syntax).next()
713 } 742 }
714} 743}
715#[derive(Debug, Clone, PartialEq, Eq, Hash)] 744#[derive(Debug, Clone, PartialEq, Eq, Hash)]
716pub struct EnumVariantList { 745pub struct SliceType {
717 pub(crate) syntax: SyntaxNode, 746 pub(crate) syntax: SyntaxNode,
718} 747}
719impl AstNode for EnumVariantList { 748impl AstNode for SliceType {
720 fn can_cast(kind: SyntaxKind) -> bool { 749 fn can_cast(kind: SyntaxKind) -> bool {
721 match kind { 750 match kind {
722 ENUM_VARIANT_LIST => true, 751 SLICE_TYPE => true,
723 _ => false, 752 _ => false,
724 } 753 }
725 } 754 }
@@ -734,294 +763,46 @@ impl AstNode for EnumVariantList {
734 &self.syntax 763 &self.syntax
735 } 764 }
736} 765}
737impl EnumVariantList { 766impl SliceType {
738 pub fn variants(&self) -> AstChildren<EnumVariant> { 767 pub fn type_ref(&self) -> Option<TypeRef> {
739 AstChildren::new(&self.syntax) 768 AstChildren::new(&self.syntax).next()
740 } 769 }
741} 770}
742#[derive(Debug, Clone, PartialEq, Eq, Hash)] 771#[derive(Debug, Clone, PartialEq, Eq, Hash)]
743pub enum Expr { 772pub struct ReferenceType {
744 TupleExpr(TupleExpr), 773 pub(crate) syntax: SyntaxNode,
745 ArrayExpr(ArrayExpr),
746 ParenExpr(ParenExpr),
747 PathExpr(PathExpr),
748 LambdaExpr(LambdaExpr),
749 IfExpr(IfExpr),
750 LoopExpr(LoopExpr),
751 ForExpr(ForExpr),
752 WhileExpr(WhileExpr),
753 ContinueExpr(ContinueExpr),
754 BreakExpr(BreakExpr),
755 Label(Label),
756 BlockExpr(BlockExpr),
757 ReturnExpr(ReturnExpr),
758 MatchExpr(MatchExpr),
759 RecordLit(RecordLit),
760 CallExpr(CallExpr),
761 IndexExpr(IndexExpr),
762 MethodCallExpr(MethodCallExpr),
763 FieldExpr(FieldExpr),
764 AwaitExpr(AwaitExpr),
765 TryExpr(TryExpr),
766 TryBlockExpr(TryBlockExpr),
767 CastExpr(CastExpr),
768 RefExpr(RefExpr),
769 PrefixExpr(PrefixExpr),
770 RangeExpr(RangeExpr),
771 BinExpr(BinExpr),
772 Literal(Literal),
773 MacroCall(MacroCall),
774 BoxExpr(BoxExpr),
775}
776impl From<TupleExpr> for Expr {
777 fn from(node: TupleExpr) -> Expr {
778 Expr::TupleExpr(node)
779 }
780}
781impl From<ArrayExpr> for Expr {
782 fn from(node: ArrayExpr) -> Expr {
783 Expr::ArrayExpr(node)
784 }
785}
786impl From<ParenExpr> for Expr {
787 fn from(node: ParenExpr) -> Expr {
788 Expr::ParenExpr(node)
789 }
790}
791impl From<PathExpr> for Expr {
792 fn from(node: PathExpr) -> Expr {
793 Expr::PathExpr(node)
794 }
795}
796impl From<LambdaExpr> for Expr {
797 fn from(node: LambdaExpr) -> Expr {
798 Expr::LambdaExpr(node)
799 }
800}
801impl From<IfExpr> for Expr {
802 fn from(node: IfExpr) -> Expr {
803 Expr::IfExpr(node)
804 }
805}
806impl From<LoopExpr> for Expr {
807 fn from(node: LoopExpr) -> Expr {
808 Expr::LoopExpr(node)
809 }
810}
811impl From<ForExpr> for Expr {
812 fn from(node: ForExpr) -> Expr {
813 Expr::ForExpr(node)
814 }
815}
816impl From<WhileExpr> for Expr {
817 fn from(node: WhileExpr) -> Expr {
818 Expr::WhileExpr(node)
819 }
820}
821impl From<ContinueExpr> for Expr {
822 fn from(node: ContinueExpr) -> Expr {
823 Expr::ContinueExpr(node)
824 }
825}
826impl From<BreakExpr> for Expr {
827 fn from(node: BreakExpr) -> Expr {
828 Expr::BreakExpr(node)
829 }
830}
831impl From<Label> for Expr {
832 fn from(node: Label) -> Expr {
833 Expr::Label(node)
834 }
835}
836impl From<BlockExpr> for Expr {
837 fn from(node: BlockExpr) -> Expr {
838 Expr::BlockExpr(node)
839 }
840}
841impl From<ReturnExpr> for Expr {
842 fn from(node: ReturnExpr) -> Expr {
843 Expr::ReturnExpr(node)
844 }
845}
846impl From<MatchExpr> for Expr {
847 fn from(node: MatchExpr) -> Expr {
848 Expr::MatchExpr(node)
849 }
850}
851impl From<RecordLit> for Expr {
852 fn from(node: RecordLit) -> Expr {
853 Expr::RecordLit(node)
854 }
855}
856impl From<CallExpr> for Expr {
857 fn from(node: CallExpr) -> Expr {
858 Expr::CallExpr(node)
859 }
860}
861impl From<IndexExpr> for Expr {
862 fn from(node: IndexExpr) -> Expr {
863 Expr::IndexExpr(node)
864 }
865}
866impl From<MethodCallExpr> for Expr {
867 fn from(node: MethodCallExpr) -> Expr {
868 Expr::MethodCallExpr(node)
869 }
870}
871impl From<FieldExpr> for Expr {
872 fn from(node: FieldExpr) -> Expr {
873 Expr::FieldExpr(node)
874 }
875}
876impl From<AwaitExpr> for Expr {
877 fn from(node: AwaitExpr) -> Expr {
878 Expr::AwaitExpr(node)
879 }
880}
881impl From<TryExpr> for Expr {
882 fn from(node: TryExpr) -> Expr {
883 Expr::TryExpr(node)
884 }
885}
886impl From<TryBlockExpr> for Expr {
887 fn from(node: TryBlockExpr) -> Expr {
888 Expr::TryBlockExpr(node)
889 }
890}
891impl From<CastExpr> for Expr {
892 fn from(node: CastExpr) -> Expr {
893 Expr::CastExpr(node)
894 }
895}
896impl From<RefExpr> for Expr {
897 fn from(node: RefExpr) -> Expr {
898 Expr::RefExpr(node)
899 }
900}
901impl From<PrefixExpr> for Expr {
902 fn from(node: PrefixExpr) -> Expr {
903 Expr::PrefixExpr(node)
904 }
905}
906impl From<RangeExpr> for Expr {
907 fn from(node: RangeExpr) -> Expr {
908 Expr::RangeExpr(node)
909 }
910}
911impl From<BinExpr> for Expr {
912 fn from(node: BinExpr) -> Expr {
913 Expr::BinExpr(node)
914 }
915}
916impl From<Literal> for Expr {
917 fn from(node: Literal) -> Expr {
918 Expr::Literal(node)
919 }
920}
921impl From<MacroCall> for Expr {
922 fn from(node: MacroCall) -> Expr {
923 Expr::MacroCall(node)
924 }
925}
926impl From<BoxExpr> for Expr {
927 fn from(node: BoxExpr) -> Expr {
928 Expr::BoxExpr(node)
929 }
930} 774}
931impl AstNode for Expr { 775impl AstNode for ReferenceType {
932 fn can_cast(kind: SyntaxKind) -> bool { 776 fn can_cast(kind: SyntaxKind) -> bool {
933 match kind { 777 match kind {
934 TUPLE_EXPR | ARRAY_EXPR | PAREN_EXPR | PATH_EXPR | LAMBDA_EXPR | IF_EXPR 778 REFERENCE_TYPE => true,
935 | LOOP_EXPR | FOR_EXPR | WHILE_EXPR | CONTINUE_EXPR | BREAK_EXPR | LABEL
936 | BLOCK_EXPR | RETURN_EXPR | MATCH_EXPR | RECORD_LIT | CALL_EXPR | INDEX_EXPR
937 | METHOD_CALL_EXPR | FIELD_EXPR | AWAIT_EXPR | TRY_EXPR | TRY_BLOCK_EXPR
938 | CAST_EXPR | REF_EXPR | PREFIX_EXPR | RANGE_EXPR | BIN_EXPR | LITERAL | MACRO_CALL
939 | BOX_EXPR => true,
940 _ => false, 779 _ => false,
941 } 780 }
942 } 781 }
943 fn cast(syntax: SyntaxNode) -> Option<Self> { 782 fn cast(syntax: SyntaxNode) -> Option<Self> {
944 let res = match syntax.kind() { 783 if Self::can_cast(syntax.kind()) {
945 TUPLE_EXPR => Expr::TupleExpr(TupleExpr { syntax }), 784 Some(Self { syntax })
946 ARRAY_EXPR => Expr::ArrayExpr(ArrayExpr { syntax }), 785 } else {
947 PAREN_EXPR => Expr::ParenExpr(ParenExpr { syntax }), 786 None
948 PATH_EXPR => Expr::PathExpr(PathExpr { syntax }), 787 }
949 LAMBDA_EXPR => Expr::LambdaExpr(LambdaExpr { syntax }),
950 IF_EXPR => Expr::IfExpr(IfExpr { syntax }),
951 LOOP_EXPR => Expr::LoopExpr(LoopExpr { syntax }),
952 FOR_EXPR => Expr::ForExpr(ForExpr { syntax }),
953 WHILE_EXPR => Expr::WhileExpr(WhileExpr { syntax }),
954 CONTINUE_EXPR => Expr::ContinueExpr(ContinueExpr { syntax }),
955 BREAK_EXPR => Expr::BreakExpr(BreakExpr { syntax }),
956 LABEL => Expr::Label(Label { syntax }),
957 BLOCK_EXPR => Expr::BlockExpr(BlockExpr { syntax }),
958 RETURN_EXPR => Expr::ReturnExpr(ReturnExpr { syntax }),
959 MATCH_EXPR => Expr::MatchExpr(MatchExpr { syntax }),
960 RECORD_LIT => Expr::RecordLit(RecordLit { syntax }),
961 CALL_EXPR => Expr::CallExpr(CallExpr { syntax }),
962 INDEX_EXPR => Expr::IndexExpr(IndexExpr { syntax }),
963 METHOD_CALL_EXPR => Expr::MethodCallExpr(MethodCallExpr { syntax }),
964 FIELD_EXPR => Expr::FieldExpr(FieldExpr { syntax }),
965 AWAIT_EXPR => Expr::AwaitExpr(AwaitExpr { syntax }),
966 TRY_EXPR => Expr::TryExpr(TryExpr { syntax }),
967 TRY_BLOCK_EXPR => Expr::TryBlockExpr(TryBlockExpr { syntax }),
968 CAST_EXPR => Expr::CastExpr(CastExpr { syntax }),
969 REF_EXPR => Expr::RefExpr(RefExpr { syntax }),
970 PREFIX_EXPR => Expr::PrefixExpr(PrefixExpr { syntax }),
971 RANGE_EXPR => Expr::RangeExpr(RangeExpr { syntax }),
972 BIN_EXPR => Expr::BinExpr(BinExpr { syntax }),
973 LITERAL => Expr::Literal(Literal { syntax }),
974 MACRO_CALL => Expr::MacroCall(MacroCall { syntax }),
975 BOX_EXPR => Expr::BoxExpr(BoxExpr { syntax }),
976 _ => return None,
977 };
978 Some(res)
979 } 788 }
980 fn syntax(&self) -> &SyntaxNode { 789 fn syntax(&self) -> &SyntaxNode {
981 match self { 790 &self.syntax
982 Expr::TupleExpr(it) => &it.syntax, 791 }
983 Expr::ArrayExpr(it) => &it.syntax, 792}
984 Expr::ParenExpr(it) => &it.syntax, 793impl ReferenceType {
985 Expr::PathExpr(it) => &it.syntax, 794 pub fn type_ref(&self) -> Option<TypeRef> {
986 Expr::LambdaExpr(it) => &it.syntax, 795 AstChildren::new(&self.syntax).next()
987 Expr::IfExpr(it) => &it.syntax,
988 Expr::LoopExpr(it) => &it.syntax,
989 Expr::ForExpr(it) => &it.syntax,
990 Expr::WhileExpr(it) => &it.syntax,
991 Expr::ContinueExpr(it) => &it.syntax,
992 Expr::BreakExpr(it) => &it.syntax,
993 Expr::Label(it) => &it.syntax,
994 Expr::BlockExpr(it) => &it.syntax,
995 Expr::ReturnExpr(it) => &it.syntax,
996 Expr::MatchExpr(it) => &it.syntax,
997 Expr::RecordLit(it) => &it.syntax,
998 Expr::CallExpr(it) => &it.syntax,
999 Expr::IndexExpr(it) => &it.syntax,
1000 Expr::MethodCallExpr(it) => &it.syntax,
1001 Expr::FieldExpr(it) => &it.syntax,
1002 Expr::AwaitExpr(it) => &it.syntax,
1003 Expr::TryExpr(it) => &it.syntax,
1004 Expr::TryBlockExpr(it) => &it.syntax,
1005 Expr::CastExpr(it) => &it.syntax,
1006 Expr::RefExpr(it) => &it.syntax,
1007 Expr::PrefixExpr(it) => &it.syntax,
1008 Expr::RangeExpr(it) => &it.syntax,
1009 Expr::BinExpr(it) => &it.syntax,
1010 Expr::Literal(it) => &it.syntax,
1011 Expr::MacroCall(it) => &it.syntax,
1012 Expr::BoxExpr(it) => &it.syntax,
1013 }
1014 } 796 }
1015} 797}
1016impl Expr {}
1017#[derive(Debug, Clone, PartialEq, Eq, Hash)] 798#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1018pub struct ExprStmt { 799pub struct PlaceholderType {
1019 pub(crate) syntax: SyntaxNode, 800 pub(crate) syntax: SyntaxNode,
1020} 801}
1021impl AstNode for ExprStmt { 802impl AstNode for PlaceholderType {
1022 fn can_cast(kind: SyntaxKind) -> bool { 803 fn can_cast(kind: SyntaxKind) -> bool {
1023 match kind { 804 match kind {
1024 EXPR_STMT => true, 805 PLACEHOLDER_TYPE => true,
1025 _ => false, 806 _ => false,
1026 } 807 }
1027 } 808 }
@@ -1036,19 +817,15 @@ impl AstNode for ExprStmt {
1036 &self.syntax 817 &self.syntax
1037 } 818 }
1038} 819}
1039impl ExprStmt { 820impl PlaceholderType {}
1040 pub fn expr(&self) -> Option<Expr> {
1041 AstChildren::new(&self.syntax).next()
1042 }
1043}
1044#[derive(Debug, Clone, PartialEq, Eq, Hash)] 821#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1045pub struct ExternCrateItem { 822pub struct FnPointerType {
1046 pub(crate) syntax: SyntaxNode, 823 pub(crate) syntax: SyntaxNode,
1047} 824}
1048impl AstNode for ExternCrateItem { 825impl AstNode for FnPointerType {
1049 fn can_cast(kind: SyntaxKind) -> bool { 826 fn can_cast(kind: SyntaxKind) -> bool {
1050 match kind { 827 match kind {
1051 EXTERN_CRATE_ITEM => true, 828 FN_POINTER_TYPE => true,
1052 _ => false, 829 _ => false,
1053 } 830 }
1054 } 831 }
@@ -1063,24 +840,22 @@ impl AstNode for ExternCrateItem {
1063 &self.syntax 840 &self.syntax
1064 } 841 }
1065} 842}
1066impl ast::AttrsOwner for ExternCrateItem {} 843impl FnPointerType {
1067impl ast::VisibilityOwner for ExternCrateItem {} 844 pub fn param_list(&self) -> Option<ParamList> {
1068impl ExternCrateItem {
1069 pub fn name_ref(&self) -> Option<NameRef> {
1070 AstChildren::new(&self.syntax).next() 845 AstChildren::new(&self.syntax).next()
1071 } 846 }
1072 pub fn alias(&self) -> Option<Alias> { 847 pub fn ret_type(&self) -> Option<RetType> {
1073 AstChildren::new(&self.syntax).next() 848 AstChildren::new(&self.syntax).next()
1074 } 849 }
1075} 850}
1076#[derive(Debug, Clone, PartialEq, Eq, Hash)] 851#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1077pub struct FieldExpr { 852pub struct ForType {
1078 pub(crate) syntax: SyntaxNode, 853 pub(crate) syntax: SyntaxNode,
1079} 854}
1080impl AstNode for FieldExpr { 855impl AstNode for ForType {
1081 fn can_cast(kind: SyntaxKind) -> bool { 856 fn can_cast(kind: SyntaxKind) -> bool {
1082 match kind { 857 match kind {
1083 FIELD_EXPR => true, 858 FOR_TYPE => true,
1084 _ => false, 859 _ => false,
1085 } 860 }
1086 } 861 }
@@ -1095,22 +870,19 @@ impl AstNode for FieldExpr {
1095 &self.syntax 870 &self.syntax
1096 } 871 }
1097} 872}
1098impl FieldExpr { 873impl ForType {
1099 pub fn expr(&self) -> Option<Expr> { 874 pub fn type_ref(&self) -> Option<TypeRef> {
1100 AstChildren::new(&self.syntax).next()
1101 }
1102 pub fn name_ref(&self) -> Option<NameRef> {
1103 AstChildren::new(&self.syntax).next() 875 AstChildren::new(&self.syntax).next()
1104 } 876 }
1105} 877}
1106#[derive(Debug, Clone, PartialEq, Eq, Hash)] 878#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1107pub struct FnDef { 879pub struct ImplTraitType {
1108 pub(crate) syntax: SyntaxNode, 880 pub(crate) syntax: SyntaxNode,
1109} 881}
1110impl AstNode for FnDef { 882impl AstNode for ImplTraitType {
1111 fn can_cast(kind: SyntaxKind) -> bool { 883 fn can_cast(kind: SyntaxKind) -> bool {
1112 match kind { 884 match kind {
1113 FN_DEF => true, 885 IMPL_TRAIT_TYPE => true,
1114 _ => false, 886 _ => false,
1115 } 887 }
1116 } 888 }
@@ -1125,30 +897,16 @@ impl AstNode for FnDef {
1125 &self.syntax 897 &self.syntax
1126 } 898 }
1127} 899}
1128impl ast::VisibilityOwner for FnDef {} 900impl ast::TypeBoundsOwner for ImplTraitType {}
1129impl ast::NameOwner for FnDef {} 901impl ImplTraitType {}
1130impl ast::TypeParamsOwner for FnDef {}
1131impl ast::AttrsOwner for FnDef {}
1132impl ast::DocCommentsOwner for FnDef {}
1133impl FnDef {
1134 pub fn param_list(&self) -> Option<ParamList> {
1135 AstChildren::new(&self.syntax).next()
1136 }
1137 pub fn body(&self) -> Option<BlockExpr> {
1138 AstChildren::new(&self.syntax).next()
1139 }
1140 pub fn ret_type(&self) -> Option<RetType> {
1141 AstChildren::new(&self.syntax).next()
1142 }
1143}
1144#[derive(Debug, Clone, PartialEq, Eq, Hash)] 902#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1145pub struct FnPointerType { 903pub struct DynTraitType {
1146 pub(crate) syntax: SyntaxNode, 904 pub(crate) syntax: SyntaxNode,
1147} 905}
1148impl AstNode for FnPointerType { 906impl AstNode for DynTraitType {
1149 fn can_cast(kind: SyntaxKind) -> bool { 907 fn can_cast(kind: SyntaxKind) -> bool {
1150 match kind { 908 match kind {
1151 FN_POINTER_TYPE => true, 909 DYN_TRAIT_TYPE => true,
1152 _ => false, 910 _ => false,
1153 } 911 }
1154 } 912 }
@@ -1163,22 +921,16 @@ impl AstNode for FnPointerType {
1163 &self.syntax 921 &self.syntax
1164 } 922 }
1165} 923}
1166impl FnPointerType { 924impl ast::TypeBoundsOwner for DynTraitType {}
1167 pub fn param_list(&self) -> Option<ParamList> { 925impl DynTraitType {}
1168 AstChildren::new(&self.syntax).next()
1169 }
1170 pub fn ret_type(&self) -> Option<RetType> {
1171 AstChildren::new(&self.syntax).next()
1172 }
1173}
1174#[derive(Debug, Clone, PartialEq, Eq, Hash)] 926#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1175pub struct ForExpr { 927pub struct TupleExpr {
1176 pub(crate) syntax: SyntaxNode, 928 pub(crate) syntax: SyntaxNode,
1177} 929}
1178impl AstNode for ForExpr { 930impl AstNode for TupleExpr {
1179 fn can_cast(kind: SyntaxKind) -> bool { 931 fn can_cast(kind: SyntaxKind) -> bool {
1180 match kind { 932 match kind {
1181 FOR_EXPR => true, 933 TUPLE_EXPR => true,
1182 _ => false, 934 _ => false,
1183 } 935 }
1184 } 936 }
@@ -1193,23 +945,19 @@ impl AstNode for ForExpr {
1193 &self.syntax 945 &self.syntax
1194 } 946 }
1195} 947}
1196impl ast::LoopBodyOwner for ForExpr {} 948impl TupleExpr {
1197impl ForExpr { 949 pub fn exprs(&self) -> AstChildren<Expr> {
1198 pub fn pat(&self) -> Option<Pat> { 950 AstChildren::new(&self.syntax)
1199 AstChildren::new(&self.syntax).next()
1200 }
1201 pub fn iterable(&self) -> Option<Expr> {
1202 AstChildren::new(&self.syntax).next()
1203 } 951 }
1204} 952}
1205#[derive(Debug, Clone, PartialEq, Eq, Hash)] 953#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1206pub struct ForType { 954pub struct ArrayExpr {
1207 pub(crate) syntax: SyntaxNode, 955 pub(crate) syntax: SyntaxNode,
1208} 956}
1209impl AstNode for ForType { 957impl AstNode for ArrayExpr {
1210 fn can_cast(kind: SyntaxKind) -> bool { 958 fn can_cast(kind: SyntaxKind) -> bool {
1211 match kind { 959 match kind {
1212 FOR_TYPE => true, 960 ARRAY_EXPR => true,
1213 _ => false, 961 _ => false,
1214 } 962 }
1215 } 963 }
@@ -1224,19 +972,19 @@ impl AstNode for ForType {
1224 &self.syntax 972 &self.syntax
1225 } 973 }
1226} 974}
1227impl ForType { 975impl ArrayExpr {
1228 pub fn type_ref(&self) -> Option<TypeRef> { 976 pub fn exprs(&self) -> AstChildren<Expr> {
1229 AstChildren::new(&self.syntax).next() 977 AstChildren::new(&self.syntax)
1230 } 978 }
1231} 979}
1232#[derive(Debug, Clone, PartialEq, Eq, Hash)] 980#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1233pub struct IfExpr { 981pub struct ParenExpr {
1234 pub(crate) syntax: SyntaxNode, 982 pub(crate) syntax: SyntaxNode,
1235} 983}
1236impl AstNode for IfExpr { 984impl AstNode for ParenExpr {
1237 fn can_cast(kind: SyntaxKind) -> bool { 985 fn can_cast(kind: SyntaxKind) -> bool {
1238 match kind { 986 match kind {
1239 IF_EXPR => true, 987 PAREN_EXPR => true,
1240 _ => false, 988 _ => false,
1241 } 989 }
1242 } 990 }
@@ -1251,19 +999,19 @@ impl AstNode for IfExpr {
1251 &self.syntax 999 &self.syntax
1252 } 1000 }
1253} 1001}
1254impl IfExpr { 1002impl ParenExpr {
1255 pub fn condition(&self) -> Option<Condition> { 1003 pub fn expr(&self) -> Option<Expr> {
1256 AstChildren::new(&self.syntax).next() 1004 AstChildren::new(&self.syntax).next()
1257 } 1005 }
1258} 1006}
1259#[derive(Debug, Clone, PartialEq, Eq, Hash)] 1007#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1260pub struct ImplBlock { 1008pub struct PathExpr {
1261 pub(crate) syntax: SyntaxNode, 1009 pub(crate) syntax: SyntaxNode,
1262} 1010}
1263impl AstNode for ImplBlock { 1011impl AstNode for PathExpr {
1264 fn can_cast(kind: SyntaxKind) -> bool { 1012 fn can_cast(kind: SyntaxKind) -> bool {
1265 match kind { 1013 match kind {
1266 IMPL_BLOCK => true, 1014 PATH_EXPR => true,
1267 _ => false, 1015 _ => false,
1268 } 1016 }
1269 } 1017 }
@@ -1278,68 +1026,52 @@ impl AstNode for ImplBlock {
1278 &self.syntax 1026 &self.syntax
1279 } 1027 }
1280} 1028}
1281impl ast::TypeParamsOwner for ImplBlock {} 1029impl PathExpr {
1282impl ast::AttrsOwner for ImplBlock {} 1030 pub fn path(&self) -> Option<Path> {
1283impl ImplBlock {
1284 pub fn item_list(&self) -> Option<ItemList> {
1285 AstChildren::new(&self.syntax).next() 1031 AstChildren::new(&self.syntax).next()
1286 } 1032 }
1287} 1033}
1288#[derive(Debug, Clone, PartialEq, Eq, Hash)] 1034#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1289pub enum ImplItem { 1035pub struct LambdaExpr {
1290 FnDef(FnDef), 1036 pub(crate) syntax: SyntaxNode,
1291 TypeAliasDef(TypeAliasDef),
1292 ConstDef(ConstDef),
1293}
1294impl From<FnDef> for ImplItem {
1295 fn from(node: FnDef) -> ImplItem {
1296 ImplItem::FnDef(node)
1297 }
1298}
1299impl From<TypeAliasDef> for ImplItem {
1300 fn from(node: TypeAliasDef) -> ImplItem {
1301 ImplItem::TypeAliasDef(node)
1302 }
1303}
1304impl From<ConstDef> for ImplItem {
1305 fn from(node: ConstDef) -> ImplItem {
1306 ImplItem::ConstDef(node)
1307 }
1308} 1037}
1309impl AstNode for ImplItem { 1038impl AstNode for LambdaExpr {
1310 fn can_cast(kind: SyntaxKind) -> bool { 1039 fn can_cast(kind: SyntaxKind) -> bool {
1311 match kind { 1040 match kind {
1312 FN_DEF | TYPE_ALIAS_DEF | CONST_DEF => true, 1041 LAMBDA_EXPR => true,
1313 _ => false, 1042 _ => false,
1314 } 1043 }
1315 } 1044 }
1316 fn cast(syntax: SyntaxNode) -> Option<Self> { 1045 fn cast(syntax: SyntaxNode) -> Option<Self> {
1317 let res = match syntax.kind() { 1046 if Self::can_cast(syntax.kind()) {
1318 FN_DEF => ImplItem::FnDef(FnDef { syntax }), 1047 Some(Self { syntax })
1319 TYPE_ALIAS_DEF => ImplItem::TypeAliasDef(TypeAliasDef { syntax }), 1048 } else {
1320 CONST_DEF => ImplItem::ConstDef(ConstDef { syntax }), 1049 None
1321 _ => return None, 1050 }
1322 };
1323 Some(res)
1324 } 1051 }
1325 fn syntax(&self) -> &SyntaxNode { 1052 fn syntax(&self) -> &SyntaxNode {
1326 match self { 1053 &self.syntax
1327 ImplItem::FnDef(it) => &it.syntax, 1054 }
1328 ImplItem::TypeAliasDef(it) => &it.syntax, 1055}
1329 ImplItem::ConstDef(it) => &it.syntax, 1056impl LambdaExpr {
1330 } 1057 pub fn param_list(&self) -> Option<ParamList> {
1058 AstChildren::new(&self.syntax).next()
1059 }
1060 pub fn ret_type(&self) -> Option<RetType> {
1061 AstChildren::new(&self.syntax).next()
1062 }
1063 pub fn body(&self) -> Option<Expr> {
1064 AstChildren::new(&self.syntax).next()
1331 } 1065 }
1332} 1066}
1333impl ast::AttrsOwner for ImplItem {}
1334impl ImplItem {}
1335#[derive(Debug, Clone, PartialEq, Eq, Hash)] 1067#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1336pub struct ImplTraitType { 1068pub struct IfExpr {
1337 pub(crate) syntax: SyntaxNode, 1069 pub(crate) syntax: SyntaxNode,
1338} 1070}
1339impl AstNode for ImplTraitType { 1071impl AstNode for IfExpr {
1340 fn can_cast(kind: SyntaxKind) -> bool { 1072 fn can_cast(kind: SyntaxKind) -> bool {
1341 match kind { 1073 match kind {
1342 IMPL_TRAIT_TYPE => true, 1074 IF_EXPR => true,
1343 _ => false, 1075 _ => false,
1344 } 1076 }
1345 } 1077 }
@@ -1354,16 +1086,19 @@ impl AstNode for ImplTraitType {
1354 &self.syntax 1086 &self.syntax
1355 } 1087 }
1356} 1088}
1357impl ast::TypeBoundsOwner for ImplTraitType {} 1089impl IfExpr {
1358impl ImplTraitType {} 1090 pub fn condition(&self) -> Option<Condition> {
1091 AstChildren::new(&self.syntax).next()
1092 }
1093}
1359#[derive(Debug, Clone, PartialEq, Eq, Hash)] 1094#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1360pub struct IndexExpr { 1095pub struct LoopExpr {
1361 pub(crate) syntax: SyntaxNode, 1096 pub(crate) syntax: SyntaxNode,
1362} 1097}
1363impl AstNode for IndexExpr { 1098impl AstNode for LoopExpr {
1364 fn can_cast(kind: SyntaxKind) -> bool { 1099 fn can_cast(kind: SyntaxKind) -> bool {
1365 match kind { 1100 match kind {
1366 INDEX_EXPR => true, 1101 LOOP_EXPR => true,
1367 _ => false, 1102 _ => false,
1368 } 1103 }
1369 } 1104 }
@@ -1378,15 +1113,16 @@ impl AstNode for IndexExpr {
1378 &self.syntax 1113 &self.syntax
1379 } 1114 }
1380} 1115}
1381impl IndexExpr {} 1116impl ast::LoopBodyOwner for LoopExpr {}
1117impl LoopExpr {}
1382#[derive(Debug, Clone, PartialEq, Eq, Hash)] 1118#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1383pub struct ItemList { 1119pub struct TryBlockExpr {
1384 pub(crate) syntax: SyntaxNode, 1120 pub(crate) syntax: SyntaxNode,
1385} 1121}
1386impl AstNode for ItemList { 1122impl AstNode for TryBlockExpr {
1387 fn can_cast(kind: SyntaxKind) -> bool { 1123 fn can_cast(kind: SyntaxKind) -> bool {
1388 match kind { 1124 match kind {
1389 ITEM_LIST => true, 1125 TRY_BLOCK_EXPR => true,
1390 _ => false, 1126 _ => false,
1391 } 1127 }
1392 } 1128 }
@@ -1401,21 +1137,19 @@ impl AstNode for ItemList {
1401 &self.syntax 1137 &self.syntax
1402 } 1138 }
1403} 1139}
1404impl ast::FnDefOwner for ItemList {} 1140impl TryBlockExpr {
1405impl ast::ModuleItemOwner for ItemList {} 1141 pub fn body(&self) -> Option<BlockExpr> {
1406impl ItemList { 1142 AstChildren::new(&self.syntax).next()
1407 pub fn impl_items(&self) -> AstChildren<ImplItem> {
1408 AstChildren::new(&self.syntax)
1409 } 1143 }
1410} 1144}
1411#[derive(Debug, Clone, PartialEq, Eq, Hash)] 1145#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1412pub struct Label { 1146pub struct ForExpr {
1413 pub(crate) syntax: SyntaxNode, 1147 pub(crate) syntax: SyntaxNode,
1414} 1148}
1415impl AstNode for Label { 1149impl AstNode for ForExpr {
1416 fn can_cast(kind: SyntaxKind) -> bool { 1150 fn can_cast(kind: SyntaxKind) -> bool {
1417 match kind { 1151 match kind {
1418 LABEL => true, 1152 FOR_EXPR => true,
1419 _ => false, 1153 _ => false,
1420 } 1154 }
1421 } 1155 }
@@ -1430,15 +1164,23 @@ impl AstNode for Label {
1430 &self.syntax 1164 &self.syntax
1431 } 1165 }
1432} 1166}
1433impl Label {} 1167impl ast::LoopBodyOwner for ForExpr {}
1168impl ForExpr {
1169 pub fn pat(&self) -> Option<Pat> {
1170 AstChildren::new(&self.syntax).next()
1171 }
1172 pub fn iterable(&self) -> Option<Expr> {
1173 AstChildren::new(&self.syntax).next()
1174 }
1175}
1434#[derive(Debug, Clone, PartialEq, Eq, Hash)] 1176#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1435pub struct LambdaExpr { 1177pub struct WhileExpr {
1436 pub(crate) syntax: SyntaxNode, 1178 pub(crate) syntax: SyntaxNode,
1437} 1179}
1438impl AstNode for LambdaExpr { 1180impl AstNode for WhileExpr {
1439 fn can_cast(kind: SyntaxKind) -> bool { 1181 fn can_cast(kind: SyntaxKind) -> bool {
1440 match kind { 1182 match kind {
1441 LAMBDA_EXPR => true, 1183 WHILE_EXPR => true,
1442 _ => false, 1184 _ =>