├── .gitattributes ├── .github └── workflows │ └── ci.yml ├── .gitignore ├── COPYRIGHT ├── Cargo.lock ├── Cargo.toml ├── LICENSE-APACHE ├── LICENSE-MIT ├── README.md ├── architecture.md ├── build.rs ├── changelog.md ├── ci └── setup-toolchain.sh ├── clients.md ├── contributing.md ├── debugging.md ├── racer ├── .github │ └── workflows │ │ └── ci.yml ├── .gitignore ├── .rustfmt.toml ├── CHANGELOG.md ├── Cargo.toml ├── LICENSE-MIT ├── README.md ├── fixtures │ ├── .cargo │ │ └── config │ └── arst │ │ ├── Cargo.toml │ │ └── src │ │ ├── lib.rs │ │ └── submodule │ │ └── mod.rs ├── interner │ ├── Cargo.toml │ └── src │ │ └── lib.rs ├── metadata │ ├── Cargo.toml │ └── src │ │ ├── lib.rs │ │ ├── mapping.rs │ │ └── metadata.rs ├── rust-toolchain.toml └── src │ └── racer │ ├── ast.rs │ ├── ast_types.rs │ ├── benches.rs │ ├── codecleaner.rs │ ├── codeiter.rs │ ├── core.rs │ ├── fileres.rs │ ├── lib.rs │ ├── matchers.rs │ ├── metadata.rs │ ├── nameres.rs │ ├── primitive.rs │ ├── project_model.rs │ ├── scopes.rs │ ├── snippets.rs │ ├── testutils.rs │ ├── typeinf.rs │ └── util.rs ├── rls-analysis ├── .gitignore ├── Cargo.toml ├── README.md ├── benches │ └── std_api_crate.rs ├── examples │ └── print-crate-id.rs ├── src │ ├── analysis.rs │ ├── lib.rs │ ├── listings │ │ └── mod.rs │ ├── loader.rs │ ├── lowering.rs │ ├── raw.rs │ ├── symbol_query.rs │ ├── test │ │ └── mod.rs │ └── util.rs └── test_data │ ├── .ignore │ ├── exprs │ ├── Cargo.lock │ ├── Cargo.toml │ ├── save-analysis │ │ └── exprs.json │ └── src │ │ └── main.rs │ ├── hello │ ├── Cargo.lock │ ├── Cargo.toml │ ├── save-analysis │ │ └── hello.json │ └── src │ │ └── main.rs │ ├── make_data.sh │ ├── rename │ ├── Cargo.lock │ ├── Cargo.toml │ ├── save-analysis │ │ └── rename.json │ └── src │ │ └── main.rs │ ├── rls-analysis │ ├── libbyteorder.json │ ├── libcfg_if.json │ ├── libderive_new.json │ ├── libeither.json │ ├── libfst.json │ ├── libitertools.json │ ├── libitoa.json │ ├── libjson.json │ ├── liblog.json │ ├── libproc_macro2.json │ ├── libquote.json │ ├── librls_analysis.json │ ├── librls_data.json │ ├── librls_span.json │ ├── libryu.json │ ├── libserde.json │ ├── libserde_json.json │ ├── libsyn.json │ └── libunicode_xid.json │ ├── rust-analysis │ ├── liballoc-dd00ad303ae24b18.json │ ├── libbacktrace_sys-c129970c5e23c3eb.json │ ├── libcompiler_builtins-8aed34fb6416e6f8.json │ ├── libcore-a5db6a3445116c08.json │ ├── liblibc-08bc34c3a07b089e.json │ ├── libpanic_abort-bc692285f7fa669f.json │ ├── libpanic_unwind-1400fdc1e89071fe.json │ ├── librustc_asan-78879868ade8efee.json │ ├── librustc_demangle-132fd86beaa57ca4.json │ ├── librustc_lsan-5fda8638db6a6948.json │ ├── librustc_msan-8492c3e570f2bd15.json │ ├── librustc_std_workspace_core-a48dbd3d0edd9076.json │ ├── librustc_tsan-859a51be98ad349f.json │ ├── libstd-af9bacceee784405.json │ └── libunwind-e14db3aa6fb2de70.json │ └── types │ ├── Cargo.lock │ ├── Cargo.toml │ ├── save-analysis │ └── types.json │ └── src │ └── main.rs ├── rls-data ├── .gitignore ├── Cargo.toml ├── README.md └── src │ ├── config.rs │ └── lib.rs ├── rls-ipc ├── .gitignore ├── Cargo.toml └── src │ ├── client.rs │ ├── lib.rs │ ├── rpc.rs │ └── server.rs ├── rls-rustc ├── .gitignore ├── COPYRIGHT ├── Cargo.toml ├── LICENSE-APACHE ├── LICENSE-MIT ├── README.md └── src │ ├── bin │ └── rustc.rs │ ├── clippy.rs │ ├── ipc.rs │ └── lib.rs ├── rls-span ├── .gitignore ├── Cargo.toml └── src │ ├── compiler.rs │ └── lib.rs ├── rls-vfs ├── .gitignore ├── Cargo.toml ├── benches │ └── bench.rs └── src │ ├── lib.rs │ └── test.rs ├── rls └── src │ ├── actions │ ├── diagnostics.rs │ ├── format.rs │ ├── hover.rs │ ├── mod.rs │ ├── notifications.rs │ ├── post_build.rs │ ├── progress.rs │ ├── requests.rs │ ├── run.rs │ └── work_pool.rs │ ├── build │ ├── cargo.rs │ ├── cargo_plan.rs │ ├── environment.rs │ ├── external.rs │ ├── ipc.rs │ ├── mod.rs │ ├── plan.rs │ └── rustc.rs │ ├── cmd.rs │ ├── concurrency.rs │ ├── config.rs │ ├── lib.rs │ ├── lsp_data.rs │ ├── main.rs │ ├── project_model.rs │ └── server │ ├── dispatch.rs │ ├── io.rs │ ├── message.rs │ └── mod.rs ├── rust-toolchain ├── rustfmt.toml └── tests ├── client.rs ├── fixtures ├── Cargo.lock ├── Cargo.toml ├── bin_lib │ ├── Cargo.lock │ ├── Cargo.toml │ ├── src │ │ ├── lib.rs │ │ └── main.rs │ └── tests │ │ └── tests.rs ├── borrow_error │ ├── Cargo.lock │ ├── Cargo.toml │ └── src │ │ └── main.rs ├── common │ ├── Cargo.lock │ ├── Cargo.toml │ └── src │ │ └── main.rs ├── compile_fail │ ├── Cargo.toml │ └── src │ │ └── lib.rs ├── compiler_message │ ├── cannot-find-type.json │ ├── clippy-const-static-lifetime.json │ ├── clippy-identity-op.json │ ├── consider-borrowing.json │ ├── macro-error-no-trait.json │ ├── macro-expected-token.json │ ├── mismatched-types.json │ ├── move-out-of-borrow.json │ ├── not-mut.json │ ├── type-annotations-needed.json │ ├── unused-use.json │ └── use-after-move.json ├── deglob │ ├── Cargo.lock │ ├── Cargo.toml │ └── src │ │ └── main.rs ├── dep_fail │ ├── Cargo.toml │ └── src │ │ └── main.rs ├── features │ ├── Cargo.lock │ ├── Cargo.toml │ └── src │ │ └── main.rs ├── find_all_refs_no_cfg_test │ ├── Cargo.lock │ ├── Cargo.toml │ └── src │ │ └── main.rs ├── find_impls │ ├── Cargo.lock │ ├── Cargo.toml │ └── src │ │ └── main.rs ├── hover │ ├── Cargo.lock │ ├── Cargo.toml │ ├── save_data │ │ ├── test_tooltip_01.rs.0003_011.json │ │ ├── test_tooltip_01.rs.0005_007.json │ │ ├── test_tooltip_01.rs.0007_007.json │ │ ├── test_tooltip_01.rs.0011_013.json │ │ ├── test_tooltip_01.rs.0013_009.json │ │ ├── test_tooltip_01.rs.0013_016.json │ │ ├── test_tooltip_01.rs.0015_008.json │ │ ├── test_tooltip_01.rs.0017_008.json │ │ ├── test_tooltip_01.rs.0020_011.json │ │ ├── test_tooltip_01.rs.0022_010.json │ │ ├── test_tooltip_01.rs.0022_019.json │ │ ├── test_tooltip_01.rs.0022_026.json │ │ ├── test_tooltip_01.rs.0022_035.json │ │ ├── test_tooltip_01.rs.0022_049.json │ │ ├── test_tooltip_01.rs.0023_011.json │ │ ├── test_tooltip_01.rs.0024_016.json │ │ ├── test_tooltip_01.rs.0024_023.json │ │ ├── test_tooltip_01.rs.0025_016.json │ │ ├── test_tooltip_01.rs.0025_023.json │ │ ├── test_tooltip_01.rs.0026_016.json │ │ ├── test_tooltip_01.rs.0026_023.json │ │ ├── test_tooltip_01.rs.0032_015.json │ │ ├── test_tooltip_01.rs.0046_006.json │ │ ├── test_tooltip_01.rs.0056_006.json │ │ ├── test_tooltip_01.rs.0057_030.json │ │ ├── test_tooltip_01.rs.0058_011.json │ │ ├── test_tooltip_01.rs.0058_026.json │ │ ├── test_tooltip_01.rs.0065_010.json │ │ ├── test_tooltip_01.rs.0070_011.json │ │ ├── test_tooltip_01.rs.0075_014.json │ │ ├── test_tooltip_01.rs.0075_050.json │ │ ├── test_tooltip_01.rs.0075_054.json │ │ ├── test_tooltip_01.rs.0076_007.json │ │ ├── test_tooltip_01.rs.0076_010.json │ │ ├── test_tooltip_01.rs.0077_020.json │ │ ├── test_tooltip_01.rs.0078_018.json │ │ ├── test_tooltip_01.rs.0083_011.json │ │ ├── test_tooltip_01.rs.0083_018.json │ │ ├── test_tooltip_01.rs.0085_025.json │ │ ├── test_tooltip_01.rs.0099_021.json │ │ ├── test_tooltip_01.rs.0103_021.json │ │ ├── test_tooltip_mod.rs.0012_014.json │ │ ├── test_tooltip_mod_use.rs.0001_014.json │ │ ├── test_tooltip_mod_use.rs.0002_014.json │ │ ├── test_tooltip_mod_use.rs.0002_025.json │ │ ├── test_tooltip_mod_use.rs.0003_028.json │ │ ├── test_tooltip_mod_use_external.rs.0001_007.json │ │ ├── test_tooltip_mod_use_external.rs.0002_007.json │ │ ├── test_tooltip_mod_use_external.rs.0002_012.json │ │ ├── test_tooltip_mod_use_external.rs.0004_012.json │ │ ├── test_tooltip_mod_use_external.rs.0005_012.json │ │ ├── test_tooltip_std.rs.0008_015.json │ │ ├── test_tooltip_std.rs.0008_027.json │ │ ├── test_tooltip_std.rs.0009_007.json │ │ ├── test_tooltip_std.rs.0009_012.json │ │ ├── test_tooltip_std.rs.0010_012.json │ │ ├── test_tooltip_std.rs.0010_020.json │ │ ├── test_tooltip_std.rs.0011_025.json │ │ ├── test_tooltip_std.rs.0012_033.json │ │ ├── test_tooltip_std.rs.0013_011.json │ │ ├── test_tooltip_std.rs.0013_018.json │ │ ├── test_tooltip_std.rs.0014_024.json │ │ ├── test_tooltip_std.rs.0015_017.json │ │ └── test_tooltip_std.rs.0015_025.json │ └── src │ │ ├── lib.rs │ │ ├── test_extract_decl.rs │ │ ├── test_extract_decl_multiline_empty_function.rs │ │ ├── test_extract_docs_attributes.rs │ │ ├── test_extract_docs_comment_block.rs │ │ ├── test_extract_docs_comment_first_line.rs │ │ ├── test_extract_docs_empty_line_before_decl.rs │ │ ├── test_extract_docs_module_docs.rs │ │ ├── test_extract_docs_module_docs_no_copyright.rs │ │ ├── test_extract_docs_module_docs_with_attribute.rs │ │ ├── test_tooltip_01.rs │ │ ├── test_tooltip_mod.rs │ │ ├── test_tooltip_mod_use.rs │ │ ├── test_tooltip_mod_use_external.rs │ │ └── test_tooltip_std.rs ├── infer_bin │ ├── Cargo.lock │ ├── Cargo.toml │ └── src │ │ └── main.rs ├── infer_custom_bin │ ├── Cargo.lock │ ├── Cargo.toml │ └── src │ │ └── custom_bin.rs ├── infer_lib │ ├── Cargo.lock │ ├── Cargo.toml │ └── src │ │ └── lib.rs ├── lens_run │ ├── Cargo.lock │ ├── Cargo.toml │ └── src │ │ └── main.rs ├── multiple_bins │ ├── Cargo.lock │ ├── Cargo.toml │ └── src │ │ ├── main.rs │ │ └── main2.rs ├── reformat │ ├── Cargo.lock │ ├── Cargo.toml │ ├── rustfmt.toml │ └── src │ │ ├── foo.rs │ │ └── main.rs ├── reformat_with_range │ ├── Cargo.lock │ ├── Cargo.toml │ ├── rustfmt.toml │ └── src │ │ └── main.rs ├── workspace_symbol │ ├── Cargo.lock │ ├── Cargo.toml │ └── src │ │ ├── foo.rs │ │ └── main.rs └── workspace_symbol_duplicates │ ├── Cargo.lock │ ├── Cargo.toml │ └── src │ ├── main.rs │ └── shared.rs ├── support ├── client │ ├── child_process.rs │ └── mod.rs ├── harness.rs ├── mod.rs ├── paths.rs └── project_builder.rs └── tooltip.rs /.gitattributes: -------------------------------------------------------------------------------- 1 | rls-analysis/test_data/rls-analysis/*.json binary 2 | rls-analysis/test_data/rust-analysis/*.json binary 3 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: 4 | pull_request: 5 | types: [opened, synchronize, reopened] 6 | push: 7 | branches: 8 | - '*' 9 | - master 10 | # Managed by bors 11 | - auto 12 | # Run nightly checks to detect possible breakage due to upstream rustc changes 13 | schedule: 14 | - cron: '0 0 * * *' 15 | 16 | jobs: 17 | build_and_test: 18 | strategy: 19 | fail-fast: false 20 | matrix: 21 | toolchain: 22 | - x86_64-unknown-linux-gnu 23 | - x86_64-apple-darwin 24 | - x86_64-pc-windows-msvc 25 | include: 26 | - toolchain: x86_64-unknown-linux-gnu 27 | builder: ubuntu-latest 28 | os: linux 29 | - toolchain: x86_64-apple-darwin 30 | builder: macos-latest 31 | os: macos 32 | - toolchain: x86_64-pc-windows-msvc 33 | builder: windows-latest 34 | os: windows 35 | env: 36 | CFG_RELEASE_CHANNEL: nightly 37 | CFG_RELEASE: nightly 38 | RUST_BACKTRACE: 1 39 | RLS_TEST_WAIT_FOR_AGES: 1 40 | 41 | name: nightly - ${{ matrix.toolchain }} 42 | runs-on: ${{ matrix.builder }} 43 | 44 | steps: 45 | - uses: actions/checkout@v2 46 | - name: Setup latest nightly toolchain 47 | run: bash ci/setup-toolchain.sh 48 | if: github.event_name == 'schedule' 49 | - run: rustup component add rust-src rust-analysis rustc-dev llvm-tools-preview 50 | if: github.event_name != 'schedule' 51 | - run: rustc -vV 52 | - run: cargo build -v 53 | - run: cargo test -v 54 | - run: cargo test -v test_tooltip_std -- --ignored 55 | # Test that we don't regress in-process compilation build 56 | - run: cargo test -v --no-default-features 57 | - run: cargo test -v --manifest-path=rls-analysis/Cargo.toml 58 | - run: cargo test -v --manifest-path=rls-data/Cargo.toml 59 | - run: cargo test -v --manifest-path=rls-ipc/Cargo.toml 60 | - run: cargo test -v --manifest-path=rls-rustc/Cargo.toml 61 | - run: cargo test -v --manifest-path=rls-span/Cargo.toml 62 | - run: cargo test -v --manifest-path=rls-vfs/Cargo.toml 63 | 64 | style: 65 | name: Check formatting 66 | runs-on: ubuntu-latest 67 | steps: 68 | - uses: actions/checkout@v2 69 | - run: cargo +stable fmt --manifest-path=Cargo.toml -- --check 70 | - run: cargo +stable fmt --manifest-path=rls-analysis/Cargo.toml -- --check 71 | - run: cargo +stable fmt --manifest-path=rls-data/Cargo.toml -- --check 72 | - run: cargo +stable fmt --manifest-path=rls-ipc/Cargo.toml -- --check 73 | - run: cargo +stable fmt --manifest-path=rls-rustc/Cargo.toml -- --check 74 | - run: cargo +stable fmt --manifest-path=rls-span/Cargo.toml -- --check 75 | - run: cargo +stable fmt --manifest-path=rls-vfs/Cargo.toml -- --check 76 | 77 | # https://forge.rust-lang.org/infra/docs/bors.html#adding-a-new-repository-to-bors 78 | build_result: 79 | name: bors build finished 80 | runs-on: ubuntu-latest 81 | needs: ["build_and_test"] 82 | steps: 83 | - name: Mark the job as successful 84 | run: exit 0 85 | if: success() 86 | - name: Mark the job as unsuccessful 87 | run: exit 1 88 | if: "!success()" 89 | 90 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .vscode 2 | .idea 3 | 4 | target 5 | -------------------------------------------------------------------------------- /COPYRIGHT: -------------------------------------------------------------------------------- 1 | Short version for non-lawyers: 2 | 3 | The Rust Project is dual-licensed under Apache 2.0 and MIT 4 | terms. 5 | 6 | 7 | Longer version: 8 | 9 | The Rust Project is copyright 2010, The Rust Project 10 | Developers. 11 | 12 | Licensed under the Apache License, Version 2.0 13 | or the MIT 15 | license , 16 | at your option. All files in the project carrying such 17 | notice may not be copied, modified, or distributed except 18 | according to those terms. 19 | 20 | * Additional copyright may be retained by contributors other 21 | than Mozilla, the Rust Project Developers, or the parties 22 | enumerated in this file. Such copyright can be determined 23 | on a case-by-case basis by examining the author of each 24 | portion of a file in the revision-control commit records 25 | of the project, or by consulting representative comments 26 | claiming copyright ownership for a file. 27 | 28 | For example, the text: 29 | 30 | "Copyright (c) 2011 Google Inc." 31 | 32 | appears in some files, and these files thereby denote 33 | that their author and copyright-holder is Google Inc. 34 | 35 | In all such cases, the absence of explicit licensing text 36 | indicates that the contributor chose to license their work 37 | for distribution under identical terms to those Mozilla 38 | has chosen for the collective work, enumerated at the top 39 | of this file. The only difference is the retention of 40 | copyright itself, held by the contributor. 41 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "rls" 3 | version = "1.41.0" 4 | edition = "2018" 5 | authors = ["Nick Cameron ", "The RLS developers"] 6 | description = "Rust Language Server - provides information about Rust programs to IDEs and other tools" 7 | license = "Apache-2.0/MIT" 8 | repository = "https://github.com/rust-lang/rls" 9 | categories = ["development-tools"] 10 | 11 | build = "build.rs" 12 | 13 | [lib] 14 | name = "rls" 15 | doctest = false 16 | path = "rls/src/lib.rs" 17 | 18 | [[bin]] 19 | name = "rls" 20 | test = false 21 | path = "rls/src/main.rs" 22 | 23 | [dependencies] 24 | # FIXME: Release rls-analysis 0.18.2 to crates.io 25 | rls-analysis = { version = "0.18.2", path = "rls-analysis" } 26 | rls-data = "0.19" 27 | # FIXME: Release rls-rustc 0.6.0 to crates.io 28 | rls-rustc = { version = "0.6.0", path = "rls-rustc" } 29 | rls-span = "0.5" 30 | rls-vfs = "0.8" 31 | rls-ipc = { version = "0.1.0", path = "rls-ipc", optional = true } 32 | 33 | anyhow = "1.0.26" 34 | cargo = { git = "https://github.com/rust-lang/cargo", rev = "5514f1e0e1b3650ed8a78306198e90b66b292693" } 35 | cargo-util = { git = "https://github.com/rust-lang/cargo", rev = "5514f1e0e1b3650ed8a78306198e90b66b292693" } 36 | cargo_metadata = "0.14" 37 | clippy_lints = { git = "https://github.com/rust-lang/rust-clippy", version = "0.1.60", optional = true } 38 | env_logger = "0.9" 39 | home = "0.5.1" 40 | itertools = "0.10" 41 | jsonrpc-core = "18" 42 | lsp-types = { version = "0.60", features = ["proposed"] } 43 | lazy_static = "1" 44 | log = "0.4" 45 | num_cpus = "1" 46 | racer = { path = "racer" } 47 | rand = "0.8" 48 | rayon = "1" 49 | rustc_tools_util = "0.2" 50 | rustfmt-nightly = { git = "https://github.com/rust-lang/rustfmt", rev = "5fa2727ddeef534a7cd437f9e288c221a2cf0b6a" } 51 | serde = "1.0" 52 | serde_json = "1.0" 53 | serde_derive = "1.0" 54 | serde_ignored = "0.1" 55 | url = "2" 56 | walkdir = "2" 57 | regex = "1" 58 | ordslice = "0.3" 59 | crossbeam-channel = "0.5" 60 | toml = "0.5" 61 | toml_edit = { version = "0.14.3", features = ["easy"] } 62 | heck = "0.4" 63 | 64 | # A noop dependency that changes in the Rust repository, it's a bit of a hack. 65 | # See the `src/tools/rustc-workspace-hack/README.md` file in `rust-lang/rust` 66 | # for more information. 67 | rustc-workspace-hack = "1.0.0" 68 | 69 | [dev-dependencies] 70 | difference = "2" 71 | tempfile = "3" 72 | lsp-codec = "0.3" 73 | tokio = { version = "1", default-features = false, features = ["rt", "time", "io-util", "process"] } 74 | tokio-util = { version = "0.6", default-features = false, features = ["codec"] } 75 | tokio-stream = "0.1" 76 | futures = "0.3" 77 | 78 | [build-dependencies] 79 | rustc_tools_util = "0.2" 80 | 81 | [features] 82 | clippy = ["clippy_lints", "rls-rustc/clippy"] 83 | ipc = ["rls-rustc/ipc", "rls-ipc/server"] 84 | default = ["ipc"] 85 | -------------------------------------------------------------------------------- /LICENSE-MIT: -------------------------------------------------------------------------------- 1 | Copyright (c) 2016 The Rust Project Developers 2 | 3 | Permission is hereby granted, free of charge, to any 4 | person obtaining a copy of this software and associated 5 | documentation files (the "Software"), to deal in the 6 | Software without restriction, including without 7 | limitation the rights to use, copy, modify, merge, 8 | publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software 10 | is furnished to do so, subject to the following 11 | conditions: 12 | 13 | The above copyright notice and this permission notice 14 | shall be included in all copies or substantial portions 15 | of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF 18 | ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 19 | TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 20 | PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT 21 | SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 22 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 23 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR 24 | IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 25 | DEALINGS IN THE SOFTWARE. 26 | -------------------------------------------------------------------------------- /build.rs: -------------------------------------------------------------------------------- 1 | use std::env; 2 | use std::path::Path; 3 | 4 | fn main() { 5 | println!("cargo:rerun-if-changed=build.rs"); 6 | println!("cargo:rerun-if-env-changed=CFG_RELEASE_CHANNEL"); 7 | 8 | println!( 9 | "cargo:rustc-env=GIT_HASH={}", 10 | rustc_tools_util::get_commit_hash().unwrap_or_default() 11 | ); 12 | println!( 13 | "cargo:rustc-env=COMMIT_DATE={}", 14 | rustc_tools_util::get_commit_date().unwrap_or_default() 15 | ); 16 | println!( 17 | "cargo:rustc-env=FIXTURES_DIR={}", 18 | Path::new(&env::var("CARGO_MANIFEST_DIR").unwrap()) 19 | .join("tests") 20 | .join("fixtures") 21 | .display() 22 | ); 23 | } 24 | -------------------------------------------------------------------------------- /changelog.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | ## [Unreleased] 4 | ### Added 5 | - Allow to override or disable default crate blacklist via new `crate_blacklist` setting 6 | - Support both owned and borrowed blacklisted crate names in `rls-analysis` 7 | - Publicly re-export `rls_analysis::raw::Crate` 8 | ### Changed 9 | - Formatting project files now only needs project to parse and expand macros (and not type-check) 10 | - Converted remaining crates `rls-*` to 2018 edition 11 | ### Removed 12 | - Removed `use_crate_blacklist` setting in favour of `crate_blacklist` 13 | ## [Beta] 14 | ### Changed 15 | - Fix spurious tests on slow disks by clearing `CARGO_TARGET_DIR` for tests 16 | - Document `RUSTC_SHIM_ENV_VAR_NAME` purpose 17 | - Disable `clear_env_rust_log` in CLI mode 18 | 19 | ### Fixed 20 | - Fixed passing `--file-lines` to external Rustfmt for whole-file formatting requests ([#1497](https://github.com/rust-lang/rls/pull/1497)) 21 | - Fixed RLS when used together with Cargo pipelined build feature ([#1500](https://github.com/rust-lang/rls/pull/1500)) 22 | 23 | ## [1.36.0] 24 | 25 | ### Changed 26 | - Cleaned up and converted `rls-{analysis, span}` to 2018 edition 27 | - Made `rls-{analysis, span}` use `serde` instead of `rustc_serialize ` by default 28 | - Clarified how `clippy_preference` setting works in README 29 | 30 | ### Removed 31 | - Removed support for obsolete `rustDocument/{beginBuild,diagnostics{Begin,End}}` LSP messages 32 | 33 | ### Fixed 34 | - Fixed destructive formatting edits due to miscalculated newlines in diffs ([#1455](https://github.com/rust-lang/rls/pull/1455)) 35 | 36 | [Unreleased]: https://github.com/rust-lang/rls/compare/beta...HEAD 37 | [Beta]: https://github.com/rust-lang/rls/compare/1.36.0...beta 38 | [1.36.0]: https://github.com/rust-lang/rls/compare/1.35.0...1.36.0 39 | -------------------------------------------------------------------------------- /ci/setup-toolchain.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # Set up the appropriate rustc toolchain 3 | 4 | set -e 5 | 6 | RTIM_PATH=$(command -v rustup-toolchain-install-master) || INSTALLED=false 7 | CARGO_HOME=${CARGO_HOME:-$HOME/.cargo} 8 | 9 | # Check if RTIM is not installed or installed in other locations not in ~/.cargo/bin 10 | if [[ "$INSTALLED" == false || "$RTIM_PATH" == $CARGO_HOME/bin/rustup-toolchain-install-master ]]; then 11 | cargo install rustup-toolchain-install-master 12 | else 13 | VERSION=$(rustup-toolchain-install-master -V | grep -o "[0-9.]*") 14 | REMOTE=$(cargo search rustup-toolchain-install-master | grep -o "[0-9.]*") 15 | echo "info: skipping updating rustup-toolchain-install-master at $RTIM_PATH" 16 | echo " current version : $VERSION" 17 | echo " remote version : $REMOTE" 18 | fi 19 | 20 | RUST_COMMIT=$(git ls-remote https://github.com/rust-lang/rust master | awk '{print $1}') 21 | 22 | if rustc +master -Vv 2>/dev/null | grep -q "$RUST_COMMIT"; then 23 | echo "info: master toolchain is up-to-date" 24 | exit 0 25 | fi 26 | 27 | if [[ -n "$HOST_TOOLCHAIN" ]]; then 28 | TOOLCHAIN=('--host' "$HOST_TOOLCHAIN") 29 | else 30 | TOOLCHAIN=() 31 | fi 32 | 33 | rustup-toolchain-install-master -f -n master "${TOOLCHAIN[@]}" -c rustc-dev -c llvm-tools -- "$RUST_COMMIT" 34 | rustup override set master 35 | 36 | -------------------------------------------------------------------------------- /racer/.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: 4 | pull_request: 5 | types: [opened, synchronize, reopened] 6 | push: 7 | branches: 8 | - master 9 | - '*' 10 | schedule: 11 | - cron: '0 0 * * *' # Nightly at 00:00 UTC 12 | 13 | jobs: 14 | build_and_test: 15 | strategy: 16 | fail-fast: false 17 | matrix: 18 | toolchain: 19 | - x86_64-unknown-linux-gnu 20 | - x86_64-apple-darwin 21 | - x86_64-pc-windows-msvc 22 | - i686-pc-windows-msvc 23 | include: 24 | - toolchain: x86_64-unknown-linux-gnu 25 | builder: ubuntu-latest 26 | os: linux 27 | - toolchain: x86_64-apple-darwin 28 | builder: macos-latest 29 | os: macos 30 | - toolchain: x86_64-pc-windows-msvc 31 | builder: windows-latest 32 | os: windows 33 | - toolchain: i686-pc-windows-msvc 34 | builder: windows-latest 35 | os: windows 36 | 37 | name: nightly - ${{ matrix.toolchain }} 38 | runs-on: ${{ matrix.builder }} 39 | 40 | steps: 41 | - uses: actions/checkout@v2 42 | - name: Use latest nightly on scheduled builds 43 | if: github.event_name == 'schedule' 44 | run: echo "nightly" > rust-toolchain 45 | - run: rustup set default-host ${{ matrix.toolchain }} 46 | - run: rustup component add rust-src 47 | - run: rustc -vV 48 | - run: cargo build --verbose --all 49 | - run: cargo test --all 50 | -------------------------------------------------------------------------------- /racer/.gitignore: -------------------------------------------------------------------------------- 1 | \#* 2 | src/scopes 3 | !.travis.yml 4 | *tmpfile* 5 | *.racertmp 6 | target/ 7 | *.py[cod] 8 | .vscode/** 9 | *.log -------------------------------------------------------------------------------- /racer/.rustfmt.toml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rust-lang/rls/04afefab3f993d6c59ecaaf9f3fcf7a5b8f6d2bc/racer/.rustfmt.toml -------------------------------------------------------------------------------- /racer/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "racer" 3 | version = "2.2.2" 4 | license = "MIT" 5 | description = "Code completion for Rust" 6 | authors = ["Phil Dawes ", "The Racer developers"] 7 | homepage = "https://github.com/racer-rust/racer" 8 | repository = "https://github.com/racer-rust/racer" 9 | edition = "2018" 10 | 11 | [lib] 12 | name = "racer" 13 | path = "src/racer/lib.rs" 14 | 15 | [dependencies] 16 | bitflags = "1.0" 17 | log = "0.4" 18 | env_logger = "0.7.1" 19 | lazy_static = "1.2" 20 | humantime = "2.0.0" 21 | derive_more = "0.99.2" 22 | rls-span = "0.5.1" 23 | lazycell = "1.2" 24 | 25 | [dependencies.racer-cargo-metadata] 26 | version = "0.1" 27 | path = "metadata" 28 | 29 | [features] 30 | default = ["metadata"] 31 | metadata = [] 32 | 33 | [package.metadata.rust-analyzer] 34 | # This package uses #[feature(rustc_private)] 35 | rustc_private = true 36 | -------------------------------------------------------------------------------- /racer/LICENSE-MIT: -------------------------------------------------------------------------------- 1 | Copyright (c) 2014 Phil Dawes 2 | 3 | Permission is hereby granted, free of charge, to any 4 | person obtaining a copy of this software and associated 5 | documentation files (the "Software"), to deal in the 6 | Software without restriction, including without 7 | limitation the rights to use, copy, modify, merge, 8 | publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software 10 | is furnished to do so, subject to the following 11 | conditions: 12 | 13 | The above copyright notice and this permission notice 14 | shall be included in all copies or substantial portions 15 | of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF 18 | ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 19 | TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 20 | PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT 21 | SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 22 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 23 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR 24 | IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 25 | DEALINGS IN THE SOFTWARE. 26 | -------------------------------------------------------------------------------- /racer/fixtures/.cargo/config: -------------------------------------------------------------------------------- 1 | paths = ["./arst"] 2 | -------------------------------------------------------------------------------- /racer/fixtures/arst/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "arst" 3 | version = "0.1.0" 4 | authors = ["Joe Wilm "] 5 | 6 | [dependencies] 7 | -------------------------------------------------------------------------------- /racer/fixtures/arst/src/lib.rs: -------------------------------------------------------------------------------- 1 | #[cfg(test)] 2 | mod tests { 3 | #[test] 4 | fn it_works() { 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /racer/fixtures/arst/src/submodule/mod.rs: -------------------------------------------------------------------------------- 1 | pub fn hello_submodule() { 2 | println!("Hello from submodule."); 3 | } -------------------------------------------------------------------------------- /racer/interner/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "racer-interner" 3 | version = "0.1.0" 4 | authors = ["Yuji Kanagawa "] 5 | license = "MIT" 6 | description = "thread-local string interner for racer-rust" 7 | homepage = "https://github.com/racer-rust/racer" 8 | repository = "https://github.com/racer-rust/racer" 9 | edition = "2018" 10 | 11 | [dependencies] 12 | serde = "1.0" 13 | -------------------------------------------------------------------------------- /racer/interner/src/lib.rs: -------------------------------------------------------------------------------- 1 | //! string interner 2 | //! same as cargo::core::interning.rs, but thread local and Deserializable 3 | 4 | use serde::{de::Visitor, Deserialize, Deserializer, Serialize, Serializer}; 5 | 6 | use std::cell::RefCell; 7 | use std::collections::HashSet; 8 | use std::error::Error; 9 | use std::fmt; 10 | use std::ops::Deref; 11 | use std::ptr; 12 | use std::str; 13 | 14 | fn leak(s: String) -> &'static str { 15 | Box::leak(s.into_boxed_str()) 16 | } 17 | 18 | thread_local! { 19 | static STRING_CACHE: RefCell> = Default::default(); 20 | } 21 | 22 | #[derive(Clone, Copy, PartialOrd, Ord, Eq, Hash)] 23 | pub struct InternedString { 24 | inner: &'static str, 25 | } 26 | 27 | impl PartialEq for InternedString { 28 | fn eq(&self, other: &InternedString) -> bool { 29 | ptr::eq(self.as_str(), other.as_str()) 30 | } 31 | } 32 | 33 | impl InternedString { 34 | pub fn new(st: &str) -> InternedString { 35 | STRING_CACHE.with(|cache| { 36 | let mut cache = cache.borrow_mut(); 37 | let s = cache.get(st).map(|&s| s).unwrap_or_else(|| { 38 | let s = leak(st.to_string()); 39 | cache.insert(s); 40 | s 41 | }); 42 | InternedString { inner: s } 43 | }) 44 | } 45 | 46 | pub fn new_if_exists(st: &str) -> Option { 47 | STRING_CACHE.with(|cache| cache.borrow().get(st).map(|&s| InternedString { inner: s })) 48 | } 49 | 50 | pub fn as_str(&self) -> &'static str { 51 | self.inner 52 | } 53 | } 54 | 55 | impl Deref for InternedString { 56 | type Target = str; 57 | fn deref(&self) -> &'static str { 58 | self.as_str() 59 | } 60 | } 61 | 62 | impl fmt::Debug for InternedString { 63 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 64 | fmt::Debug::fmt(self.as_str(), f) 65 | } 66 | } 67 | 68 | impl fmt::Display for InternedString { 69 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 70 | fmt::Display::fmt(self.as_str(), f) 71 | } 72 | } 73 | 74 | impl Serialize for InternedString { 75 | fn serialize(&self, serializer: S) -> Result 76 | where 77 | S: Serializer, 78 | { 79 | serializer.serialize_str(self.inner) 80 | } 81 | } 82 | 83 | impl<'de> Deserialize<'de> for InternedString { 84 | fn deserialize(deserializer: D) -> Result 85 | where 86 | D: Deserializer<'de>, 87 | { 88 | struct VisStr; 89 | impl<'de> Visitor<'de> for VisStr { 90 | type Value = InternedString; 91 | fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 92 | write!(f, "expecting string") 93 | } 94 | fn visit_borrowed_str(self, v: &'de str) -> Result { 95 | Ok(InternedString::new(v)) 96 | } 97 | } 98 | deserializer.deserialize_str(VisStr {}) 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /racer/metadata/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "racer-cargo-metadata" 3 | version = "0.1.2" 4 | authors = ["Yuji Kanagawa "] 5 | license = "MIT" 6 | description = "light-weight cargo metadata parser for racer" 7 | homepage = "https://github.com/racer-rust/racer" 8 | repository = "https://github.com/racer-rust/racer" 9 | edition = "2018" 10 | 11 | [dependencies] 12 | serde_json = "1.0" 13 | 14 | [dependencies.serde] 15 | version = "1.0" 16 | features = ["derive"] 17 | 18 | [dependencies.racer-interner] 19 | version = "0.1" 20 | path = "../interner" 21 | 22 | -------------------------------------------------------------------------------- /racer/metadata/src/lib.rs: -------------------------------------------------------------------------------- 1 | extern crate racer_interner; 2 | #[macro_use] 3 | extern crate serde; 4 | extern crate serde_json; 5 | 6 | pub mod mapping; 7 | pub mod metadata; 8 | 9 | use crate::metadata::Metadata; 10 | use std::env; 11 | use std::error::Error; 12 | use std::fmt; 13 | use std::io; 14 | use std::path::{Path, PathBuf}; 15 | use std::process::Command; 16 | use std::str::Utf8Error; 17 | 18 | #[derive(Debug)] 19 | pub enum ErrorKind { 20 | Encode(Utf8Error), 21 | Json(serde_json::Error), 22 | Io(io::Error), 23 | Subprocess(String), 24 | } 25 | 26 | impl fmt::Display for ErrorKind { 27 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 28 | match self { 29 | ErrorKind::Encode(e) => fmt::Display::fmt(e, f), 30 | ErrorKind::Json(e) => fmt::Display::fmt(e, f), 31 | ErrorKind::Io(e) => fmt::Display::fmt(e, f), 32 | ErrorKind::Subprocess(s) => write!(f, "stderr: {}", s), 33 | } 34 | } 35 | } 36 | 37 | impl Error for ErrorKind {} 38 | 39 | impl From for ErrorKind { 40 | fn from(e: Utf8Error) -> ErrorKind { 41 | ErrorKind::Encode(e) 42 | } 43 | } 44 | 45 | impl From for ErrorKind { 46 | fn from(e: serde_json::Error) -> ErrorKind { 47 | ErrorKind::Json(e) 48 | } 49 | } 50 | 51 | impl From for ErrorKind { 52 | fn from(e: io::Error) -> ErrorKind { 53 | ErrorKind::Io(e) 54 | } 55 | } 56 | 57 | pub fn find_manifest(mut current: &Path) -> Option { 58 | let file = "Cargo.toml"; 59 | if current.is_dir() { 60 | let manifest = current.join(file); 61 | if manifest.exists() { 62 | return Some(manifest); 63 | } 64 | } 65 | while let Some(parent) = current.parent() { 66 | let manifest = parent.join(file); 67 | if manifest.exists() { 68 | return Some(manifest); 69 | } 70 | current = parent; 71 | } 72 | None 73 | } 74 | 75 | pub fn run(manifest_path: &Path, frozen: bool) -> Result { 76 | let cargo = env::var("CARGO").unwrap_or_else(|_| "cargo".to_owned()); 77 | let mut cmd = Command::new(cargo); 78 | cmd.arg("metadata"); 79 | cmd.arg("--all-features"); 80 | cmd.args(&["--format-version", "1"]); 81 | cmd.args(&["--color", "never"]); 82 | cmd.arg("--manifest-path"); 83 | cmd.arg(manifest_path.as_os_str()); 84 | if frozen { 85 | cmd.arg("--frozen"); 86 | } 87 | let op = cmd.output()?; 88 | if !op.status.success() { 89 | let stderr = String::from_utf8(op.stderr).map_err(|e| e.utf8_error())?; 90 | return Err(ErrorKind::Subprocess(stderr)); 91 | } 92 | serde_json::from_slice(&op.stdout).map_err(From::from) 93 | } 94 | -------------------------------------------------------------------------------- /racer/metadata/src/metadata.rs: -------------------------------------------------------------------------------- 1 | //! Data structures for metadata 2 | use racer_interner::InternedString; 3 | use std::path::PathBuf; 4 | 5 | #[derive(Clone, Debug, Serialize, Deserialize)] 6 | pub struct Metadata { 7 | pub packages: Vec, 8 | pub workspace_members: Vec, 9 | pub resolve: Option, 10 | #[serde(default)] 11 | pub workspace_root: PathBuf, 12 | pub target_directory: PathBuf, 13 | version: usize, 14 | #[serde(skip)] 15 | __guard: (), 16 | } 17 | 18 | #[derive(Clone, Debug, Serialize, Deserialize)] 19 | pub struct Package { 20 | pub id: PackageId, 21 | pub targets: Vec, 22 | pub manifest_path: PathBuf, 23 | #[serde(default = "edition_default")] 24 | pub edition: InternedString, 25 | #[serde(skip)] 26 | __guard: (), 27 | } 28 | 29 | #[derive(Clone, Debug, Serialize, Deserialize)] 30 | pub struct Resolve { 31 | pub nodes: Vec, 32 | #[serde(skip)] 33 | __guard: (), 34 | } 35 | 36 | #[derive(Clone, Debug, Serialize, Deserialize)] 37 | pub struct ResolveNode { 38 | pub id: PackageId, 39 | pub dependencies: Vec, 40 | } 41 | 42 | #[derive(Clone, Debug, Serialize, Deserialize)] 43 | pub struct Target { 44 | pub name: InternedString, 45 | pub kind: Vec, 46 | pub src_path: PathBuf, 47 | #[serde(default = "edition_default")] 48 | pub edition: InternedString, 49 | #[serde(skip)] 50 | __guard: (), 51 | } 52 | 53 | const LIB_KINDS: [&'static str; 4] = ["lib", "rlib", "dylib", "proc-macro"]; 54 | 55 | impl Target { 56 | pub fn is_lib(&self) -> bool { 57 | self.kind.iter().any(|k| LIB_KINDS.contains(&k.as_str())) 58 | } 59 | pub fn is_2015(&self) -> bool { 60 | self.edition.as_str() == "2015" 61 | } 62 | } 63 | 64 | #[derive(Clone, Copy, Debug, Eq, PartialEq, Hash, Serialize, Deserialize)] 65 | pub struct PackageId(InternedString); 66 | 67 | impl PackageId { 68 | pub fn name(&self) -> &str { 69 | let idx = self.0.find(' ').expect("Whitespace not found"); 70 | &self.0[..idx] 71 | } 72 | } 73 | 74 | #[inline(always)] 75 | fn edition_default() -> InternedString { 76 | InternedString::new("2015") 77 | } 78 | -------------------------------------------------------------------------------- /racer/rust-toolchain.toml: -------------------------------------------------------------------------------- 1 | [toolchain] 2 | channel = "nightly-2022-04-06" 3 | components = ["rust-src", "rustc-dev"] 4 | -------------------------------------------------------------------------------- /racer/src/racer/benches.rs: -------------------------------------------------------------------------------- 1 | extern crate test; 2 | 3 | use std::env::var; 4 | use std::fs::File; 5 | use std::io::Read; 6 | use std::path::PathBuf; 7 | 8 | use codecleaner::code_chunks; 9 | use codeiter::StmtIndicesIter; 10 | use core::IndexedSource; 11 | use scopes::{mask_comments, mask_sub_scopes}; 12 | 13 | use self::test::Bencher; 14 | 15 | fn get_rust_file_str(path: &[&str]) -> String { 16 | let mut src_path = match var("RUST_SRC_PATH") { 17 | Ok(env) => PathBuf::from(&env), 18 | _ => panic!("Cannot find $RUST_SRC_PATH"), 19 | }; 20 | for &s in path.iter() { 21 | src_path.push(s); 22 | } 23 | 24 | let mut s = String::new(); 25 | File::open(&src_path) 26 | .unwrap() 27 | .read_to_string(&mut s) 28 | .unwrap(); 29 | s 30 | } 31 | 32 | #[bench] 33 | fn bench_code_chunks(b: &mut Bencher) { 34 | let src = &get_rust_file_str(&["liballoc", "vec.rs"]); 35 | b.iter(|| { 36 | test::black_box(code_chunks(src).collect::>()); 37 | }); 38 | } 39 | 40 | #[bench] 41 | fn bench_iter_stmts(b: &mut Bencher) { 42 | let src = &get_rust_file_str(&["liballoc", "vec.rs"]); 43 | b.iter(|| { 44 | test::black_box(StmtIndicesIter::from_parts(src, code_chunks(src)).collect::>()); 45 | }); 46 | } 47 | 48 | #[bench] 49 | fn bench_mask_comments(b: &mut Bencher) { 50 | let src_indexed = IndexedSource::new(get_rust_file_str(&["liballoc", "vec.rs"])); 51 | let src = src_indexed.as_src(); 52 | b.iter(|| { 53 | test::black_box(mask_comments(src)); 54 | }); 55 | } 56 | 57 | #[bench] 58 | fn bench_mask_sub_scopes(b: &mut Bencher) { 59 | let src = &get_rust_file_str(&["liballoc", "vec.rs"]); 60 | b.iter(|| { 61 | test::black_box(mask_sub_scopes(src)); 62 | }); 63 | } 64 | -------------------------------------------------------------------------------- /racer/src/racer/fileres.rs: -------------------------------------------------------------------------------- 1 | use crate::core::{BytePos, Coordinate, Match, MatchType, SearchType, Session, SessionExt}; 2 | use crate::matchers; 3 | use crate::nameres::RUST_SRC_PATH; 4 | use crate::project_model::Edition; 5 | use std::path::{Path, PathBuf}; 6 | 7 | /// get crate file from current path & crate name 8 | pub fn get_crate_file(name: &str, from_path: &Path, session: &Session<'_>) -> Option { 9 | debug!("get_crate_file {}, {:?}", name, from_path); 10 | get_std_file(name, session).or_else(|| get_outer_crates(name, from_path, session)) 11 | } 12 | 13 | pub fn get_std_file(name: &str, session: &Session<'_>) -> Option { 14 | if let Some(ref std_path) = *RUST_SRC_PATH { 15 | // try lib/lib.rs, like in the rust source dir 16 | let cratelibname = format!("lib{}", name); 17 | let filepath = std_path.join(cratelibname).join("lib.rs"); 18 | if filepath.exists() || session.contains_file(&filepath) { 19 | return Some(filepath); 20 | } 21 | // If not found, try using the new standard library directory layout 22 | let filepath = std_path.join(name).join("src").join("lib.rs"); 23 | if filepath.exists() || session.contains_file(&filepath) { 24 | return Some(filepath); 25 | } 26 | } 27 | return None; 28 | } 29 | 30 | /// 2018 style crate name resolution 31 | pub fn search_crate_names( 32 | searchstr: &str, 33 | search_type: SearchType, 34 | file_path: &Path, 35 | only_2018: bool, 36 | session: &Session<'_>, 37 | ) -> Vec { 38 | let manifest_path = try_vec!(session.project_model.discover_project_manifest(file_path)); 39 | if only_2018 { 40 | let edition = session 41 | .project_model 42 | .edition(&manifest_path) 43 | .unwrap_or(Edition::Ed2015); 44 | if edition < Edition::Ed2018 { 45 | return Vec::new(); 46 | } 47 | } 48 | let hyphenated = searchstr.replace('_', "-"); 49 | let searchstr = searchstr.to_owned(); 50 | session 51 | .project_model 52 | .search_dependencies( 53 | &manifest_path, 54 | Box::new(move |libname| match search_type { 55 | SearchType::ExactMatch => libname == hyphenated || libname == searchstr, 56 | SearchType::StartsWith => { 57 | libname.starts_with(&hyphenated) || libname.starts_with(&searchstr) 58 | } 59 | }), 60 | ) 61 | .into_iter() 62 | .map(|(name, path)| { 63 | let name = name.replace('-', "_"); 64 | let raw_src = session.load_raw_file(&path); 65 | Match { 66 | matchstr: name, 67 | filepath: path, 68 | point: BytePos::ZERO, 69 | coords: Some(Coordinate::start()), 70 | local: false, 71 | mtype: MatchType::Crate, 72 | contextstr: String::new(), 73 | docs: matchers::find_mod_doc(&raw_src, BytePos::ZERO), 74 | } 75 | }) 76 | .collect() 77 | } 78 | 79 | /// get module file from current path & crate name 80 | pub fn get_module_file(name: &str, parentdir: &Path, session: &Session<'_>) -> Option { 81 | // try just .rs 82 | let filepath = parentdir.join(format!("{}.rs", name)); 83 | if filepath.exists() || session.contains_file(&filepath) { 84 | return Some(filepath); 85 | } 86 | // try /mod.rs 87 | let filepath = parentdir.join(name).join("mod.rs"); 88 | if filepath.exists() || session.contains_file(&filepath) { 89 | return Some(filepath); 90 | } 91 | None 92 | } 93 | 94 | /// try to get outer crates 95 | /// if we have dependencies in cache, use it. 96 | /// else, call cargo-metadata(default) or fall back to rls 97 | fn get_outer_crates(libname: &str, from_path: &Path, session: &Session<'_>) -> Option { 98 | debug!( 99 | "[get_outer_crates] lib name: {:?}, from_path: {:?}", 100 | libname, from_path 101 | ); 102 | 103 | let manifest = session.project_model.discover_project_manifest(from_path)?; 104 | let res = session.project_model.resolve_dependency(&manifest, libname); 105 | res 106 | } 107 | -------------------------------------------------------------------------------- /racer/src/racer/lib.rs: -------------------------------------------------------------------------------- 1 | #![cfg_attr(feature = "nightly", feature(test))] 2 | #![feature(control_flow_enum)] 3 | #![feature(try_trait_v2)] 4 | #![feature(rustc_private)] 5 | 6 | #[macro_use] 7 | extern crate log; 8 | #[macro_use] 9 | extern crate lazy_static; 10 | #[macro_use] 11 | extern crate bitflags; 12 | 13 | #[macro_use] 14 | extern crate derive_more; 15 | 16 | extern crate rustc_ast; 17 | extern crate rustc_ast_pretty; 18 | extern crate rustc_data_structures; 19 | extern crate rustc_errors; 20 | extern crate rustc_parse; 21 | extern crate rustc_session; 22 | extern crate rustc_span; 23 | 24 | #[macro_use] 25 | mod testutils; 26 | #[macro_use] 27 | mod util; 28 | mod ast; 29 | mod ast_types; 30 | mod codecleaner; 31 | mod codeiter; 32 | mod core; 33 | mod fileres; 34 | mod matchers; 35 | #[cfg(feature = "metadata")] 36 | mod metadata; 37 | mod nameres; 38 | mod primitive; 39 | mod project_model; 40 | mod scopes; 41 | mod snippets; 42 | mod typeinf; 43 | 44 | pub use crate::ast_types::PathSearch; 45 | pub use crate::core::{ 46 | complete_from_file, complete_fully_qualified_name, find_definition, is_use_stmt, to_coords, 47 | to_point, 48 | }; 49 | pub use crate::core::{ 50 | BytePos, ByteRange, Coordinate, FileCache, FileLoader, Location, Match, MatchType, Session, 51 | }; 52 | pub use crate::primitive::PrimKind; 53 | pub use crate::project_model::{Edition, ProjectModelProvider}; 54 | pub use crate::snippets::snippet_for_match; 55 | pub use crate::util::expand_ident; 56 | 57 | pub use crate::util::{get_rust_src_path, RustSrcPathError}; 58 | 59 | #[cfg(all(feature = "nightly", test))] 60 | mod benches; 61 | -------------------------------------------------------------------------------- /racer/src/racer/project_model.rs: -------------------------------------------------------------------------------- 1 | use std::path::{Path, PathBuf}; 2 | 3 | #[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd)] 4 | pub enum Edition { 5 | Ed2015, 6 | Ed2018, 7 | Ed2021, 8 | } 9 | 10 | pub trait ProjectModelProvider { 11 | fn edition(&self, manifest: &Path) -> Option; 12 | fn discover_project_manifest(&self, path: &Path) -> Option; 13 | fn search_dependencies( 14 | &self, 15 | manifest: &Path, 16 | search_fn: Box bool>, 17 | ) -> Vec<(String, PathBuf)>; 18 | fn resolve_dependency(&self, manifest: &Path, dep_name: &str) -> Option; 19 | } 20 | -------------------------------------------------------------------------------- /racer/src/racer/testutils.rs: -------------------------------------------------------------------------------- 1 | #![cfg(test)] 2 | use crate::core::ByteRange; 3 | 4 | pub fn rejustify(src: &str) -> String { 5 | let s = &src[1..]; // remove the newline 6 | let mut sb = String::new(); 7 | for l in s.lines() { 8 | let tabless = &l[4..]; 9 | sb.push_str(tabless); 10 | if !tabless.is_empty() { 11 | sb.push_str("\n"); 12 | } 13 | } 14 | let newlen = sb.len() - 1; // remove the trailing newline 15 | sb.truncate(newlen); 16 | sb 17 | } 18 | 19 | pub fn slice(src: &str, range: ByteRange) -> &str { 20 | &src[range.to_range()] 21 | } 22 | -------------------------------------------------------------------------------- /rls-analysis/.gitignore: -------------------------------------------------------------------------------- 1 | target 2 | 3 | Cargo.lock 4 | -------------------------------------------------------------------------------- /rls-analysis/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "rls-analysis" 3 | version = "0.18.3" 4 | edition = "2018" 5 | authors = ["Nick Cameron "] 6 | description = "Library for processing rustc's save-analysis data for the RLS" 7 | license = "Apache-2.0/MIT" 8 | repository = "https://github.com/rust-lang/rls" 9 | categories = ["development-tools"] 10 | exclude = [ 11 | "test_data/*", 12 | ] 13 | 14 | [features] 15 | default = [] 16 | idents = ["rls-span/nightly"] 17 | derive = ["rls-data/derive", "rls-span/derive"] 18 | 19 | [dependencies] 20 | log = "0.4" 21 | rls-data = "= 0.19" 22 | rls-span = "0.5.2" 23 | derive-new = "0.5" 24 | fst = { version = "0.4", default-features = false } 25 | itertools = "0.10" 26 | json = "0.12" 27 | serde = "1.0" 28 | serde_json = "1.0" 29 | 30 | [dev-dependencies] 31 | lazy_static = "1" 32 | env_logger = "0.9" 33 | -------------------------------------------------------------------------------- /rls-analysis/README.md: -------------------------------------------------------------------------------- 1 | [![Build Status](https://travis-ci.org/nrc/rls-analysis.svg?branch=master)](https://travis-ci.org/nrc/rls-analysis) 2 | 3 | # rls-analysis 4 | 5 | Library for processing rustc's save-analysis data for the RLS. 6 | 7 | [API Documentation](https://docs.rs/rls-analysis/) 8 | -------------------------------------------------------------------------------- /rls-analysis/benches/std_api_crate.rs: -------------------------------------------------------------------------------- 1 | #![feature(test)] 2 | 3 | extern crate rls_analysis; 4 | #[macro_use] 5 | extern crate derive_new; 6 | #[macro_use] 7 | extern crate lazy_static; 8 | extern crate test; 9 | use test::Bencher; 10 | 11 | use std::path::{Path, PathBuf}; 12 | use std::sync::RwLock; 13 | 14 | use rls_analysis::{AnalysisHost, AnalysisLoader, SearchDirectory}; 15 | 16 | #[derive(Clone, new)] 17 | struct TestAnalysisLoader { 18 | path: PathBuf, 19 | } 20 | 21 | impl AnalysisLoader for TestAnalysisLoader { 22 | fn needs_hard_reload(&self, _path_prefix: &Path) -> bool { 23 | true 24 | } 25 | 26 | fn fresh_host(&self) -> AnalysisHost { 27 | AnalysisHost::new_with_loader(self.clone()) 28 | } 29 | 30 | fn set_path_prefix(&mut self, _path_prefix: &Path) {} 31 | 32 | fn abs_path_prefix(&self) -> Option { 33 | panic!(); 34 | } 35 | 36 | fn search_directories(&self) -> Vec { 37 | vec![SearchDirectory::new(self.path.clone(), None)] 38 | } 39 | } 40 | 41 | lazy_static! { 42 | static ref STDLIB_FILE_PATH: PathBuf = PathBuf::from("/checkout/src/libstd/lib.rs"); 43 | static ref STDLIB_DATA_PATH: PathBuf = PathBuf::from("test_data/rust-analysis"); 44 | static ref HOST: RwLock> = { 45 | let host = AnalysisHost::new_with_loader(TestAnalysisLoader::new(STDLIB_DATA_PATH.clone())); 46 | host.reload(&STDLIB_DATA_PATH, &STDLIB_DATA_PATH).unwrap(); 47 | RwLock::new(host) 48 | }; 49 | } 50 | 51 | #[bench] 52 | fn search_for_id(b: &mut Bencher) { 53 | let host = HOST.read().unwrap(); 54 | 55 | b.iter(|| { 56 | let _ = host.search_for_id("no_std"); 57 | }); 58 | } 59 | 60 | #[bench] 61 | fn search(b: &mut Bencher) { 62 | let host = HOST.read().unwrap(); 63 | b.iter(|| { 64 | let _ = host.search("some_inexistent_symbol"); 65 | }) 66 | } 67 | 68 | #[bench] 69 | fn symbols(b: &mut Bencher) { 70 | let host = HOST.read().unwrap(); 71 | b.iter(|| { 72 | let _ = host.symbols(&STDLIB_FILE_PATH); 73 | }) 74 | } 75 | 76 | #[bench] 77 | fn reload(b: &mut Bencher) { 78 | let host = HOST.write().unwrap(); 79 | b.iter(|| { 80 | host.reload(&STDLIB_DATA_PATH, &STDLIB_DATA_PATH).unwrap(); 81 | }) 82 | } 83 | -------------------------------------------------------------------------------- /rls-analysis/examples/print-crate-id.rs: -------------------------------------------------------------------------------- 1 | extern crate env_logger; 2 | extern crate rls_analysis; 3 | 4 | use rls_analysis::{AnalysisHost, AnalysisLoader, SearchDirectory}; 5 | use std::env; 6 | use std::path::{Path, PathBuf}; 7 | 8 | #[derive(Clone)] 9 | pub struct Loader { 10 | deps_dir: PathBuf, 11 | } 12 | 13 | impl Loader { 14 | pub fn new(deps_dir: PathBuf) -> Self { 15 | Self { deps_dir } 16 | } 17 | } 18 | 19 | impl AnalysisLoader for Loader { 20 | fn needs_hard_reload(&self, _: &Path) -> bool { 21 | true 22 | } 23 | 24 | fn fresh_host(&self) -> AnalysisHost { 25 | AnalysisHost::new_with_loader(self.clone()) 26 | } 27 | 28 | fn set_path_prefix(&mut self, _: &Path) {} 29 | 30 | fn abs_path_prefix(&self) -> Option { 31 | None 32 | } 33 | fn search_directories(&self) -> Vec { 34 | vec![SearchDirectory { path: self.deps_dir.clone(), prefix_rewrite: None }] 35 | } 36 | } 37 | 38 | fn main() { 39 | env_logger::init(); 40 | if env::args().len() < 2 { 41 | println!("Usage: print-crate-id "); 42 | std::process::exit(1); 43 | } 44 | let loader = Loader::new(PathBuf::from(env::args().nth(1).unwrap())); 45 | let crates = 46 | rls_analysis::read_analysis_from_files(&loader, Default::default(), &[] as &[&str]); 47 | 48 | for krate in &crates { 49 | println!("Crate {:?} data version {:?}", krate.id, krate.analysis.version); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /rls-analysis/src/listings/mod.rs: -------------------------------------------------------------------------------- 1 | use std::io; 2 | use std::path::Path; 3 | use std::time::SystemTime; 4 | 5 | #[derive(Debug, Clone)] 6 | pub struct DirectoryListing { 7 | pub path: Vec, 8 | pub files: Vec, 9 | } 10 | 11 | #[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd)] 12 | pub struct Listing { 13 | pub kind: ListingKind, 14 | pub name: String, 15 | } 16 | 17 | #[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd)] 18 | pub enum ListingKind { 19 | Directory, 20 | // Time last modified. 21 | File(SystemTime), 22 | } 23 | 24 | impl DirectoryListing { 25 | pub fn from_path(path: &Path) -> io::Result { 26 | let mut files = vec![]; 27 | let dir = path.read_dir()?; 28 | 29 | for entry in dir { 30 | if let Ok(entry) = entry { 31 | let name = entry.file_name().to_str().unwrap().to_owned(); 32 | if let Ok(file_type) = entry.file_type() { 33 | if file_type.is_dir() { 34 | files.push(Listing { kind: ListingKind::Directory, name }); 35 | } else if file_type.is_file() { 36 | files.push(Listing { 37 | kind: ListingKind::File(entry.metadata()?.modified()?), 38 | name, 39 | }); 40 | } 41 | } 42 | } 43 | } 44 | 45 | files.sort(); 46 | 47 | Ok(DirectoryListing { 48 | path: path.components().map(|c| c.as_os_str().to_str().unwrap().to_owned()).collect(), 49 | files, 50 | }) 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /rls-analysis/src/util.rs: -------------------------------------------------------------------------------- 1 | #[cfg(unix)] 2 | pub fn get_resident() -> Option { 3 | use std::fs::File; 4 | use std::io::Read; 5 | 6 | let field = 1; 7 | let mut f = File::open("/proc/self/statm").ok()?; 8 | let mut contents = String::new(); 9 | f.read_to_string(&mut contents).ok()?; 10 | let s = contents.split_whitespace().nth(field)?; 11 | let npages = s.parse::().ok()?; 12 | Some(npages * 4096) 13 | } 14 | 15 | #[cfg(not(unix))] 16 | pub fn get_resident() -> Option { 17 | None 18 | } 19 | -------------------------------------------------------------------------------- /rls-analysis/test_data/.ignore: -------------------------------------------------------------------------------- 1 | /rls-analysis 2 | /rust-analysis 3 | -------------------------------------------------------------------------------- /rls-analysis/test_data/exprs/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | [[package]] 4 | name = "exprs" 5 | version = "0.1.0" 6 | 7 | -------------------------------------------------------------------------------- /rls-analysis/test_data/exprs/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "exprs" 3 | version = "0.1.0" 4 | authors = ["Nick Cameron "] 5 | 6 | [dependencies] 7 | -------------------------------------------------------------------------------- /rls-analysis/test_data/exprs/src/main.rs: -------------------------------------------------------------------------------- 1 | struct Foo; 2 | 3 | impl Foo { 4 | fn bar(&self) { 5 | let _ = self; 6 | } 7 | } 8 | 9 | pub extern "C" fn foo() {} 10 | 11 | fn main() { 12 | foo(); 13 | } 14 | -------------------------------------------------------------------------------- /rls-analysis/test_data/hello/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | [[package]] 4 | name = "hello" 5 | version = "0.1.0" 6 | 7 | -------------------------------------------------------------------------------- /rls-analysis/test_data/hello/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "hello" 3 | version = "0.1.0" 4 | authors = ["Nick Cameron "] 5 | 6 | [dependencies] 7 | -------------------------------------------------------------------------------- /rls-analysis/test_data/hello/src/main.rs: -------------------------------------------------------------------------------- 1 | fn print_hello() { 2 | let name = "world"; 3 | println!("Hello, {}!", name); 4 | } 5 | 6 | fn main() { 7 | print_hello(); 8 | } 9 | -------------------------------------------------------------------------------- /rls-analysis/test_data/make_data.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # This script reproduces all save-analysis data in the test_data directories. 3 | 4 | # $1 is where to run cargo build 5 | # $2 is the output dir 6 | function build { 7 | echo "$1 => $2" 8 | output="$(pwd)/$2" 9 | pushd "$1" > /dev/null 10 | RUSTFLAGS=-Zsave-analysis cargo build 11 | cp target/debug/deps/save-analysis/*.json "$output" 12 | # strip all hashes from filenames libfoo-[hash].json -> libfoo.json 13 | for from in $output/*.json; do 14 | to=$(echo "$from" | sed -e "s/\(.*\)-[a-f0-9]*.json/\1.json/1") 15 | mv "$from" "$to" 16 | done 17 | popd > /dev/null 18 | } 19 | 20 | # Data for rls-analysis. This is essentially a bootstrap. Be careful when using 21 | # this data because the source is not pinned, therefore the data will change 22 | # regularly. It should basically just be used as a 'big'-ish set of real-world 23 | # data for smoke testing. 24 | 25 | rm rls-analysis/*.json 26 | build .. rls-analysis 27 | 28 | # Hello world test case 29 | build hello hello/save-analysis 30 | 31 | # Types 32 | build types types/save-analysis 33 | 34 | # Expressions 35 | build exprs exprs/save-analysis 36 | 37 | # all_ref_unique 38 | build rename rename/save-analysis 39 | -------------------------------------------------------------------------------- /rls-analysis/test_data/rename/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | [[package]] 4 | name = "rename" 5 | version = "0.1.0" 6 | 7 | -------------------------------------------------------------------------------- /rls-analysis/test_data/rename/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "rename" 3 | version = "0.1.0" 4 | authors = ["Nick Cameron "] 5 | 6 | [dependencies] 7 | -------------------------------------------------------------------------------- /rls-analysis/test_data/rename/src/main.rs: -------------------------------------------------------------------------------- 1 | mod a { 2 | pub fn bar() {} 3 | pub fn qux() {} 4 | } 5 | 6 | mod b { 7 | use a::qux; 8 | use a::bar as baz; 9 | 10 | pub fn foo() { 11 | qux(); 12 | baz(); 13 | } 14 | } 15 | 16 | fn main() {} 17 | -------------------------------------------------------------------------------- /rls-analysis/test_data/rls-analysis/libcfg_if.json: -------------------------------------------------------------------------------- 1 | {"config":{"output_file":null,"full_docs":false,"pub_only":false,"reachable_only":false,"distro_crate":false,"signatures":false,"borrow_data":false},"version":"0.19.0","compilation":{"directory":"/home/xanewok/.cargo/registry/src/github.com-1ecc6299db9ec823/cfg-if-0.1.7","program":"/home/xanewok/.rustup/toolchains/custom/bin/rustc","arguments":["--crate-name","cfg_if","/home/xanewok/.cargo/registry/src/github.com-1ecc6299db9ec823/cfg-if-0.1.7/src/lib.rs","--color","always","--crate-type","lib","--emit=dep-info,link","-C","debuginfo=2","-C","metadata=e80e175b9ec769c0","-C","extra-filename=-e80e175b9ec769c0","--out-dir","/home/xanewok/repos/rls/rls-analysis/target/debug/deps","-L","dependency=/home/xanewok/repos/rls/rls-analysis/target/debug/deps","--cap-lints","allow","-Zsave-analysis"],"output":"/home/xanewok/repos/rls/rls-analysis/target/debug/deps/libcfg_if-e80e175b9ec769c0.rlib"},"prelude":{"crate_id":{"name":"cfg_if","disambiguator":[7025270825250565032,5946918761383340377]},"crate_root":"/home/xanewok/.cargo/registry/src/github.com-1ecc6299db9ec823/cfg-if-0.1.7/src","external_crates":[{"file_name":"/home/xanewok/.cargo/registry/src/github.com-1ecc6299db9ec823/cfg-if-0.1.7/src/lib.rs","num":1,"id":{"name":"core","disambiguator":[824896561043773286,9999613319747983107]}},{"file_name":"/home/xanewok/.cargo/registry/src/github.com-1ecc6299db9ec823/cfg-if-0.1.7/src/lib.rs","num":2,"id":{"name":"compiler_builtins","disambiguator":[12915625401948968286,5836208655484837655]}},{"file_name":"/home/xanewok/.cargo/registry/src/github.com-1ecc6299db9ec823/cfg-if-0.1.7/src/lib.rs","num":3,"id":{"name":"rustc_std_workspace_core","disambiguator":[12313834146842590529,3636109452838087496]}}],"span":{"file_name":"/home/xanewok/.cargo/registry/src/github.com-1ecc6299db9ec823/cfg-if-0.1.7/src/lib.rs","byte_start":0,"byte_end":3989,"line_start":1,"line_end":144,"column_start":1,"column_end":2}},"imports":[],"defs":[{"kind":"Mod","id":{"krate":0,"index":0},"span":{"file_name":"/home/xanewok/.cargo/registry/src/github.com-1ecc6299db9ec823/cfg-if-0.1.7/src/lib.rs","byte_start":0,"byte_end":3989,"line_start":1,"line_end":144,"column_start":1,"column_end":2},"name":"","qualname":"::","value":"/home/xanewok/.cargo/registry/src/github.com-1ecc6299db9ec823/cfg-if-0.1.7/src/lib.rs","parent":null,"children":[{"krate":0,"index":2},{"krate":0,"index":4},{"krate":0,"index":6},{"krate":0,"index":8}],"decl_id":null,"docs":" A macro for defining `#[cfg]` if-else statements.","sig":null,"attributes":[{"value":"no_std","span":{"file_name":"/home/xanewok/.cargo/registry/src/github.com-1ecc6299db9ec823/cfg-if-0.1.7/src/lib.rs","byte_start":824,"byte_end":834,"line_start":29,"line_end":29,"column_start":1,"column_end":11}},{"value":"deny(missing_docs)","span":{"file_name":"/home/xanewok/.cargo/registry/src/github.com-1ecc6299db9ec823/cfg-if-0.1.7/src/lib.rs","byte_start":886,"byte_end":908,"line_start":32,"line_end":32,"column_start":1,"column_end":23}}]}],"impls":[],"refs":[],"macro_refs":[],"relations":[]} -------------------------------------------------------------------------------- /rls-analysis/test_data/rust-analysis/librustc_asan-78879868ade8efee.json: -------------------------------------------------------------------------------- 1 | {"config":{"output_file":null,"full_docs":false,"pub_only":true,"reachable_only":false,"distro_crate":true,"signatures":false,"borrow_data":false},"version":"0.19.0","compilation":{"directory":"/home/xanewok/repos/rust","program":"/home/xanewok/repos/rust/build/x86_64-unknown-linux-gnu/stage1/bin/rustc","arguments":["--edition=2018","--crate-name","rustc_asan","src/librustc_asan/lib.rs","--color","always","--crate-type","lib","--emit=dep-info,link","-C","opt-level=2","-C","metadata=78879868ade8efee-rustc","-C","extra-filename=-78879868ade8efee","--out-dir","/home/xanewok/repos/rust/build/x86_64-unknown-linux-gnu/stage1-std/x86_64-unknown-linux-gnu/release/deps","--target","x86_64-unknown-linux-gnu","-L","dependency=/home/xanewok/repos/rust/build/x86_64-unknown-linux-gnu/stage1-std/x86_64-unknown-linux-gnu/release/deps","-L","dependency=/home/xanewok/repos/rust/build/x86_64-unknown-linux-gnu/stage1-std/release/deps","--extern","alloc=/home/xanewok/repos/rust/build/x86_64-unknown-linux-gnu/stage1-std/x86_64-unknown-linux-gnu/release/deps/liballoc-dd00ad303ae24b18.rlib","--extern","compiler_builtins=/home/xanewok/repos/rust/build/x86_64-unknown-linux-gnu/stage1-std/x86_64-unknown-linux-gnu/release/deps/libcompiler_builtins-8aed34fb6416e6f8.rlib","--extern","core=/home/xanewok/repos/rust/build/x86_64-unknown-linux-gnu/stage1-std/x86_64-unknown-linux-gnu/release/deps/libcore-a5db6a3445116c08.rlib","-L","native=/home/xanewok/repos/rust/build/x86_64-unknown-linux-gnu/stage1-std/x86_64-unknown-linux-gnu/release/build/compiler_builtins-3afcb1fbb7509ea8/out","--cfg","stage1","--sysroot","/home/xanewok/repos/rust/build/x86_64-unknown-linux-gnu/stage1","-Zexternal-macro-backtrace","-Cprefer-dynamic","-C","debug-assertions=n","-Zsave-analysis","-C","link-args=-Wl,-rpath,$ORIGIN/../lib","-Zunstable-options","-Z","force-unstable-if-unmarked","-Dwarnings","-Dbare_trait_objects"],"output":"/home/xanewok/repos/rust/build/x86_64-unknown-linux-gnu/stage1-std/x86_64-unknown-linux-gnu/release/deps/librustc_asan-78879868ade8efee.rlib"},"prelude":{"crate_id":{"name":"rustc_asan","disambiguator":[13778923913746699946,7146402557799343130]},"crate_root":"src/librustc_asan","external_crates":[{"file_name":"/home/xanewok/repos/rust/src/librustc_asan/lib.rs","num":1,"id":{"name":"core","disambiguator":[824896561043773286,9999613319747983107]}},{"file_name":"/home/xanewok/repos/rust/src/librustc_asan/lib.rs","num":2,"id":{"name":"compiler_builtins","disambiguator":[12915625401948968286,5836208655484837655]}},{"file_name":"/home/xanewok/repos/rust/src/librustc_asan/lib.rs","num":3,"id":{"name":"rustc_std_workspace_core","disambiguator":[12313834146842590529,3636109452838087496]}}],"span":{"file_name":"src/librustc_asan/lib.rs","byte_start":0,"byte_end":274,"line_start":1,"line_end":10,"column_start":1,"column_end":27}},"imports":[],"defs":[{"kind":"Mod","id":{"krate":0,"index":0},"span":{"file_name":"src/librustc_asan/lib.rs","byte_start":0,"byte_end":274,"line_start":1,"line_end":10,"column_start":1,"column_end":27},"name":"","qualname":"::","value":"src/librustc_asan/lib.rs","parent":null,"children":[{"krate":0,"index":2},{"krate":0,"index":4},{"krate":0,"index":6}],"decl_id":null,"docs":"","sig":null,"attributes":[{"value":"sanitizer_runtime","span":{"file_name":"src/librustc_asan/lib.rs","byte_start":0,"byte_end":21,"line_start":1,"line_end":1,"column_start":1,"column_end":22}},{"value":"feature(nll)","span":{"file_name":"src/librustc_asan/lib.rs","byte_start":22,"byte_end":38,"line_start":2,"line_end":2,"column_start":1,"column_end":17}},{"value":"feature(sanitizer_runtime)","span":{"file_name":"src/librustc_asan/lib.rs","byte_start":39,"byte_end":69,"line_start":3,"line_end":3,"column_start":1,"column_end":31}},{"value":"feature(staged_api)","span":{"file_name":"src/librustc_asan/lib.rs","byte_start":70,"byte_end":93,"line_start":4,"line_end":4,"column_start":1,"column_end":24}},{"value":"no_std","span":{"file_name":"src/librustc_asan/lib.rs","byte_start":94,"byte_end":104,"line_start":5,"line_end":5,"column_start":1,"column_end":11}},{"value":"unstable(feature = \"sanitizer_runtime_lib\",\n reason = \"internal implementation detail of sanitizers\",\n issue = \"0\")","span":{"file_name":"src/librustc_asan/lib.rs","byte_start":105,"byte_end":246,"line_start":6,"line_end":8,"column_start":1,"column_end":26}},{"value":"deny(rust_2018_idioms)","span":{"file_name":"src/librustc_asan/lib.rs","byte_start":248,"byte_end":274,"line_start":10,"line_end":10,"column_start":1,"column_end":27}}]}],"impls":[],"refs":[],"macro_refs":[],"relations":[]} -------------------------------------------------------------------------------- /rls-analysis/test_data/rust-analysis/librustc_lsan-5fda8638db6a6948.json: -------------------------------------------------------------------------------- 1 | {"config":{"output_file":null,"full_docs":false,"pub_only":true,"reachable_only":false,"distro_crate":true,"signatures":false,"borrow_data":false},"version":"0.19.0","compilation":{"directory":"/home/xanewok/repos/rust","program":"/home/xanewok/repos/rust/build/x86_64-unknown-linux-gnu/stage1/bin/rustc","arguments":["--edition=2018","--crate-name","rustc_lsan","src/librustc_lsan/lib.rs","--color","always","--crate-type","lib","--emit=dep-info,link","-C","opt-level=2","-C","metadata=5fda8638db6a6948-rustc","-C","extra-filename=-5fda8638db6a6948","--out-dir","/home/xanewok/repos/rust/build/x86_64-unknown-linux-gnu/stage1-std/x86_64-unknown-linux-gnu/release/deps","--target","x86_64-unknown-linux-gnu","-L","dependency=/home/xanewok/repos/rust/build/x86_64-unknown-linux-gnu/stage1-std/x86_64-unknown-linux-gnu/release/deps","-L","dependency=/home/xanewok/repos/rust/build/x86_64-unknown-linux-gnu/stage1-std/release/deps","--extern","alloc=/home/xanewok/repos/rust/build/x86_64-unknown-linux-gnu/stage1-std/x86_64-unknown-linux-gnu/release/deps/liballoc-dd00ad303ae24b18.rlib","--extern","compiler_builtins=/home/xanewok/repos/rust/build/x86_64-unknown-linux-gnu/stage1-std/x86_64-unknown-linux-gnu/release/deps/libcompiler_builtins-8aed34fb6416e6f8.rlib","--extern","core=/home/xanewok/repos/rust/build/x86_64-unknown-linux-gnu/stage1-std/x86_64-unknown-linux-gnu/release/deps/libcore-a5db6a3445116c08.rlib","-L","native=/home/xanewok/repos/rust/build/x86_64-unknown-linux-gnu/stage1-std/x86_64-unknown-linux-gnu/release/build/compiler_builtins-3afcb1fbb7509ea8/out","--cfg","stage1","--sysroot","/home/xanewok/repos/rust/build/x86_64-unknown-linux-gnu/stage1","-Zexternal-macro-backtrace","-Cprefer-dynamic","-C","debug-assertions=n","-Zsave-analysis","-C","link-args=-Wl,-rpath,$ORIGIN/../lib","-Zunstable-options","-Z","force-unstable-if-unmarked","-Dwarnings","-Dbare_trait_objects"],"output":"/home/xanewok/repos/rust/build/x86_64-unknown-linux-gnu/stage1-std/x86_64-unknown-linux-gnu/release/deps/librustc_lsan-5fda8638db6a6948.rlib"},"prelude":{"crate_id":{"name":"rustc_lsan","disambiguator":[16637470637097307769,3749245714323909860]},"crate_root":"src/librustc_lsan","external_crates":[{"file_name":"/home/xanewok/repos/rust/src/librustc_lsan/lib.rs","num":1,"id":{"name":"core","disambiguator":[824896561043773286,9999613319747983107]}},{"file_name":"/home/xanewok/repos/rust/src/librustc_lsan/lib.rs","num":2,"id":{"name":"compiler_builtins","disambiguator":[12915625401948968286,5836208655484837655]}},{"file_name":"/home/xanewok/repos/rust/src/librustc_lsan/lib.rs","num":3,"id":{"name":"rustc_std_workspace_core","disambiguator":[12313834146842590529,3636109452838087496]}}],"span":{"file_name":"src/librustc_lsan/lib.rs","byte_start":0,"byte_end":274,"line_start":1,"line_end":10,"column_start":1,"column_end":27}},"imports":[],"defs":[{"kind":"Mod","id":{"krate":0,"index":0},"span":{"file_name":"src/librustc_lsan/lib.rs","byte_start":0,"byte_end":274,"line_start":1,"line_end":10,"column_start":1,"column_end":27},"name":"","qualname":"::","value":"src/librustc_lsan/lib.rs","parent":null,"children":[{"krate":0,"index":2},{"krate":0,"index":4},{"krate":0,"index":6}],"decl_id":null,"docs":"","sig":null,"attributes":[{"value":"sanitizer_runtime","span":{"file_name":"src/librustc_lsan/lib.rs","byte_start":0,"byte_end":21,"line_start":1,"line_end":1,"column_start":1,"column_end":22}},{"value":"feature(nll)","span":{"file_name":"src/librustc_lsan/lib.rs","byte_start":22,"byte_end":38,"line_start":2,"line_end":2,"column_start":1,"column_end":17}},{"value":"feature(sanitizer_runtime)","span":{"file_name":"src/librustc_lsan/lib.rs","byte_start":39,"byte_end":69,"line_start":3,"line_end":3,"column_start":1,"column_end":31}},{"value":"feature(staged_api)","span":{"file_name":"src/librustc_lsan/lib.rs","byte_start":70,"byte_end":93,"line_start":4,"line_end":4,"column_start":1,"column_end":24}},{"value":"no_std","span":{"file_name":"src/librustc_lsan/lib.rs","byte_start":94,"byte_end":104,"line_start":5,"line_end":5,"column_start":1,"column_end":11}},{"value":"unstable(feature = \"sanitizer_runtime_lib\",\n reason = \"internal implementation detail of sanitizers\",\n issue = \"0\")","span":{"file_name":"src/librustc_lsan/lib.rs","byte_start":105,"byte_end":246,"line_start":6,"line_end":8,"column_start":1,"column_end":26}},{"value":"deny(rust_2018_idioms)","span":{"file_name":"src/librustc_lsan/lib.rs","byte_start":248,"byte_end":274,"line_start":10,"line_end":10,"column_start":1,"column_end":27}}]}],"impls":[],"refs":[],"macro_refs":[],"relations":[]} -------------------------------------------------------------------------------- /rls-analysis/test_data/rust-analysis/librustc_msan-8492c3e570f2bd15.json: -------------------------------------------------------------------------------- 1 | {"config":{"output_file":null,"full_docs":false,"pub_only":true,"reachable_only":false,"distro_crate":true,"signatures":false,"borrow_data":false},"version":"0.19.0","compilation":{"directory":"/home/xanewok/repos/rust","program":"/home/xanewok/repos/rust/build/x86_64-unknown-linux-gnu/stage1/bin/rustc","arguments":["--edition=2018","--crate-name","rustc_msan","src/librustc_msan/lib.rs","--color","always","--crate-type","lib","--emit=dep-info,link","-C","opt-level=2","-C","metadata=8492c3e570f2bd15-rustc","-C","extra-filename=-8492c3e570f2bd15","--out-dir","/home/xanewok/repos/rust/build/x86_64-unknown-linux-gnu/stage1-std/x86_64-unknown-linux-gnu/release/deps","--target","x86_64-unknown-linux-gnu","-L","dependency=/home/xanewok/repos/rust/build/x86_64-unknown-linux-gnu/stage1-std/x86_64-unknown-linux-gnu/release/deps","-L","dependency=/home/xanewok/repos/rust/build/x86_64-unknown-linux-gnu/stage1-std/release/deps","--extern","alloc=/home/xanewok/repos/rust/build/x86_64-unknown-linux-gnu/stage1-std/x86_64-unknown-linux-gnu/release/deps/liballoc-dd00ad303ae24b18.rlib","--extern","compiler_builtins=/home/xanewok/repos/rust/build/x86_64-unknown-linux-gnu/stage1-std/x86_64-unknown-linux-gnu/release/deps/libcompiler_builtins-8aed34fb6416e6f8.rlib","--extern","core=/home/xanewok/repos/rust/build/x86_64-unknown-linux-gnu/stage1-std/x86_64-unknown-linux-gnu/release/deps/libcore-a5db6a3445116c08.rlib","-L","native=/home/xanewok/repos/rust/build/x86_64-unknown-linux-gnu/stage1-std/x86_64-unknown-linux-gnu/release/build/compiler_builtins-3afcb1fbb7509ea8/out","--cfg","stage1","--sysroot","/home/xanewok/repos/rust/build/x86_64-unknown-linux-gnu/stage1","-Zexternal-macro-backtrace","-Cprefer-dynamic","-C","debug-assertions=n","-Zsave-analysis","-C","link-args=-Wl,-rpath,$ORIGIN/../lib","-Zunstable-options","-Z","force-unstable-if-unmarked","-Dwarnings","-Dbare_trait_objects"],"output":"/home/xanewok/repos/rust/build/x86_64-unknown-linux-gnu/stage1-std/x86_64-unknown-linux-gnu/release/deps/librustc_msan-8492c3e570f2bd15.rlib"},"prelude":{"crate_id":{"name":"rustc_msan","disambiguator":[10283067350897423787,5784498176617589605]},"crate_root":"src/librustc_msan","external_crates":[{"file_name":"/home/xanewok/repos/rust/src/librustc_msan/lib.rs","num":1,"id":{"name":"core","disambiguator":[824896561043773286,9999613319747983107]}},{"file_name":"/home/xanewok/repos/rust/src/librustc_msan/lib.rs","num":2,"id":{"name":"compiler_builtins","disambiguator":[12915625401948968286,5836208655484837655]}},{"file_name":"/home/xanewok/repos/rust/src/librustc_msan/lib.rs","num":3,"id":{"name":"rustc_std_workspace_core","disambiguator":[12313834146842590529,3636109452838087496]}}],"span":{"file_name":"src/librustc_msan/lib.rs","byte_start":0,"byte_end":274,"line_start":1,"line_end":10,"column_start":1,"column_end":27}},"imports":[],"defs":[{"kind":"Mod","id":{"krate":0,"index":0},"span":{"file_name":"src/librustc_msan/lib.rs","byte_start":0,"byte_end":274,"line_start":1,"line_end":10,"column_start":1,"column_end":27},"name":"","qualname":"::","value":"src/librustc_msan/lib.rs","parent":null,"children":[{"krate":0,"index":2},{"krate":0,"index":4},{"krate":0,"index":6}],"decl_id":null,"docs":"","sig":null,"attributes":[{"value":"sanitizer_runtime","span":{"file_name":"src/librustc_msan/lib.rs","byte_start":0,"byte_end":21,"line_start":1,"line_end":1,"column_start":1,"column_end":22}},{"value":"feature(nll)","span":{"file_name":"src/librustc_msan/lib.rs","byte_start":22,"byte_end":38,"line_start":2,"line_end":2,"column_start":1,"column_end":17}},{"value":"feature(sanitizer_runtime)","span":{"file_name":"src/librustc_msan/lib.rs","byte_start":39,"byte_end":69,"line_start":3,"line_end":3,"column_start":1,"column_end":31}},{"value":"feature(staged_api)","span":{"file_name":"src/librustc_msan/lib.rs","byte_start":70,"byte_end":93,"line_start":4,"line_end":4,"column_start":1,"column_end":24}},{"value":"no_std","span":{"file_name":"src/librustc_msan/lib.rs","byte_start":94,"byte_end":104,"line_start":5,"line_end":5,"column_start":1,"column_end":11}},{"value":"unstable(feature = \"sanitizer_runtime_lib\",\n reason = \"internal implementation detail of sanitizers\",\n issue = \"0\")","span":{"file_name":"src/librustc_msan/lib.rs","byte_start":105,"byte_end":246,"line_start":6,"line_end":8,"column_start":1,"column_end":26}},{"value":"deny(rust_2018_idioms)","span":{"file_name":"src/librustc_msan/lib.rs","byte_start":248,"byte_end":274,"line_start":10,"line_end":10,"column_start":1,"column_end":27}}]}],"impls":[],"refs":[],"macro_refs":[],"relations":[]} -------------------------------------------------------------------------------- /rls-analysis/test_data/rust-analysis/librustc_std_workspace_core-a48dbd3d0edd9076.json: -------------------------------------------------------------------------------- 1 | {"config":{"output_file":null,"full_docs":false,"pub_only":true,"reachable_only":false,"distro_crate":true,"signatures":false,"borrow_data":false},"version":"0.19.0","compilation":{"directory":"/home/xanewok/repos/rust","program":"/home/xanewok/repos/rust/build/x86_64-unknown-linux-gnu/stage1/bin/rustc","arguments":["--edition=2018","--crate-name","rustc_std_workspace_core","src/tools/rustc-std-workspace-core/lib.rs","--color","always","--crate-type","lib","--emit=dep-info,link","-C","opt-level=2","-C","metadata=a48dbd3d0edd9076-rustc","-C","extra-filename=-a48dbd3d0edd9076","--out-dir","/home/xanewok/repos/rust/build/x86_64-unknown-linux-gnu/stage1-std/x86_64-unknown-linux-gnu/release/deps","--target","x86_64-unknown-linux-gnu","-L","dependency=/home/xanewok/repos/rust/build/x86_64-unknown-linux-gnu/stage1-std/x86_64-unknown-linux-gnu/release/deps","-L","dependency=/home/xanewok/repos/rust/build/x86_64-unknown-linux-gnu/stage1-std/release/deps","--extern","core=/home/xanewok/repos/rust/build/x86_64-unknown-linux-gnu/stage1-std/x86_64-unknown-linux-gnu/release/deps/libcore-a5db6a3445116c08.rlib","--cfg","stage1","--sysroot","/home/xanewok/repos/rust/build/x86_64-unknown-linux-gnu/stage1","-Zexternal-macro-backtrace","-Cprefer-dynamic","-C","debug-assertions=n","-Zsave-analysis","-C","link-args=-Wl,-rpath,$ORIGIN/../lib","-Zunstable-options","-Z","force-unstable-if-unmarked","-Dwarnings","-Dbare_trait_objects"],"output":"/home/xanewok/repos/rust/build/x86_64-unknown-linux-gnu/stage1-std/x86_64-unknown-linux-gnu/release/deps/librustc_std_workspace_core-a48dbd3d0edd9076.rlib"},"prelude":{"crate_id":{"name":"rustc_std_workspace_core","disambiguator":[12313834146842590529,3636109452838087496]},"crate_root":"src/tools/rustc-std-workspace-core","external_crates":[{"file_name":"/home/xanewok/repos/rust/src/tools/rustc-std-workspace-core/lib.rs","num":1,"id":{"name":"core","disambiguator":[824896561043773286,9999613319747983107]}}],"span":{"file_name":"src/tools/rustc-std-workspace-core/lib.rs","byte_start":0,"byte_end":77,"line_start":1,"line_end":5,"column_start":1,"column_end":17}},"imports":[{"kind":"GlobUse","ref_id":null,"span":{"file_name":"src/tools/rustc-std-workspace-core/lib.rs","byte_start":75,"byte_end":76,"line_start":5,"line_end":5,"column_start":15,"column_end":16},"alias_span":null,"name":"*","value":"","parent":{"krate":0,"index":0}}],"defs":[{"kind":"Mod","id":{"krate":0,"index":0},"span":{"file_name":"src/tools/rustc-std-workspace-core/lib.rs","byte_start":0,"byte_end":77,"line_start":1,"line_end":5,"column_start":1,"column_end":17},"name":"","qualname":"::","value":"src/tools/rustc-std-workspace-core/lib.rs","parent":null,"children":[{"krate":0,"index":2}],"decl_id":null,"docs":"","sig":null,"attributes":[{"value":"feature(no_core)","span":{"file_name":"src/tools/rustc-std-workspace-core/lib.rs","byte_start":0,"byte_end":20,"line_start":1,"line_end":1,"column_start":1,"column_end":21}},{"value":"no_core","span":{"file_name":"src/tools/rustc-std-workspace-core/lib.rs","byte_start":21,"byte_end":32,"line_start":2,"line_end":2,"column_start":1,"column_end":12}},{"value":"deny(rust_2018_idioms)","span":{"file_name":"src/tools/rustc-std-workspace-core/lib.rs","byte_start":33,"byte_end":59,"line_start":3,"line_end":3,"column_start":1,"column_end":27}}]}],"impls":[],"refs":[],"macro_refs":[],"relations":[]} -------------------------------------------------------------------------------- /rls-analysis/test_data/rust-analysis/librustc_tsan-859a51be98ad349f.json: -------------------------------------------------------------------------------- 1 | {"config":{"output_file":null,"full_docs":false,"pub_only":true,"reachable_only":false,"distro_crate":true,"signatures":false,"borrow_data":false},"version":"0.19.0","compilation":{"directory":"/home/xanewok/repos/rust","program":"/home/xanewok/repos/rust/build/x86_64-unknown-linux-gnu/stage1/bin/rustc","arguments":["--edition=2018","--crate-name","rustc_tsan","src/librustc_tsan/lib.rs","--color","always","--crate-type","lib","--emit=dep-info,link","-C","opt-level=2","-C","metadata=859a51be98ad349f-rustc","-C","extra-filename=-859a51be98ad349f","--out-dir","/home/xanewok/repos/rust/build/x86_64-unknown-linux-gnu/stage1-std/x86_64-unknown-linux-gnu/release/deps","--target","x86_64-unknown-linux-gnu","-L","dependency=/home/xanewok/repos/rust/build/x86_64-unknown-linux-gnu/stage1-std/x86_64-unknown-linux-gnu/release/deps","-L","dependency=/home/xanewok/repos/rust/build/x86_64-unknown-linux-gnu/stage1-std/release/deps","--extern","alloc=/home/xanewok/repos/rust/build/x86_64-unknown-linux-gnu/stage1-std/x86_64-unknown-linux-gnu/release/deps/liballoc-dd00ad303ae24b18.rlib","--extern","compiler_builtins=/home/xanewok/repos/rust/build/x86_64-unknown-linux-gnu/stage1-std/x86_64-unknown-linux-gnu/release/deps/libcompiler_builtins-8aed34fb6416e6f8.rlib","--extern","core=/home/xanewok/repos/rust/build/x86_64-unknown-linux-gnu/stage1-std/x86_64-unknown-linux-gnu/release/deps/libcore-a5db6a3445116c08.rlib","-L","native=/home/xanewok/repos/rust/build/x86_64-unknown-linux-gnu/stage1-std/x86_64-unknown-linux-gnu/release/build/compiler_builtins-3afcb1fbb7509ea8/out","--cfg","stage1","--sysroot","/home/xanewok/repos/rust/build/x86_64-unknown-linux-gnu/stage1","-Zexternal-macro-backtrace","-Cprefer-dynamic","-C","debug-assertions=n","-Zsave-analysis","-C","link-args=-Wl,-rpath,$ORIGIN/../lib","-Zunstable-options","-Z","force-unstable-if-unmarked","-Dwarnings","-Dbare_trait_objects"],"output":"/home/xanewok/repos/rust/build/x86_64-unknown-linux-gnu/stage1-std/x86_64-unknown-linux-gnu/release/deps/librustc_tsan-859a51be98ad349f.rlib"},"prelude":{"crate_id":{"name":"rustc_tsan","disambiguator":[13484419767617518402,11135388578896074560]},"crate_root":"src/librustc_tsan","external_crates":[{"file_name":"/home/xanewok/repos/rust/src/librustc_tsan/lib.rs","num":1,"id":{"name":"core","disambiguator":[824896561043773286,9999613319747983107]}},{"file_name":"/home/xanewok/repos/rust/src/librustc_tsan/lib.rs","num":2,"id":{"name":"compiler_builtins","disambiguator":[12915625401948968286,5836208655484837655]}},{"file_name":"/home/xanewok/repos/rust/src/librustc_tsan/lib.rs","num":3,"id":{"name":"rustc_std_workspace_core","disambiguator":[12313834146842590529,3636109452838087496]}}],"span":{"file_name":"src/librustc_tsan/lib.rs","byte_start":0,"byte_end":274,"line_start":1,"line_end":10,"column_start":1,"column_end":27}},"imports":[],"defs":[{"kind":"Mod","id":{"krate":0,"index":0},"span":{"file_name":"src/librustc_tsan/lib.rs","byte_start":0,"byte_end":274,"line_start":1,"line_end":10,"column_start":1,"column_end":27},"name":"","qualname":"::","value":"src/librustc_tsan/lib.rs","parent":null,"children":[{"krate":0,"index":2},{"krate":0,"index":4},{"krate":0,"index":6}],"decl_id":null,"docs":"","sig":null,"attributes":[{"value":"sanitizer_runtime","span":{"file_name":"src/librustc_tsan/lib.rs","byte_start":0,"byte_end":21,"line_start":1,"line_end":1,"column_start":1,"column_end":22}},{"value":"feature(nll)","span":{"file_name":"src/librustc_tsan/lib.rs","byte_start":22,"byte_end":38,"line_start":2,"line_end":2,"column_start":1,"column_end":17}},{"value":"feature(sanitizer_runtime)","span":{"file_name":"src/librustc_tsan/lib.rs","byte_start":39,"byte_end":69,"line_start":3,"line_end":3,"column_start":1,"column_end":31}},{"value":"feature(staged_api)","span":{"file_name":"src/librustc_tsan/lib.rs","byte_start":70,"byte_end":93,"line_start":4,"line_end":4,"column_start":1,"column_end":24}},{"value":"no_std","span":{"file_name":"src/librustc_tsan/lib.rs","byte_start":94,"byte_end":104,"line_start":5,"line_end":5,"column_start":1,"column_end":11}},{"value":"unstable(feature = \"sanitizer_runtime_lib\",\n reason = \"internal implementation detail of sanitizers\",\n issue = \"0\")","span":{"file_name":"src/librustc_tsan/lib.rs","byte_start":105,"byte_end":246,"line_start":6,"line_end":8,"column_start":1,"column_end":26}},{"value":"deny(rust_2018_idioms)","span":{"file_name":"src/librustc_tsan/lib.rs","byte_start":248,"byte_end":274,"line_start":10,"line_end":10,"column_start":1,"column_end":27}}]}],"impls":[],"refs":[],"macro_refs":[],"relations":[]} -------------------------------------------------------------------------------- /rls-analysis/test_data/types/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | [[package]] 4 | name = "types" 5 | version = "0.1.0" 6 | 7 | -------------------------------------------------------------------------------- /rls-analysis/test_data/types/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "types" 3 | version = "0.1.0" 4 | authors = ["Nick Cameron "] 5 | 6 | [dependencies] 7 | -------------------------------------------------------------------------------- /rls-analysis/test_data/types/src/main.rs: -------------------------------------------------------------------------------- 1 | struct Foo { 2 | f: u32, 3 | } 4 | 5 | fn main() { 6 | let x = Foo { f: 42 }; 7 | let _: Foo = x; 8 | } 9 | 10 | fn foo(x: Foo) -> Foo { 11 | let test_binding = true; 12 | const TEST_CONST: bool = true; 13 | static TEST_STATIC: u32 = 16; 14 | panic!(); 15 | } 16 | 17 | mod test_module { 18 | type TestType = u32; 19 | } 20 | 21 | union TestUnion { 22 | f1: u32 23 | } 24 | 25 | trait TestTrait { 26 | fn test_method(&self); 27 | } 28 | 29 | enum FooEnum { 30 | TupleVariant, 31 | StructVariant { x: u8 }, 32 | } 33 | -------------------------------------------------------------------------------- /rls-data/.gitignore: -------------------------------------------------------------------------------- 1 | target/ 2 | **/*.rs.bk 3 | 4 | Cargo.lock 5 | -------------------------------------------------------------------------------- /rls-data/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "rls-data" 3 | version = "0.19.1" 4 | edition = "2018" 5 | authors = ["Nick Cameron "] 6 | description = "Data structures used by the RLS and Rust compiler" 7 | license = "Apache-2.0/MIT" 8 | repository = "https://github.com/rust-lang/rls" 9 | categories = ["development-tools"] 10 | 11 | [dependencies] 12 | rls-span = "0.5.0" 13 | serde = "1.0" 14 | 15 | [features] 16 | default = ["derive"] 17 | derive = ["serde/derive", "rls-span/derive"] 18 | -------------------------------------------------------------------------------- /rls-data/README.md: -------------------------------------------------------------------------------- 1 | # RLS-data 2 | 3 | Data structures used by the RLS and the Rust compiler. 4 | 5 | These are used by the save-analysis functionality in the compiler 6 | (`rustc -Zsave-analysis`). In that use, the compiler translates info in its 7 | internal data structures to these data structures then serialises them as JSON. 8 | Clients (such as the RLS) can use this crate when deserialising. 9 | 10 | The data can also be passed directly from compiler to client if the compiler is 11 | used as a library. 12 | -------------------------------------------------------------------------------- /rls-data/src/config.rs: -------------------------------------------------------------------------------- 1 | #[cfg(feature = "derive")] 2 | use serde::{Deserialize, Serialize}; 3 | 4 | /// Used to configure save-analysis. 5 | #[derive(Debug, Clone, Default)] 6 | #[cfg_attr(feature = "derive", derive(Serialize, Deserialize))] 7 | pub struct Config { 8 | /// File to output save-analysis data to. 9 | pub output_file: Option, 10 | /// Include all documentation for items. (If `false`, only includes the 11 | /// summary (first paragraph) for each item). 12 | pub full_docs: bool, 13 | /// If true only includes data for public items in a crate (useful for 14 | /// library crates). 15 | pub pub_only: bool, 16 | /// If true only includes data for items reachable from the crate root. 17 | pub reachable_only: bool, 18 | /// True if and only if the analysed crate is part of the standard Rust distro. 19 | pub distro_crate: bool, 20 | /// Include signature information. 21 | pub signatures: bool, 22 | /// Include experimental borrow data. 23 | pub borrow_data: bool, 24 | } 25 | -------------------------------------------------------------------------------- /rls-ipc/.gitignore: -------------------------------------------------------------------------------- 1 | /target/ 2 | **/*.rs.bk 3 | Cargo.lock 4 | -------------------------------------------------------------------------------- /rls-ipc/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "rls-ipc" 3 | version = "0.1.0" 4 | authors = ["Igor Matuszewski "] 5 | edition = "2018" 6 | description = "Inter-process communication (IPC) layer between RLS and rustc" 7 | license = "Apache-2.0/MIT" 8 | repository = "https://github.com/rust-lang/rls" 9 | categories = ["development-tools"] 10 | 11 | [dependencies] 12 | jsonrpc-core = "18" 13 | jsonrpc-core-client = "18" 14 | jsonrpc-derive = "18" 15 | jsonrpc-ipc-server = { version = "18", optional = true } 16 | rls-data = "0.19" 17 | serde = { version = "1.0", features = ["derive"] } 18 | 19 | [features] 20 | client = ["jsonrpc-core-client/ipc"] 21 | server = ["jsonrpc-ipc-server"] 22 | -------------------------------------------------------------------------------- /rls-ipc/src/client.rs: -------------------------------------------------------------------------------- 1 | //! Allows to connect to an IPC server. 2 | 3 | use crate::rpc::callbacks::gen_client::Client as CallbacksClient; 4 | use crate::rpc::file_loader::gen_client::Client as FileLoaderClient; 5 | 6 | pub use jsonrpc_core_client::transports::ipc::connect; 7 | pub use jsonrpc_core_client::{RpcChannel, RpcError}; 8 | 9 | /// Joint IPC client. 10 | #[derive(Clone)] 11 | pub struct Client { 12 | /// File loader interface 13 | pub file_loader: FileLoaderClient, 14 | /// Callbacks interface 15 | pub callbacks: CallbacksClient, 16 | } 17 | 18 | impl From for Client { 19 | fn from(channel: RpcChannel) -> Self { 20 | Client { 21 | file_loader: FileLoaderClient::from(channel.clone()), 22 | callbacks: CallbacksClient::from(channel), 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /rls-ipc/src/lib.rs: -------------------------------------------------------------------------------- 1 | //! Inter-process communication (IPC) layer between RLS and rustc. 2 | 3 | #![deny(missing_docs)] 4 | 5 | #[cfg(feature = "client")] 6 | pub mod client; 7 | pub mod rpc; 8 | #[cfg(feature = "server")] 9 | pub mod server; 10 | -------------------------------------------------------------------------------- /rls-ipc/src/rpc.rs: -------------------------------------------------------------------------------- 1 | //! Available remote procedure call (RPC) interfaces. 2 | 3 | use std::collections::{HashMap, HashSet}; 4 | use std::path::PathBuf; 5 | 6 | use jsonrpc_derive::rpc; 7 | use serde::{Deserialize, Serialize}; 8 | 9 | pub use jsonrpc_core::{Error, Result}; 10 | 11 | // Separated because #[rpc] macro generated a `gen_client` mod and so two 12 | // interfaces cannot be derived in the same scope due to a generated name clash 13 | /// RPC interface for an overriden file loader to be used inside `rustc`. 14 | pub mod file_loader { 15 | use super::*; 16 | // Expanded via #[rpc] 17 | pub use gen_client::Client; 18 | pub use rpc_impl_Rpc::gen_server::Rpc as Server; 19 | 20 | #[rpc] 21 | /// RPC interface for an overriden file loader to be used inside `rustc`. 22 | pub trait Rpc { 23 | /// Query the existence of a file. 24 | #[rpc(name = "file_exists")] 25 | fn file_exists(&self, path: PathBuf) -> Result; 26 | 27 | /// Read the contents of a UTF-8 file into memory. 28 | #[rpc(name = "read_file")] 29 | fn read_file(&self, path: PathBuf) -> Result; 30 | } 31 | } 32 | 33 | // Separated because #[rpc] macro generated a `gen_client` mod and so two 34 | // interfaces cannot be derived in the same scope due to a generated name clash 35 | /// RPC interface to feed back data from `rustc` instances. 36 | pub mod callbacks { 37 | use super::*; 38 | // Expanded via #[rpc] 39 | pub use gen_client::Client; 40 | pub use rpc_impl_Rpc::gen_server::Rpc as Server; 41 | 42 | #[rpc] 43 | /// RPC interface to feed back data from `rustc` instances. 44 | pub trait Rpc { 45 | /// Hands back computed analysis data for the compiled crate 46 | #[rpc(name = "complete_analysis")] 47 | fn complete_analysis(&self, analysis: rls_data::Analysis) -> Result<()>; 48 | 49 | /// Hands back computed input files for the compiled crate 50 | #[rpc(name = "input_files")] 51 | fn input_files(&self, input_files: HashMap>) -> Result<()>; 52 | } 53 | } 54 | 55 | /// Build system-agnostic, basic compilation unit 56 | #[derive(PartialEq, Eq, Hash, Debug, Clone, Deserialize, Serialize)] 57 | pub struct Crate { 58 | /// Crate name 59 | pub name: String, 60 | /// Optional path to a crate root 61 | pub src_path: Option, 62 | /// Edition in which a given crate is compiled 63 | pub edition: Edition, 64 | /// From rustc; mainly used to group other properties used to disambiguate a 65 | /// given compilation unit. 66 | pub disambiguator: (u64, u64), 67 | } 68 | 69 | /// Rust edition 70 | #[derive(PartialEq, Eq, Hash, Debug, PartialOrd, Ord, Copy, Clone, Deserialize, Serialize)] 71 | pub enum Edition { 72 | /// Rust 2015 73 | Edition2015, 74 | /// Rust 2018 75 | Edition2018, 76 | /// Rust 2021 77 | Edition2021, 78 | /// Rust 2024 79 | Edition2024, 80 | } 81 | -------------------------------------------------------------------------------- /rls-ipc/src/server.rs: -------------------------------------------------------------------------------- 1 | //! Includes facility functions to start an IPC server. 2 | 3 | pub use jsonrpc_ipc_server::{CloseHandle, ServerBuilder}; 4 | -------------------------------------------------------------------------------- /rls-rustc/.gitignore: -------------------------------------------------------------------------------- 1 | /target/ 2 | **/*.rs.bk 3 | Cargo.lock 4 | -------------------------------------------------------------------------------- /rls-rustc/COPYRIGHT: -------------------------------------------------------------------------------- 1 | Short version for non-lawyers: 2 | 3 | rls-rustc is dual-licensed under Apache 2.0 and MIT 4 | terms. 5 | 6 | 7 | Longer version: 8 | 9 | Licensed under the Apache License, Version 2.0 10 | or the MIT 12 | license , 13 | at your option. All files in the project carrying such 14 | notice may not be copied, modified, or distributed except 15 | according to those terms. 16 | -------------------------------------------------------------------------------- /rls-rustc/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "rls-rustc" 3 | version = "0.6.0" 4 | edition = "2018" 5 | authors = ["Nick Cameron "] 6 | description = "A simple shim around rustc to allow using save-analysis with a stable toolchain" 7 | license = "Apache-2.0/MIT" 8 | repository = "https://github.com/rust-lang/rls" 9 | categories = ["development-tools"] 10 | 11 | [dependencies] 12 | env_logger = "0.9" 13 | log = "0.4" 14 | rand = "0.8" 15 | clippy_lints = { git = "https://github.com/rust-lang/rust-clippy", version = "0.1.60", optional = true } 16 | tokio = { version = "1", optional = true } 17 | futures = { version = "0.3", optional = true } 18 | serde = { version = "1", features = ["derive"], optional = true } 19 | rls-data = { version = "0.19", optional = true } 20 | rls-ipc = { path = "../rls-ipc", optional = true } 21 | 22 | [features] 23 | clippy = ["clippy_lints"] 24 | ipc = ["tokio", "futures", "serde", "rls-data", "rls-ipc/client"] 25 | default = [] 26 | -------------------------------------------------------------------------------- /rls-rustc/LICENSE-MIT: -------------------------------------------------------------------------------- 1 | Copyright (c) 2016 The Rust Project Developers 2 | 3 | Permission is hereby granted, free of charge, to any 4 | person obtaining a copy of this software and associated 5 | documentation files (the "Software"), to deal in the 6 | Software without restriction, including without 7 | limitation the rights to use, copy, modify, merge, 8 | publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software 10 | is furnished to do so, subject to the following 11 | conditions: 12 | 13 | The above copyright notice and this permission notice 14 | shall be included in all copies or substantial portions 15 | of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF 18 | ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 19 | TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 20 | PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT 21 | SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 22 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 23 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR 24 | IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 25 | DEALINGS IN THE SOFTWARE. 26 | -------------------------------------------------------------------------------- /rls-rustc/README.md: -------------------------------------------------------------------------------- 1 | # rls-rustc 2 | 3 | A simple shim around rustc to allow using save-analysis with a stable toolchain 4 | 5 | ## Building and running 6 | 7 | `cargo build` or `cargo run` 8 | 9 | You probably want to use `--release` 10 | 11 | ## Support 12 | 13 | File an issue or ping nrc in #rust-dev-tools 14 | 15 | ## Implementation 16 | 17 | The compiler has an extensible driver interface. The main API is the `CompilerCalls` 18 | trait. A tool can emulate the compiler, but adjust operation by implementing 19 | that trait. This shim does exactly that, using nearly all the defaults, but 20 | setting some properties that are useful for tools. These are usually only 21 | available by using a nightly toolchain, but by using this shim, can be used on 22 | stable. 23 | 24 | In the future we might want to make the properties we set configurable. 25 | -------------------------------------------------------------------------------- /rls-rustc/src/bin/rustc.rs: -------------------------------------------------------------------------------- 1 | fn main() -> Result<(), ()> { 2 | rls_rustc::run() 3 | } 4 | -------------------------------------------------------------------------------- /rls-rustc/src/clippy.rs: -------------------------------------------------------------------------------- 1 | //! Copied from rls/src/config.rs 2 | 3 | use std::str::FromStr; 4 | 5 | #[derive(Debug, Clone, Copy, PartialEq)] 6 | pub enum ClippyPreference { 7 | /// Disable clippy. 8 | Off, 9 | /// Enable clippy, but `allow` clippy lints (i.e., require `warn` override). 10 | OptIn, 11 | /// Enable clippy. 12 | On, 13 | } 14 | 15 | pub fn preference() -> Option { 16 | std::env::var("RLS_CLIPPY_PREFERENCE").ok().and_then(|pref| FromStr::from_str(&pref).ok()) 17 | } 18 | 19 | /// Permissive deserialization for `ClippyPreference` 20 | /// "opt-in", "Optin" -> `ClippyPreference::OptIn` 21 | impl FromStr for ClippyPreference { 22 | type Err = (); 23 | fn from_str(s: &str) -> Result { 24 | match s.to_lowercase().as_str() { 25 | "off" => Ok(ClippyPreference::Off), 26 | "optin" | "opt-in" => Ok(ClippyPreference::OptIn), 27 | "on" => Ok(ClippyPreference::On), 28 | _ => Err(()), 29 | } 30 | } 31 | } 32 | 33 | pub fn adjust_args(args: Vec, preference: ClippyPreference) -> Vec { 34 | if preference != ClippyPreference::Off { 35 | // Allow feature gating in the same way as `cargo clippy` 36 | let mut clippy_args = vec!["--cfg".to_owned(), r#"feature="cargo-clippy""#.to_owned()]; 37 | 38 | if preference == ClippyPreference::OptIn { 39 | // `OptIn`: Require explicit `#![warn(clippy::all)]` annotation in each workspace crate 40 | clippy_args.push("-A".to_owned()); 41 | clippy_args.push("clippy::all".to_owned()); 42 | } 43 | 44 | args.iter().map(ToOwned::to_owned).chain(clippy_args).collect() 45 | } else { 46 | args.to_owned() 47 | } 48 | } 49 | 50 | #[cfg(feature = "clippy")] 51 | pub fn config(config: &mut rustc_interface::interface::Config) { 52 | let previous = config.register_lints.take(); 53 | config.register_lints = Some(Box::new(move |sess, mut lint_store| { 54 | // technically we're ~guaranteed that this is none but might as well call anything that 55 | // is there already. Certainly it can't hurt. 56 | if let Some(previous) = &previous { 57 | (previous)(sess, lint_store); 58 | } 59 | 60 | let conf = clippy_lints::read_conf(&sess); 61 | clippy_lints::register_plugins(&mut lint_store, &sess, &conf); 62 | clippy_lints::register_pre_expansion_lints(&mut lint_store, &sess, &conf); 63 | clippy_lints::register_renamed(&mut lint_store); 64 | })); 65 | } 66 | -------------------------------------------------------------------------------- /rls-rustc/src/ipc.rs: -------------------------------------------------------------------------------- 1 | use std::collections::{HashMap, HashSet}; 2 | use std::future::Future; 3 | use std::io; 4 | use std::path::{Path, PathBuf}; 5 | 6 | use rls_ipc::client::{Client as JointClient, RpcChannel, RpcError}; 7 | use rls_ipc::rpc::callbacks::Client as CallbacksClient; 8 | use rls_ipc::rpc::file_loader::Client as FileLoaderClient; 9 | 10 | pub use rls_ipc::client::connect; 11 | 12 | #[derive(Clone)] 13 | pub struct Client(JointClient); 14 | 15 | impl From for Client { 16 | fn from(channel: RpcChannel) -> Self { 17 | Client(channel.into()) 18 | } 19 | } 20 | 21 | #[derive(Clone)] 22 | pub struct IpcFileLoader(FileLoaderClient); 23 | 24 | impl IpcFileLoader { 25 | pub fn into_boxed(self) -> Option> { 26 | Some(Box::new(self)) 27 | } 28 | } 29 | 30 | impl rustc_span::source_map::FileLoader for IpcFileLoader { 31 | fn file_exists(&self, path: &Path) -> bool { 32 | futures::executor::block_on(self.0.file_exists(path.to_owned())).unwrap() 33 | } 34 | 35 | fn read_file(&self, path: &Path) -> io::Result { 36 | futures::executor::block_on(self.0.read_file(path.to_owned())) 37 | .map_err(|e| io::Error::new(io::ErrorKind::Other, format!("{}", e))) 38 | } 39 | } 40 | 41 | #[derive(Clone)] 42 | pub struct IpcCallbacks(CallbacksClient); 43 | 44 | impl IpcCallbacks { 45 | pub fn complete_analysis( 46 | &self, 47 | analysis: rls_data::Analysis, 48 | ) -> impl Future> { 49 | self.0.complete_analysis(analysis) 50 | } 51 | 52 | pub fn input_files( 53 | &self, 54 | input_files: HashMap>, 55 | ) -> impl Future> { 56 | self.0.input_files(input_files) 57 | } 58 | } 59 | 60 | impl Client { 61 | pub fn split(self) -> (IpcFileLoader, IpcCallbacks) { 62 | let JointClient { file_loader, callbacks } = self.0; 63 | (IpcFileLoader(file_loader), IpcCallbacks(callbacks)) 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /rls-span/.gitignore: -------------------------------------------------------------------------------- 1 | target 2 | Cargo.lock 3 | -------------------------------------------------------------------------------- /rls-span/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "rls-span" 3 | version = "0.5.4" 4 | edition = "2018" 5 | authors = ["Nick Cameron "] 6 | description = "Types for identifying code spans/ranges" 7 | license = "Apache-2.0/MIT" 8 | repository = "https://github.com/rust-lang/rls" 9 | categories = ["development-tools"] 10 | 11 | 12 | [dependencies] 13 | rustc-serialize = { version = "0.3.24", optional = true } 14 | serde = "1.0" 15 | 16 | [features] 17 | default = [] 18 | nightly = [] 19 | serialize-rustc = ["rustc-serialize"] 20 | derive = ["serde/derive"] 21 | -------------------------------------------------------------------------------- /rls-span/src/compiler.rs: -------------------------------------------------------------------------------- 1 | ///! These are the structures emitted by the compiler as part of JSON errors. 2 | ///! The original source can be found at 3 | ///! https://github.com/rust-lang/rust/blob/master/compiler/rustc_errors/src/json.rs 4 | use std::path::PathBuf; 5 | 6 | #[cfg(feature = "derive")] 7 | use serde::Deserialize; 8 | 9 | use crate::{Column, OneIndexed, Row, Span}; 10 | 11 | #[cfg_attr(feature = "derive", derive(Deserialize))] 12 | #[cfg_attr(feature = "serialize-rustc", derive(RustcDecodable))] 13 | #[derive(Debug, Clone)] 14 | pub struct DiagnosticSpan { 15 | pub file_name: String, 16 | pub byte_start: u32, 17 | pub byte_end: u32, 18 | /// 1-based. 19 | pub line_start: usize, 20 | pub line_end: usize, 21 | /// 1-based, character offset. 22 | pub column_start: usize, 23 | pub column_end: usize, 24 | /// Is this a "primary" span -- meaning the point, or one of the points, 25 | /// where the error occurred? 26 | pub is_primary: bool, 27 | /// Source text from the start of line_start to the end of line_end. 28 | pub text: Vec, 29 | /// Label that should be placed at this location (if any) 30 | pub label: Option, 31 | /// If we are suggesting a replacement, this will contain text 32 | /// that should be sliced in atop this span. You may prefer to 33 | /// load the fully rendered version from the parent `Diagnostic`, 34 | /// however. 35 | pub suggested_replacement: Option, 36 | /// Macro invocations that created the code at this span, if any. 37 | pub expansion: Option>, 38 | } 39 | 40 | impl DiagnosticSpan { 41 | pub fn rls_span(&self) -> Span { 42 | Span::new( 43 | Row::new(self.line_start as u32), 44 | Row::new(self.line_end as u32), 45 | Column::new(self.column_start as u32), 46 | Column::new(self.column_end as u32), 47 | PathBuf::from(&self.file_name), 48 | ) 49 | } 50 | } 51 | 52 | #[cfg_attr(feature = "derive", derive(Deserialize))] 53 | #[cfg_attr(feature = "serialize-rustc", derive(RustcDecodable))] 54 | #[derive(Debug, Clone)] 55 | pub struct DiagnosticSpanLine { 56 | pub text: String, 57 | 58 | /// 1-based, character offset in self.text. 59 | pub highlight_start: usize, 60 | 61 | pub highlight_end: usize, 62 | } 63 | 64 | #[cfg_attr(feature = "derive", derive(Deserialize))] 65 | #[cfg_attr(feature = "serialize-rustc", derive(RustcDecodable))] 66 | #[derive(Debug, Clone)] 67 | pub struct DiagnosticSpanMacroExpansion { 68 | /// span where macro was applied to generate this code; note that 69 | /// this may itself derive from a macro (if 70 | /// `span.expansion.is_some()`) 71 | pub span: DiagnosticSpan, 72 | 73 | /// name of macro that was applied (e.g., "foo!" or "#[derive(Eq)]") 74 | pub macro_decl_name: String, 75 | 76 | /// span where macro was defined (if known) 77 | pub def_site_span: Option, 78 | } 79 | -------------------------------------------------------------------------------- /rls-vfs/.gitignore: -------------------------------------------------------------------------------- 1 | target/ 2 | Cargo.lock 3 | -------------------------------------------------------------------------------- /rls-vfs/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "rls-vfs" 3 | version = "0.8.0" 4 | edition = "2018" 5 | authors = ["Nick Cameron "] 6 | description = "Virtual File System for the RLS" 7 | license = "Apache-2.0/MIT" 8 | repository = "https://github.com/rust-lang/rls" 9 | categories = ["development-tools"] 10 | 11 | [dependencies] 12 | rls-span = "0.5.1" 13 | log = "0.4.5" 14 | -------------------------------------------------------------------------------- /rls-vfs/benches/bench.rs: -------------------------------------------------------------------------------- 1 | //! benchmark which uses libstd/path.rs 2 | //! make sure rust-src installed before running this bench 3 | 4 | #![feature(test)] 5 | extern crate rls_span; 6 | extern crate rls_vfs; 7 | extern crate test; 8 | 9 | use rls_span::{Column, Position, Row, Span}; 10 | use rls_vfs::{Change, VfsSpan}; 11 | use std::fs; 12 | use std::io::prelude::*; 13 | use std::path::{Path, PathBuf}; 14 | use std::process::Command; 15 | 16 | struct EmptyUserData; 17 | type Vfs = rls_vfs::Vfs; 18 | 19 | fn std_path() -> PathBuf { 20 | let mut cmd = Command::new("rustc"); 21 | cmd.args(&["--print", "sysroot"]); 22 | let op = cmd.output().unwrap(); 23 | let sysroot = Path::new(::std::str::from_utf8(&op.stdout).unwrap().trim()); 24 | sysroot.join("lib/rustlib/src/rust/src").to_owned() 25 | } 26 | 27 | fn add_file(vfs: &Vfs, path: &Path) { 28 | let mut buf = String::new(); 29 | let mut file = fs::File::open(path).unwrap(); 30 | file.read_to_string(&mut buf).unwrap(); 31 | let change = Change::AddFile { file: path.to_owned(), text: buf }; 32 | vfs.on_changes(&[change]).unwrap(); 33 | } 34 | 35 | fn make_change_(path: &Path, start_line: usize, interval: usize) -> Change { 36 | const LEN: usize = 10; 37 | let txt = unsafe { std::str::from_utf8_unchecked(&[b' '; 100]) }; 38 | let start = 39 | Position::new(Row::new_zero_indexed(start_line as u32), Column::new_zero_indexed(0)); 40 | let end = Position::new( 41 | Row::new_zero_indexed((start_line + interval) as u32), 42 | Column::new_zero_indexed(0), 43 | ); 44 | let buf = (0..LEN).map(|_| txt.to_owned() + "\n").collect::(); 45 | Change::ReplaceText { 46 | span: VfsSpan::from_usv(Span::from_positions(start, end, path), None), 47 | text: buf, 48 | } 49 | } 50 | 51 | fn make_replace(path: &Path, start_line: usize) -> Change { 52 | make_change_(path, start_line, 10) 53 | } 54 | 55 | fn make_insertion(path: &Path, start_line: usize) -> Change { 56 | make_change_(path, start_line, 1) 57 | } 58 | 59 | fn prepare() -> (Vfs, PathBuf) { 60 | let vfs = Vfs::new(); 61 | // path.rs is very long(about 4100 lines) so let's use it 62 | let lib = std_path().join("libstd/path.rs"); 63 | println!("{:?}", lib); 64 | add_file(&vfs, &lib); 65 | (vfs, lib) 66 | } 67 | 68 | #[bench] 69 | fn replace_front(b: &mut test::Bencher) { 70 | let (vfs, lib) = prepare(); 71 | b.iter(|| { 72 | for _ in 0..10 { 73 | let change = make_replace(&lib, 0); 74 | vfs.on_changes(&[change]).unwrap(); 75 | } 76 | }) 77 | } 78 | 79 | #[bench] 80 | fn replace_mid(b: &mut test::Bencher) { 81 | let (vfs, lib) = prepare(); 82 | b.iter(|| { 83 | for _ in 0..10 { 84 | let change = make_replace(&lib, 2000); 85 | vfs.on_changes(&[change]).unwrap(); 86 | } 87 | }) 88 | } 89 | 90 | #[bench] 91 | fn replace_tale(b: &mut test::Bencher) { 92 | let (vfs, lib) = prepare(); 93 | b.iter(|| { 94 | for _ in 0..10 { 95 | let change = make_replace(&lib, 4000); 96 | vfs.on_changes(&[change]).unwrap(); 97 | } 98 | }) 99 | } 100 | 101 | #[bench] 102 | fn insert_front(b: &mut test::Bencher) { 103 | let (vfs, lib) = prepare(); 104 | b.iter(|| { 105 | for _ in 0..10 { 106 | let change = make_insertion(&lib, 0); 107 | vfs.on_changes(&[change]).unwrap(); 108 | } 109 | }) 110 | } 111 | 112 | #[bench] 113 | fn insert_mid(b: &mut test::Bencher) { 114 | let (vfs, lib) = prepare(); 115 | b.iter(|| { 116 | for _ in 0..10 { 117 | let change = make_insertion(&lib, 2000); 118 | vfs.on_changes(&[change]).unwrap(); 119 | } 120 | }) 121 | } 122 | 123 | #[bench] 124 | fn insert_tale(b: &mut test::Bencher) { 125 | let (vfs, lib) = prepare(); 126 | b.iter(|| { 127 | for _ in 0..10 { 128 | let change = make_insertion(&lib, 4000); 129 | vfs.on_changes(&[change]).unwrap(); 130 | } 131 | }) 132 | } 133 | -------------------------------------------------------------------------------- /rls/src/actions/run.rs: -------------------------------------------------------------------------------- 1 | use crate::actions::InitActionContext; 2 | use lazy_static::lazy_static; 3 | use log::error; 4 | use ordslice::Ext; 5 | use regex::Regex; 6 | use rls_span::{Column, Position, Range, Row, ZeroIndexed}; 7 | use rls_vfs::FileContents; 8 | use serde_derive::Serialize; 9 | 10 | use std::{collections::HashMap, iter, path::Path}; 11 | 12 | pub fn collect_run_actions(ctx: &InitActionContext, file: &Path) -> Vec { 13 | let text = match ctx.vfs.load_file(file) { 14 | Ok(FileContents::Text(text)) => text, 15 | Ok(FileContents::Binary(_)) => return Vec::new(), 16 | Err(e) => { 17 | error!("failed to collect run actions: {}", e); 18 | return Vec::new(); 19 | } 20 | }; 21 | if !text.contains("#[test]") { 22 | return Vec::new(); 23 | } 24 | 25 | lazy_static! { 26 | /// __(a):__ `\#\[([\w]+::)*test\]` matches `#[test]`, `#[async_executor::test]` or `#[async_lib::module::test]`. 27 | /// 28 | /// __(b):__ `^[^\/]*?fn\s+(?P\w+)` matches any line which contains `fn name` before any comment is started and captures the word after fn. 29 | /// The laziness of the quantifier is there to make the regex quicker (about 5 times less steps) 30 | /// 31 | /// __(c):__ `(\n|.)*?` will match anything lazilly, matching whatever shortest string exists between __(a)__ and __(b)__, ensuring 32 | /// that whatever sits in between `#[test]` and the next function declaration doesn't interfere. It MUST be lazy, both for performance, 33 | /// as well as to prevent matches with further declared functions. 34 | /// 35 | /// __(d):__ `(?m)` sets the and `m` regex flags to allow `^` to match line starts. 36 | /// 37 | /// This regex is still imperfect, for example: 38 | /// ```rust 39 | /// #[test] /* 40 | /// But at this point it's pretty much a deliberate attempt 41 | /// to make `fn wrong_function` be matched instead of */ 42 | /// fn right_function() {} 43 | /// ``` 44 | static ref TEST_FN_RE: Regex = 45 | Regex::new(r"(?m)#\[([\w]+::)*test\](\n|.)*?^[^/]*?fn\s+(?P\w+)").unwrap(); 46 | } 47 | 48 | let line_index = LineIndex::new(&text); 49 | 50 | let mut ret = Vec::new(); 51 | for caps in TEST_FN_RE.captures_iter(&text) { 52 | let group = caps.name("name").unwrap(); 53 | let target_element = Range::from_positions( 54 | line_index.offset_to_position(group.start()), 55 | line_index.offset_to_position(group.end()), 56 | ); 57 | let test_name = group.as_str(); 58 | let run_action = RunAction { 59 | label: "Run test".to_string(), 60 | target_element, 61 | cmd: Cmd { 62 | binary: "cargo".to_string(), 63 | args: vec![ 64 | "test".to_string(), 65 | "--".to_string(), 66 | "--nocapture".to_string(), 67 | test_name.to_string(), 68 | ], 69 | env: iter::once(("RUST_BACKTRACE".to_string(), "short".to_string())).collect(), 70 | }, 71 | }; 72 | ret.push(run_action); 73 | } 74 | ret 75 | } 76 | 77 | pub struct RunAction { 78 | pub label: String, 79 | pub target_element: Range, 80 | pub cmd: Cmd, 81 | } 82 | 83 | #[derive(Serialize)] 84 | pub struct Cmd { 85 | pub binary: String, 86 | pub args: Vec, 87 | pub env: HashMap, 88 | } 89 | 90 | pub struct LineIndex { 91 | newlines: Vec, 92 | } 93 | 94 | impl LineIndex { 95 | pub fn new(text: &str) -> LineIndex { 96 | let newlines = text.bytes().enumerate().filter(|&(_i, b)| b == b'\n').map(|(i, _b)| i + 1); 97 | let newlines = iter::once(0).chain(newlines).collect(); 98 | LineIndex { newlines } 99 | } 100 | 101 | pub fn offset_to_position(&self, offset: usize) -> Position { 102 | let line = self.newlines.upper_bound(&offset) - 1; 103 | let line_start_offset = self.newlines[line]; 104 | let col = offset - line_start_offset; 105 | Position::new(Row::new_zero_indexed(line as u32), Column::new_zero_indexed(col as u32)) 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /rls/src/concurrency.rs: -------------------------------------------------------------------------------- 1 | use std::thread; 2 | 3 | use crossbeam_channel::{bounded, select, Receiver, Select, Sender}; 4 | 5 | /// `ConcurrentJob` is a handle for some long-running computation 6 | /// off the main thread. It can be used, indirectly, to wait for 7 | /// the completion of the said computation. 8 | /// 9 | /// All `ConncurrentJob`s must eventually be stored in a `Jobs` table. 10 | /// 11 | /// All concurrent activities, like spawning a thread or pushing 12 | /// a work item to a job queue, should be covered by `ConcurrentJob`. 13 | /// This way, the set of `Jobs` table will give a complete overview of 14 | /// concurrency in the system, and it will be possinle to wait for all 15 | /// jobs to finish, which helps tremendously with making tests deterministic. 16 | /// 17 | /// `JobToken` is the worker-side counterpart of `ConcurrentJob`. Dropping 18 | /// a `JobToken` signals that the corresponding job has finished. 19 | #[must_use] 20 | pub struct ConcurrentJob { 21 | chan: Receiver, 22 | } 23 | 24 | pub struct JobToken { 25 | _chan: Sender, 26 | } 27 | 28 | #[derive(Default)] 29 | pub struct Jobs { 30 | jobs: Vec, 31 | } 32 | 33 | impl Jobs { 34 | pub fn add(&mut self, job: ConcurrentJob) { 35 | self.gc(); 36 | self.jobs.push(job); 37 | } 38 | 39 | /// Blocks the current thread until all pending jobs are finished. 40 | pub fn wait_for_all(&mut self) { 41 | while !self.jobs.is_empty() { 42 | let done: usize = { 43 | let mut select = Select::new(); 44 | for job in &self.jobs { 45 | select.recv(&job.chan); 46 | } 47 | 48 | let oper = select.select(); 49 | let oper_index = oper.index(); 50 | let chan = &self.jobs[oper_index].chan; 51 | assert!(oper.recv(chan).is_err()); 52 | oper_index 53 | }; 54 | drop(self.jobs.swap_remove(done)); 55 | } 56 | } 57 | 58 | fn gc(&mut self) { 59 | self.jobs.retain(|job| !job.is_completed()) 60 | } 61 | } 62 | 63 | impl ConcurrentJob { 64 | pub fn new() -> (ConcurrentJob, JobToken) { 65 | let (tx, rx) = bounded(0); 66 | let job = ConcurrentJob { chan: rx }; 67 | let token = JobToken { _chan: tx }; 68 | (job, token) 69 | } 70 | 71 | fn is_completed(&self) -> bool { 72 | is_closed(&self.chan) 73 | } 74 | } 75 | 76 | impl Drop for ConcurrentJob { 77 | fn drop(&mut self) { 78 | if self.is_completed() || thread::panicking() { 79 | return; 80 | } 81 | panic!("orphaned concurrent job"); 82 | } 83 | } 84 | 85 | // We don't actually send messages through the channels, 86 | // and instead just check if the channel is closed, 87 | // so we use uninhabited enum as a message type 88 | enum Never {} 89 | 90 | /// Non-blocking. 91 | fn is_closed(chan: &Receiver) -> bool { 92 | select! { 93 | recv(chan) -> msg => match msg { 94 | Err(_) => true, 95 | Ok(never) => match never {} 96 | }, 97 | default => false, 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /rls/src/lib.rs: -------------------------------------------------------------------------------- 1 | //! The Rust Language Server. 2 | //! 3 | //! The RLS provides a server that runs in the background, providing IDEs, 4 | //! editors, and other tools with information about Rust programs. It supports 5 | //! functionality such as 'goto definition', symbol search, reformatting, and 6 | //! code completion, and enables renaming and refactorings. 7 | 8 | #![feature(rustc_private, drain_filter)] 9 | #![warn(rust_2018_idioms)] 10 | #![warn(clippy::all, clippy::clone_on_ref_ptr)] 11 | #![allow(clippy::cognitive_complexity, clippy::too_many_arguments, clippy::redundant_closure)] 12 | 13 | pub use rls_analysis::{AnalysisHost, Target}; 14 | pub use rls_vfs::Vfs; 15 | 16 | pub mod actions; 17 | pub mod build; 18 | pub mod cmd; 19 | pub mod concurrency; 20 | pub mod config; 21 | pub mod lsp_data; 22 | pub mod project_model; 23 | pub mod server; 24 | 25 | type Span = rls_span::Span; 26 | 27 | pub const RUSTC_SHIM_ENV_VAR_NAME: &str = "RLS_RUSTC_SHIM"; 28 | 29 | pub fn version() -> String { 30 | use rustc_tools_util::VersionInfo; 31 | 32 | rustc_tools_util::get_version_info!().to_string() 33 | } 34 | -------------------------------------------------------------------------------- /rls/src/main.rs: -------------------------------------------------------------------------------- 1 | //! The Rust Language Server. 2 | //! 3 | //! The RLS provides a server that runs in the background, providing IDEs, 4 | //! editors, and other tools with information about Rust programs. It supports 5 | //! functionality such as 'goto definition', symbol search, reformatting, and 6 | //! code completion, and enables renaming and refactorings. 7 | 8 | use log::warn; 9 | use rls_rustc as rustc_shim; 10 | 11 | use std::env; 12 | use std::sync::Arc; 13 | 14 | const RUSTC_WRAPPER_ENV_VAR: &str = "RUSTC_WRAPPER"; 15 | 16 | /// The main entry point to the RLS. Parses CLI arguments and then runs the server. 17 | pub fn main() { 18 | let exit_code = main_inner(); 19 | std::process::exit(exit_code); 20 | } 21 | 22 | fn main_inner() -> i32 { 23 | env_logger::init(); 24 | 25 | // [workaround] 26 | // Currently sccache breaks RLS with obscure error messages. 27 | // Until it's actually fixed disable the wrapper completely 28 | // in the current process tree. 29 | // 30 | // See https://github.com/rust-lang/rls/issues/703 31 | // and https://github.com/mozilla/sccache/issues/303 32 | if env::var_os(RUSTC_WRAPPER_ENV_VAR).is_some() { 33 | warn!( 34 | "The {} environment variable is incompatible with RLS, \ 35 | removing it from the process environment", 36 | RUSTC_WRAPPER_ENV_VAR 37 | ); 38 | env::remove_var(RUSTC_WRAPPER_ENV_VAR); 39 | } 40 | 41 | if env::var(rls::RUSTC_SHIM_ENV_VAR_NAME).ok().map_or(false, |v| v != "0") { 42 | match rustc_shim::run() { 43 | Ok(..) => return 0, 44 | Err(..) => return 101, 45 | } 46 | } 47 | 48 | if let Some(first_arg) = env::args().nth(1) { 49 | return match first_arg.as_str() { 50 | "--version" | "-V" => { 51 | println!("{}", rls::version()); 52 | 0 53 | } 54 | "--help" | "-h" => { 55 | println!("{}", help()); 56 | 0 57 | } 58 | "--cli" => { 59 | rls::cmd::run(); 60 | 0 61 | } 62 | unknown => { 63 | println!("Unknown argument '{}'. Supported arguments:\n{}", unknown, help()); 64 | 101 65 | } 66 | }; 67 | } 68 | 69 | let analysis = Arc::new(rls::AnalysisHost::new(rls::Target::Debug)); 70 | let vfs = Arc::new(rls::Vfs::new()); 71 | 72 | rls::server::run_server(analysis, vfs) 73 | } 74 | 75 | fn help() -> &'static str { 76 | r#" 77 | --version or -V to print the version and commit info 78 | --help or -h for this message 79 | --cli starts the RLS in command line mode 80 | No input starts the RLS as a language server 81 | "# 82 | } 83 | -------------------------------------------------------------------------------- /rust-toolchain: -------------------------------------------------------------------------------- 1 | [toolchain] 2 | channel = "nightly-2022-06-06" 3 | components = ["rust-src", "rustc-dev", "llvm-tools-preview"] 4 | -------------------------------------------------------------------------------- /rustfmt.toml: -------------------------------------------------------------------------------- 1 | use_field_init_shorthand = true 2 | use_small_heuristics = "Max" 3 | -------------------------------------------------------------------------------- /tests/fixtures/Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | [[package]] 4 | name = "bin_lib" 5 | version = "0.1.0" 6 | 7 | [[package]] 8 | name = "borrow_error" 9 | version = "0.1.0" 10 | 11 | [[package]] 12 | name = "compile_fail" 13 | version = "0.1.0" 14 | 15 | [[package]] 16 | name = "completion" 17 | version = "0.1.0" 18 | 19 | [[package]] 20 | name = "deglob" 21 | version = "0.1.0" 22 | 23 | [[package]] 24 | name = "dep_fail" 25 | version = "0.1.0" 26 | dependencies = [ 27 | "compile_fail 0.1.0", 28 | ] 29 | 30 | [[package]] 31 | name = "features" 32 | version = "0.1.0" 33 | 34 | [[package]] 35 | name = "find_all_refs_no_cfg_test" 36 | version = "0.1.0" 37 | 38 | [[package]] 39 | name = "find_impls" 40 | version = "0.1.0" 41 | 42 | [[package]] 43 | name = "fnv" 44 | version = "1.0.6" 45 | source = "registry+https://github.com/rust-lang/crates.io-index" 46 | 47 | [[package]] 48 | name = "hover" 49 | version = "0.1.0" 50 | dependencies = [ 51 | "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", 52 | ] 53 | 54 | [[package]] 55 | name = "infer_bin" 56 | version = "0.1.0" 57 | 58 | [[package]] 59 | name = "infer_custom_bin" 60 | version = "0.1.0" 61 | 62 | [[package]] 63 | name = "infer_lib" 64 | version = "0.1.0" 65 | 66 | [[package]] 67 | name = "multiple_bins" 68 | version = "0.1.0" 69 | 70 | [[package]] 71 | name = "reformat" 72 | version = "0.1.0" 73 | 74 | [[package]] 75 | name = "reformat_with_range" 76 | version = "0.1.0" 77 | 78 | [[package]] 79 | name = "run" 80 | version = "0.1.0" 81 | 82 | [[package]] 83 | name = "workspace_symbol" 84 | version = "0.1.0" 85 | 86 | [[package]] 87 | name = "workspace_symbol_duplicates" 88 | version = "0.1.0" 89 | 90 | [metadata] 91 | "checksum fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2fad85553e09a6f881f739c29f0b00b0f01357c743266d478b68951ce23285f3" 92 | -------------------------------------------------------------------------------- /tests/fixtures/Cargo.toml: -------------------------------------------------------------------------------- 1 | # Make sure that test are not accidentally become members of 2 | # the main workspace in the rust-lang/rust repository 3 | [workspace] 4 | members = ["./*/"] 5 | exclude = ["./compiler_message", "./target"] 6 | -------------------------------------------------------------------------------- /tests/fixtures/bin_lib/Cargo.lock: -------------------------------------------------------------------------------- 1 | [[package]] 2 | name = "bin_lib" 3 | version = "0.1.0" 4 | 5 | -------------------------------------------------------------------------------- /tests/fixtures/bin_lib/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "bin_lib" 3 | version = "0.1.0" 4 | authors = ["Igor Matuszewski "] 5 | 6 | [dependencies] 7 | -------------------------------------------------------------------------------- /tests/fixtures/bin_lib/src/lib.rs: -------------------------------------------------------------------------------- 1 | pub struct LibStruct {} 2 | -------------------------------------------------------------------------------- /tests/fixtures/bin_lib/src/main.rs: -------------------------------------------------------------------------------- 1 | extern crate bin_lib; 2 | 3 | #[allow(unused_variables)] 4 | fn main() { 5 | let a = bin_lib::LibStruct {}; 6 | 7 | println!("Hello, world!"); 8 | } 9 | -------------------------------------------------------------------------------- /tests/fixtures/bin_lib/tests/tests.rs: -------------------------------------------------------------------------------- 1 | #[test] 2 | fn test_some_foo() { 3 | let unused_var = true; 4 | assert!(true); 5 | } 6 | -------------------------------------------------------------------------------- /tests/fixtures/borrow_error/Cargo.lock: -------------------------------------------------------------------------------- 1 | [[package]] 2 | name = "borrow_error" 3 | version = "0.1.0" 4 | 5 | -------------------------------------------------------------------------------- /tests/fixtures/borrow_error/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "borrow_error" 3 | version = "0.1.0" 4 | authors = ["Jonathan Turner "] 5 | edition = "2018" 6 | 7 | [dependencies] 8 | -------------------------------------------------------------------------------- /tests/fixtures/borrow_error/src/main.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | let mut x = 3; 3 | let y = &mut x; 4 | let z = &mut x; 5 | *y += 1; 6 | } 7 | -------------------------------------------------------------------------------- /tests/fixtures/common/Cargo.lock: -------------------------------------------------------------------------------- 1 | [[package]] 2 | name = "completion" 3 | version = "0.1.0" 4 | 5 | -------------------------------------------------------------------------------- /tests/fixtures/common/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "completion" 3 | version = "0.1.0" 4 | authors = ["Nick Cameron "] 5 | 6 | [dependencies] 7 | -------------------------------------------------------------------------------- /tests/fixtures/common/src/main.rs: -------------------------------------------------------------------------------- 1 | struct Bar { 2 | x: u64, 3 | } 4 | 5 | #[test] 6 | pub fn test_fn() { 7 | let bar = Bar { x: 4 }; 8 | println!("bar: {}", bar.x); 9 | } 10 | 11 | pub fn main() { 12 | let world = "world"; 13 | println!("Hello, {}!", world); 14 | 15 | let bar2 = Bar { x: 5 }; 16 | println!("bar2: {}", bar2.x); 17 | } 18 | -------------------------------------------------------------------------------- /tests/fixtures/compile_fail/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "compile_fail" 3 | version = "0.1.0" 4 | authors = ["Nick Cameron "] 5 | 6 | [dependencies] 7 | -------------------------------------------------------------------------------- /tests/fixtures/compile_fail/src/lib.rs: -------------------------------------------------------------------------------- 1 | pub fn foo() { 2 | let x = y + 4; 3 | } 4 | -------------------------------------------------------------------------------- /tests/fixtures/compiler_message/cannot-find-type.json: -------------------------------------------------------------------------------- 1 | { 2 | "children": [{ 3 | "children": [], 4 | "code": null, 5 | "level": "help", 6 | "message": "possible candidates are found in other modules, you can import them into scope", 7 | "rendered": null, 8 | "spans": [{ 9 | "byte_end": 528, 10 | "byte_start": 528, 11 | "column_end": 1, 12 | "column_start": 1, 13 | "expansion": null, 14 | "file_name": "src/actions/post_build.rs", 15 | "is_primary": true, 16 | "label": null, 17 | "line_end": 15, 18 | "line_start": 15, 19 | "suggested_replacement": "use std::collections::HashSet;\n", 20 | "text": [{ 21 | "highlight_end": 1, 22 | "highlight_start": 1, 23 | "text": "use std::collections::HashMap;" 24 | }] 25 | }, { 26 | "byte_end": 528, 27 | "byte_start": 528, 28 | "column_end": 1, 29 | "column_start": 1, 30 | "expansion": null, 31 | "file_name": "src/actions/post_build.rs", 32 | "is_primary": true, 33 | "label": null, 34 | "line_end": 15, 35 | "line_start": 15, 36 | "suggested_replacement": "use std::collections::hash_set::HashSet;\n", 37 | "text": [{ 38 | "highlight_end": 1, 39 | "highlight_start": 1, 40 | "text": "use std::collections::HashMap;" 41 | }] 42 | }] 43 | }], 44 | "code": { 45 | "code": "E0412", 46 | "explanation": "\nThe type name used is not in scope.\n\nErroneous code examples:\n\n```compile_fail,E0412\nimpl Something {} // error: type name `Something` is not in scope\n\n// or:\n\ntrait Foo {\n fn bar(N); // error: type name `N` is not in scope\n}\n\n// or:\n\nfn foo(x: T) {} // type name `T` is not in scope\n```\n\nTo fix this error, please verify you didn't misspell the type name, you did\ndeclare it or imported it into the scope. Examples:\n\n```\nstruct Something;\n\nimpl Something {} // ok!\n\n// or:\n\ntrait Foo {\n type N;\n\n fn bar(_: Self::N); // ok!\n}\n\n// or:\n\nfn foo(x: T) {} // ok!\n```\n\nAnother case that causes this error is when a type is imported into a parent\nmodule. To fix this, you can follow the suggestion and use File directly or\n`use super::File;` which will import the types from the parent namespace. An\nexample that causes this error is below:\n\n```compile_fail,E0412\nuse std::fs::File;\n\nmod foo {\n fn some_function(f: File) {}\n}\n```\n\n```\nuse std::fs::File;\n\nmod foo {\n // either\n use super::File;\n // or\n // use std::fs::File;\n fn foo(f: File) {}\n}\n# fn main() {} // don't insert it for us; that'll break imports\n```\n" 47 | }, 48 | "level": "error", 49 | "message": "cannot find type `HashSet` in this scope", 50 | "rendered": "error[E0412]: cannot find type `HashSet` in this scope\n --> src/actions/post_build.rs:158:32\n |\n158 | .collect::()\n | ^^^^^^^ not found in this scope\nhelp: possible candidates are found in other modules, you can import them into scope\n |\n15 | use std::collections::HashSet;\n |\n15 | use std::collections::hash_set::HashSet;\n |\n\n", 51 | "spans": [{ 52 | "byte_end": 5500, 53 | "byte_start": 5493, 54 | "column_end": 39, 55 | "column_start": 32, 56 | "expansion": null, 57 | "file_name": "src/actions/post_build.rs", 58 | "is_primary": true, 59 | "label": "not found in this scope", 60 | "line_end": 158, 61 | "line_start": 158, 62 | "suggested_replacement": null, 63 | "text": [{ 64 | "highlight_end": 39, 65 | "highlight_start": 32, 66 | "text": " .collect::()" 67 | }] 68 | }] 69 | } 70 | -------------------------------------------------------------------------------- /tests/fixtures/compiler_message/clippy-const-static-lifetime.json: -------------------------------------------------------------------------------- 1 | { 2 | "children": [{ 3 | "children": [], 4 | "code": null, 5 | "level": "note", 6 | "message": "lint level defined here", 7 | "rendered": null, 8 | "spans": [{ 9 | "byte_end": 889, 10 | "byte_start": 883, 11 | "column_end": 15, 12 | "column_start": 9, 13 | "expansion": null, 14 | "file_name": "src/main.rs", 15 | "is_primary": true, 16 | "label": null, 17 | "line_end": 21, 18 | "line_start": 21, 19 | "suggested_replacement": null, 20 | "text": [{ 21 | "highlight_end": 15, 22 | "highlight_start": 9, 23 | "text": "#![warn(clippy)]" 24 | }] 25 | }] 26 | }, { 27 | "children": [], 28 | "code": null, 29 | "level": "note", 30 | "message": "#[warn(const_static_lifetime)] implied by #[warn(clippy)]", 31 | "rendered": null, 32 | "spans": [] 33 | }, { 34 | "children": [], 35 | "code": null, 36 | "level": "help", 37 | "message": "for further information visit https://rust-lang-nursery.github.io/rust-clippy/v0.0.187/index.html#const_static_lifetime", 38 | "rendered": null, 39 | "spans": [] 40 | }, { 41 | "children": [], 42 | "code": null, 43 | "level": "help", 44 | "message": "consider removing `'static`", 45 | "rendered": null, 46 | "spans": [{ 47 | "byte_end": 12140, 48 | "byte_start": 12128, 49 | "column_end": 47, 50 | "column_start": 35, 51 | "expansion": null, 52 | "file_name": "src/lsp_data.rs", 53 | "is_primary": true, 54 | "label": null, 55 | "line_end": 355, 56 | "line_start": 355, 57 | "suggested_replacement": "&str", 58 | "text": [{ 59 | "highlight_end": 47, 60 | "highlight_start": 35, 61 | "text": "pub const WINDOW_PROGRESS: &'static str = \"window/progress\";" 62 | }] 63 | }] 64 | }], 65 | "code": { 66 | "code": "const_static_lifetime", 67 | "explanation": null 68 | }, 69 | "level": "warning", 70 | "message": "Constants have by default a `'static` lifetime", 71 | "rendered": "warning: Constants have by default a `'static` lifetime\n --> src/lsp_data.rs:355:36\n |\n355 | pub const WINDOW_PROGRESS: &'static str = \"window/progress\";\n | -^^^^^^^---- help: consider removing `'static`: `&str`\n |\nnote: lint level defined here\n --> src/main.rs:21:9\n |\n21 | #![warn(clippy)]\n | ^^^^^^\n = note: #[warn(const_static_lifetime)] implied by #[warn(clippy)]\n = help: for further information visit https://rust-lang-nursery.github.io/rust-clippy/v0.0.187/index.html#const_static_lifetime\n\n", 72 | "spans": [{ 73 | "byte_end": 12136, 74 | "byte_start": 12129, 75 | "column_end": 43, 76 | "column_start": 36, 77 | "expansion": null, 78 | "file_name": "src/lsp_data.rs", 79 | "is_primary": true, 80 | "label": null, 81 | "line_end": 355, 82 | "line_start": 355, 83 | "suggested_replacement": null, 84 | "text": [{ 85 | "highlight_end": 43, 86 | "highlight_start": 36, 87 | "text": "pub const WINDOW_PROGRESS: &'static str = \"window/progress\";" 88 | }] 89 | }] 90 | } 91 | -------------------------------------------------------------------------------- /tests/fixtures/compiler_message/clippy-identity-op.json: -------------------------------------------------------------------------------- 1 | { 2 | "children": [{ 3 | "children": [], 4 | "code": null, 5 | "level": "note", 6 | "message": "lint level defined here", 7 | "rendered": null, 8 | "spans": [{ 9 | "byte_end": 39, 10 | "byte_start": 33, 11 | "column_end": 15, 12 | "column_start": 9, 13 | "expansion": null, 14 | "file_name": "src/main.rs", 15 | "is_primary": true, 16 | "label": null, 17 | "line_end": 2, 18 | "line_start": 2, 19 | "suggested_replacement": null, 20 | "text": [{ 21 | "highlight_end": 15, 22 | "highlight_start": 9, 23 | "text": "#![warn(clippy)]" 24 | }] 25 | }] 26 | }, { 27 | "children": [], 28 | "code": null, 29 | "level": "note", 30 | "message": "#[warn(identity_op)] implied by #[warn(clippy)]", 31 | "rendered": null, 32 | "spans": [] 33 | }, { 34 | "children": [], 35 | "code": null, 36 | "level": "help", 37 | "message": "for further information visit https://rust-lang-nursery.github.io/rust-clippy/v0.0.186/index.html#identity_op", 38 | "rendered": null, 39 | "spans": [] 40 | }], 41 | "code": { 42 | "code": "identity_op", 43 | "explanation": null 44 | }, 45 | "level": "warning", 46 | "message": "the operation is ineffective. Consider reducing it to `1`", 47 | "rendered": "warning: the operation is ineffective. Consider reducing it to `1`\n --> src/main.rs:5:14\n |\n5 | let _s = 1 / 1;\n | ^^^^^\n |\nnote: lint level defined here\n --> src/main.rs:2:9\n |\n2 | #![warn(clippy)]\n | ^^^^^^\n = note: #[warn(identity_op)] implied by #[warn(clippy)]\n = help: for further information visit https://rust-lang-nursery.github.io/rust-clippy/v0.0.186/index.html#identity_op\n\n", 48 | "spans": [{ 49 | "byte_end": 73, 50 | "byte_start": 68, 51 | "column_end": 19, 52 | "column_start": 14, 53 | "expansion": null, 54 | "file_name": "src/main.rs", 55 | "is_primary": true, 56 | "label": null, 57 | "line_end": 5, 58 | "line_start": 5, 59 | "suggested_replacement": null, 60 | "text": [{ 61 | "highlight_end": 19, 62 | "highlight_start": 14, 63 | "text": " let _s = 1 / 1;" 64 | }] 65 | }] 66 | } 67 | -------------------------------------------------------------------------------- /tests/fixtures/compiler_message/consider-borrowing.json: -------------------------------------------------------------------------------- 1 | { 2 | "children": [{ 3 | "children": [], 4 | "code": null, 5 | "level": "note", 6 | "message": "expected type `&str`\n found type `std::string::String`", 7 | "rendered": null, 8 | "spans": [] 9 | }, { 10 | "children": [], 11 | "code": null, 12 | "level": "help", 13 | "message": "consider borrowing here", 14 | "rendered": null, 15 | "spans": [{ 16 | "byte_end": 4144, 17 | "byte_start": 4138, 18 | "column_end": 25, 19 | "column_start": 19, 20 | "expansion": null, 21 | "file_name": "src/lib.rs", 22 | "is_primary": true, 23 | "label": null, 24 | "line_end": 135, 25 | "line_start": 135, 26 | "suggested_replacement": "&string", 27 | "text": [{ 28 | "highlight_end": 25, 29 | "highlight_start": 19, 30 | "text": " takes_ref(string);" 31 | }] 32 | }] 33 | }], 34 | "code": { 35 | "code": "E0308", 36 | "explanation": "\nThis error occurs when the compiler was unable to infer the concrete type of a\nvariable. It can occur for several cases, the most common of which is a\nmismatch in the expected type that the compiler inferred for a variable's\ninitializing expression, and the actual type explicitly assigned to the\nvariable.\n\nFor example:\n\n```compile_fail,E0308\nlet x: i32 = \"I am not a number!\";\n// ~~~ ~~~~~~~~~~~~~~~~~~~~\n// | |\n// | initializing expression;\n// | compiler infers type `&str`\n// |\n// type `i32` assigned to variable `x`\n```\n" 37 | }, 38 | "level": "error", 39 | "message": "mismatched types", 40 | "rendered": "error[E0308]: mismatched types\n --> src/lib.rs:135:19\n |\n135 | takes_ref(string);\n | ^^^^^^\n | |\n | expected &str, found struct `std::string::String`\n | help: consider borrowing here: `&string`\n |\n = note: expected type `&str`\n found type `std::string::String`\n\n", 41 | "spans": [{ 42 | "byte_end": 4144, 43 | "byte_start": 4138, 44 | "column_end": 25, 45 | "column_start": 19, 46 | "expansion": null, 47 | "file_name": "src/lib.rs", 48 | "is_primary": true, 49 | "label": "expected &str, found struct `std::string::String`", 50 | "line_end": 135, 51 | "line_start": 135, 52 | "suggested_replacement": null, 53 | "text": [{ 54 | "highlight_end": 25, 55 | "highlight_start": 19, 56 | "text": " takes_ref(string);" 57 | }] 58 | }] 59 | } 60 | -------------------------------------------------------------------------------- /tests/fixtures/compiler_message/macro-error-no-trait.json: -------------------------------------------------------------------------------- 1 | { 2 | "children": [{ 3 | "children": [], 4 | "code": null, 5 | "level": "help", 6 | "message": "items from traits can only be used if the trait is in scope", 7 | "rendered": null, 8 | "spans": [] 9 | }, { 10 | "children": [], 11 | "code": null, 12 | "level": "help", 13 | "message": "the following trait is implemented but not in scope, perhaps add a `use` for it:", 14 | "rendered": null, 15 | "spans": [{ 16 | "byte_end": 0, 17 | "byte_start": 0, 18 | "column_end": 1, 19 | "column_start": 1, 20 | "expansion": null, 21 | "file_name": "src/main.rs", 22 | "is_primary": true, 23 | "label": null, 24 | "line_end": 1, 25 | "line_start": 1, 26 | "suggested_replacement": "use std::fmt::Write;\n\n", 27 | "suggestion_applicability": "Unspecified", 28 | "text": [{ 29 | "highlight_end": 1, 30 | "highlight_start": 1, 31 | "text": "fn main() {" 32 | }] 33 | }] 34 | }], 35 | "code": { 36 | "code": "E0599", 37 | "explanation": "\nThis error occurs when a method is used on a type which doesn't implement it:\n\nErroneous code example:\n\n```compile_fail,E0599\nstruct Mouth;\n\nlet x = Mouth;\nx.chocolate(); // error: no method named `chocolate` found for type `Mouth`\n // in the current scope\n```\n" 38 | }, 39 | "level": "error", 40 | "message": "no method named `write_fmt` found for type `std::string::String` in the current scope", 41 | "rendered": "error[E0599]: no method named `write_fmt` found for type `std::string::String` in the current scope\n --> src/main.rs:3:5\n |\n3 | write!(out, \"{}\", 123);\n | ^^^^^^^^^^^^^^^^^^^^^^^\n |\n = help: items from traits can only be used if the trait is in scope\n = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)\nhelp: the following trait is implemented but not in scope, perhaps add a `use` for it:\n |\n1 | use std::fmt::Write;\n |\n\n", 42 | "spans": [{ 43 | "byte_end": 60, 44 | "byte_start": 51, 45 | "column_end": 18, 46 | "column_start": 9, 47 | "expansion": { 48 | "def_site_span": { 49 | "byte_end": 98, 50 | "byte_start": 0, 51 | "column_end": 56, 52 | "column_start": 1, 53 | "expansion": null, 54 | "file_name": "", 55 | "is_primary": false, 56 | "label": null, 57 | "line_end": 2, 58 | "line_start": 1, 59 | "suggested_replacement": null, 60 | "suggestion_applicability": null, 61 | "text": [{ 62 | "highlight_end": 43, 63 | "highlight_start": 1, 64 | "text": "( $ dst : expr , $ ( $ arg : tt ) * ) => (" 65 | }, { 66 | "highlight_end": 56, 67 | "highlight_start": 1, 68 | "text": "$ dst . write_fmt ( format_args ! ( $ ( $ arg ) * ) ) )" 69 | }] 70 | }, 71 | "macro_decl_name": "write!", 72 | "span": { 73 | "byte_end": 72, 74 | "byte_start": 49, 75 | "column_end": 28, 76 | "column_start": 5, 77 | "expansion": null, 78 | "file_name": "src/main.rs", 79 | "is_primary": false, 80 | "label": null, 81 | "line_end": 3, 82 | "line_start": 3, 83 | "suggested_replacement": null, 84 | "suggestion_applicability": null, 85 | "text": [{ 86 | "highlight_end": 28, 87 | "highlight_start": 5, 88 | "text": " write!(out, \"{}\", 123);" 89 | }] 90 | } 91 | }, 92 | "file_name": "", 93 | "is_primary": true, 94 | "label": null, 95 | "line_end": 2, 96 | "line_start": 2, 97 | "suggested_replacement": null, 98 | "suggestion_applicability": null, 99 | "text": [{ 100 | "highlight_end": 18, 101 | "highlight_start": 9, 102 | "text": "$ dst . write_fmt ( format_args ! ( $ ( $ arg ) * ) ) )" 103 | }] 104 | }] 105 | } 106 | -------------------------------------------------------------------------------- /tests/fixtures/compiler_message/mismatched-types.json: -------------------------------------------------------------------------------- 1 | { 2 | "children": [], 3 | "code": { 4 | "code": "E0308", 5 | "explanation": "\nThis error occurs when the compiler was unable to infer the concrete type of a\nvariable. It can occur for several cases, the most common of which is a\nmismatch in the expected type that the compiler inferred for a variable's\ninitializing expression, and the actual type explicitly assigned to the\nvariable.\n\nFor example:\n\n```compile_fail,E0308\nlet x: i32 = \"I am not a number!\";\n// ~~~ ~~~~~~~~~~~~~~~~~~~~\n// | |\n// | initializing expression;\n// | compiler infers type `&str`\n// |\n// type `i32` assigned to variable `x`\n```\n" 6 | }, 7 | "level": "error", 8 | "message": "mismatched types", 9 | "rendered": "error[E0308]: mismatched types\n --> src/lib.rs:137:9\n |\n136 | fn mismatched_types() -> usize {\n | ----- expected `usize` because of return type\n137 | 123_i32\n | ^^^^^^^ expected usize, found i32\n\n", 10 | "spans": [{ 11 | "byte_end": 4140, 12 | "byte_start": 4133, 13 | "column_end": 16, 14 | "column_start": 9, 15 | "expansion": null, 16 | "file_name": "src/lib.rs", 17 | "is_primary": true, 18 | "label": "expected usize, found i32", 19 | "line_end": 137, 20 | "line_start": 137, 21 | "suggested_replacement": null, 22 | "text": [{ 23 | "highlight_end": 16, 24 | "highlight_start": 9, 25 | "text": " 123_i32" 26 | }] 27 | }, { 28 | "byte_end": 4122, 29 | "byte_start": 4117, 30 | "column_end": 35, 31 | "column_start": 30, 32 | "expansion": null, 33 | "file_name": "src/lib.rs", 34 | "is_primary": false, 35 | "label": "expected `usize` because of return type", 36 | "line_end": 136, 37 | "line_start": 136, 38 | "suggested_replacement": null, 39 | "text": [{ 40 | "highlight_end": 35, 41 | "highlight_start": 30, 42 | "text": " fn mismatched_types() -> usize {" 43 | }] 44 | }] 45 | } 46 | -------------------------------------------------------------------------------- /tests/fixtures/compiler_message/move-out-of-borrow.json: -------------------------------------------------------------------------------- 1 | { 2 | "children": [], 3 | "code": { 4 | "code": "E0507", 5 | "explanation": "\nYou tried to move out of a value which was borrowed. Erroneous code example:\n\n```compile_fail,E0507\nuse std::cell::RefCell;\n\nstruct TheDarkKnight;\n\nimpl TheDarkKnight {\n fn nothing_is_true(self) {}\n}\n\nfn main() {\n let x = RefCell::new(TheDarkKnight);\n\n x.borrow().nothing_is_true(); // error: cannot move out of borrowed content\n}\n```\n\nHere, the `nothing_is_true` method takes the ownership of `self`. However,\n`self` cannot be moved because `.borrow()` only provides an `&TheDarkKnight`,\nwhich is a borrow of the content owned by the `RefCell`. To fix this error,\nyou have three choices:\n\n* Try to avoid moving the variable.\n* Somehow reclaim the ownership.\n* Implement the `Copy` trait on the type.\n\nExamples:\n\n```\nuse std::cell::RefCell;\n\nstruct TheDarkKnight;\n\nimpl TheDarkKnight {\n fn nothing_is_true(&self) {} // First case, we don't take ownership\n}\n\nfn main() {\n let x = RefCell::new(TheDarkKnight);\n\n x.borrow().nothing_is_true(); // ok!\n}\n```\n\nOr:\n\n```\nuse std::cell::RefCell;\n\nstruct TheDarkKnight;\n\nimpl TheDarkKnight {\n fn nothing_is_true(self) {}\n}\n\nfn main() {\n let x = RefCell::new(TheDarkKnight);\n let x = x.into_inner(); // we get back ownership\n\n x.nothing_is_true(); // ok!\n}\n```\n\nOr:\n\n```\nuse std::cell::RefCell;\n\n#[derive(Clone, Copy)] // we implement the Copy trait\nstruct TheDarkKnight;\n\nimpl TheDarkKnight {\n fn nothing_is_true(self) {}\n}\n\nfn main() {\n let x = RefCell::new(TheDarkKnight);\n\n x.borrow().nothing_is_true(); // ok!\n}\n```\n\nMoving a member out of a mutably borrowed struct will also cause E0507 error:\n\n```compile_fail,E0507\nstruct TheDarkKnight;\n\nimpl TheDarkKnight {\n fn nothing_is_true(self) {}\n}\n\nstruct Batcave {\n knight: TheDarkKnight\n}\n\nfn main() {\n let mut cave = Batcave {\n knight: TheDarkKnight\n };\n let borrowed = &mut cave;\n\n borrowed.knight.nothing_is_true(); // E0507\n}\n```\n\nIt is fine only if you put something back. `mem::replace` can be used for that:\n\n```\n# struct TheDarkKnight;\n# impl TheDarkKnight { fn nothing_is_true(self) {} }\n# struct Batcave { knight: TheDarkKnight }\nuse std::mem;\n\nlet mut cave = Batcave {\n knight: TheDarkKnight\n};\nlet borrowed = &mut cave;\n\nmem::replace(&mut borrowed.knight, TheDarkKnight).nothing_is_true(); // ok!\n```\n\nYou can find more information about borrowing in the rust-book:\nhttp://doc.rust-lang.org/book/first-edition/references-and-borrowing.html\n" 6 | }, 7 | "level": "error", 8 | "message": "cannot move out of borrowed content", 9 | "rendered": "error[E0507]: cannot move out of borrowed content\n --> src/main.rs:18:9\n |\n18 | &Some(string) => takes_borrow(&string),\n | ^^^^^^------^\n | | |\n | | hint: to prevent move, use `ref string` or `ref mut string`\n | cannot move out of borrowed content\n\n", 10 | "spans": [{ 11 | "byte_end": 567, 12 | "byte_start": 554, 13 | "column_end": 22, 14 | "column_start": 9, 15 | "expansion": null, 16 | "file_name": "src/main.rs", 17 | "is_primary": true, 18 | "label": "cannot move out of borrowed content", 19 | "line_end": 18, 20 | "line_start": 18, 21 | "suggested_replacement": null, 22 | "text": [{ 23 | "highlight_end": 22, 24 | "highlight_start": 9, 25 | "text": " &Some(string) => takes_borrow(&string)," 26 | }] 27 | }, { 28 | "byte_end": 566, 29 | "byte_start": 560, 30 | "column_end": 21, 31 | "column_start": 15, 32 | "expansion": null, 33 | "file_name": "src/main.rs", 34 | "is_primary": false, 35 | "label": "hint: to prevent move, use `ref string` or `ref mut string`", 36 | "line_end": 18, 37 | "line_start": 18, 38 | "suggested_replacement": null, 39 | "text": [{ 40 | "highlight_end": 21, 41 | "highlight_start": 15, 42 | "text": " &Some(string) => takes_borrow(&string)," 43 | }] 44 | }] 45 | } 46 | -------------------------------------------------------------------------------- /tests/fixtures/compiler_message/not-mut.json: -------------------------------------------------------------------------------- 1 | { 2 | "children": [], 3 | "code": { 4 | "code": "E0596", 5 | "explanation": "\nThis error occurs because you tried to mutably borrow a non-mutable variable.\n\nExample of erroneous code:\n\n```compile_fail,E0596\nlet x = 1;\nlet y = &mut x; // error: cannot borrow mutably\n```\n\nIn here, `x` isn't mutable, so when we try to mutably borrow it in `y`, it\nfails. To fix this error, you need to make `x` mutable:\n\n```\nlet mut x = 1;\nlet y = &mut x; // ok!\n```\n" 6 | }, 7 | "level": "error", 8 | "message": "cannot borrow immutable local variable `string` as mutable", 9 | "rendered": "error[E0596]: cannot borrow immutable local variable `string` as mutable\n --> src/lib.rs:134:24\n |\n133 | let string = String::new();\n | ------ consider changing this to `mut string`\n134 | let _s1 = &mut string;\n | ^^^^^^ cannot borrow mutably\n\n", 10 | "spans": [{ 11 | "byte_end": 4108, 12 | "byte_start": 4102, 13 | "column_end": 30, 14 | "column_start": 24, 15 | "expansion": null, 16 | "file_name": "src/lib.rs", 17 | "is_primary": true, 18 | "label": "cannot borrow mutably", 19 | "line_end": 134, 20 | "line_start": 134, 21 | "suggested_replacement": null, 22 | "text": [{ 23 | "highlight_end": 30, 24 | "highlight_start": 24, 25 | "text": " let _s1 = &mut string;" 26 | }] 27 | }, { 28 | "byte_end": 4061, 29 | "byte_start": 4055, 30 | "column_end": 19, 31 | "column_start": 13, 32 | "expansion": null, 33 | "file_name": "src/lib.rs", 34 | "is_primary": false, 35 | "label": "consider changing this to `mut string`", 36 | "line_end": 133, 37 | "line_start": 133, 38 | "suggested_replacement": null, 39 | "text": [{ 40 | "highlight_end": 19, 41 | "highlight_start": 13, 42 | "text": " let string = String::new();" 43 | }] 44 | }] 45 | } 46 | -------------------------------------------------------------------------------- /tests/fixtures/compiler_message/type-annotations-needed.json: -------------------------------------------------------------------------------- 1 | { 2 | "children": [], 3 | "code": { 4 | "code": "E0282", 5 | "explanation": "\nThis error indicates that type inference did not result in one unique possible\ntype, and extra information is required. In most cases this can be provided\nby adding a type annotation. Sometimes you need to specify a generic type\nparameter manually.\n\nA common example is the `collect` method on `Iterator`. It has a generic type\nparameter with a `FromIterator` bound, which for a `char` iterator is\nimplemented by `Vec` and `String` among others. Consider the following snippet\nthat reverses the characters of a string:\n\n```compile_fail,E0282\nlet x = \"hello\".chars().rev().collect();\n```\n\nIn this case, the compiler cannot infer what the type of `x` should be:\n`Vec` and `String` are both suitable candidates. To specify which type to\nuse, you can use a type annotation on `x`:\n\n```\nlet x: Vec = \"hello\".chars().rev().collect();\n```\n\nIt is not necessary to annotate the full type. Once the ambiguity is resolved,\nthe compiler can infer the rest:\n\n```\nlet x: Vec<_> = \"hello\".chars().rev().collect();\n```\n\nAnother way to provide the compiler with enough information, is to specify the\ngeneric type parameter:\n\n```\nlet x = \"hello\".chars().rev().collect::>();\n```\n\nAgain, you need not specify the full type if the compiler can infer it:\n\n```\nlet x = \"hello\".chars().rev().collect::>();\n```\n\nApart from a method or function with a generic type parameter, this error can\noccur when a type parameter of a struct or trait cannot be inferred. In that\ncase it is not always possible to use a type annotation, because all candidates\nhave the same return type. For instance:\n\n```compile_fail,E0282\nstruct Foo {\n num: T,\n}\n\nimpl Foo {\n fn bar() -> i32 {\n 0\n }\n\n fn baz() {\n let number = Foo::bar();\n }\n}\n```\n\nThis will fail because the compiler does not know which instance of `Foo` to\ncall `bar` on. Change `Foo::bar()` to `Foo::::bar()` to resolve the error.\n" 6 | }, 7 | "level": "error", 8 | "message": "type annotations needed", 9 | "rendered": "error[E0282]: type annotations needed\n --> src/lib.rs:141:17\n |\n141 | let v = Vec::new();\n | - ^^^^^^^^ cannot infer type for `T`\n | |\n | consider giving `v` a type\n\n", 10 | "spans": [{ 11 | "byte_end": 4162, 12 | "byte_start": 4154, 13 | "column_end": 25, 14 | "column_start": 17, 15 | "expansion": null, 16 | "file_name": "src/lib.rs", 17 | "is_primary": true, 18 | "label": "cannot infer type for `T`", 19 | "line_end": 141, 20 | "line_start": 141, 21 | "suggested_replacement": null, 22 | "text": [{ 23 | "highlight_end": 25, 24 | "highlight_start": 17, 25 | "text": " let v = Vec::new();" 26 | }] 27 | }, { 28 | "byte_end": 4151, 29 | "byte_start": 4150, 30 | "column_end": 14, 31 | "column_start": 13, 32 | "expansion": null, 33 | "file_name": "src/lib.rs", 34 | "is_primary": false, 35 | "label": "consider giving `v` a type", 36 | "line_end": 141, 37 | "line_start": 141, 38 | "suggested_replacement": null, 39 | "text": [{ 40 | "highlight_end": 14, 41 | "highlight_start": 13, 42 | "text": " let v = Vec::new();" 43 | }] 44 | }] 45 | } 46 | -------------------------------------------------------------------------------- /tests/fixtures/compiler_message/unused-use.json: -------------------------------------------------------------------------------- 1 | { 2 | "children": [{ 3 | "children": [], 4 | "code": null, 5 | "level": "note", 6 | "message": "#[warn(unused_imports)] on by default", 7 | "rendered": null, 8 | "spans": [] 9 | }], 10 | "code": { 11 | "code": "unused_imports", 12 | "explanation": null 13 | }, 14 | "level": "warning", 15 | "message": "unused imports: `f64`, `u64`, `u8 as Foo`", 16 | "rendered": "warning: unused imports: `f64`, `u64`, `u8 as Foo`\n --> src/main.rs:1:11\n |\n1 | use std::{f64, u64, u8 as Foo};\n | ^^^ ^^^ ^^^^^^^^^\n |\n = note: #[warn(unused_imports)] on by default\n\n", 17 | "spans": [{ 18 | "byte_end": 13, 19 | "byte_start": 10, 20 | "column_end": 14, 21 | "column_start": 11, 22 | "expansion": null, 23 | "file_name": "src/main.rs", 24 | "is_primary": true, 25 | "label": null, 26 | "line_end": 1, 27 | "line_start": 1, 28 | "suggested_replacement": null, 29 | "text": [{ 30 | "highlight_end": 14, 31 | "highlight_start": 11, 32 | "text": "use std::{f64, u64, u8 as Foo};" 33 | }] 34 | }, { 35 | "byte_end": 18, 36 | "byte_start": 15, 37 | "column_end": 19, 38 | "column_start": 16, 39 | "expansion": null, 40 | "file_name": "src/main.rs", 41 | "is_primary": true, 42 | "label": null, 43 | "line_end": 1, 44 | "line_start": 1, 45 | "suggested_replacement": null, 46 | "text": [{ 47 | "highlight_end": 19, 48 | "highlight_start": 16, 49 | "text": "use std::{f64, u64, u8 as Foo};" 50 | }] 51 | }, { 52 | "byte_end": 29, 53 | "byte_start": 20, 54 | "column_end": 30, 55 | "column_start": 21, 56 | "expansion": null, 57 | "file_name": "src/main.rs", 58 | "is_primary": true, 59 | "label": null, 60 | "line_end": 1, 61 | "line_start": 1, 62 | "suggested_replacement": null, 63 | "text": [{ 64 | "highlight_end": 30, 65 | "highlight_start": 21, 66 | "text": "use std::{f64, u64, u8 as Foo};" 67 | }] 68 | }] 69 | } 70 | -------------------------------------------------------------------------------- /tests/fixtures/deglob/Cargo.lock: -------------------------------------------------------------------------------- 1 | [[package]] 2 | name = "deglob" 3 | version = "0.1.0" 4 | 5 | -------------------------------------------------------------------------------- /tests/fixtures/deglob/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "deglob" 3 | version = "0.1.0" 4 | authors = ["Nick Cameron "] 5 | 6 | [dependencies] 7 | -------------------------------------------------------------------------------- /tests/fixtures/deglob/src/main.rs: -------------------------------------------------------------------------------- 1 | // single wildcard import 2 | // imports two values 3 | use std::io::*; 4 | 5 | // multiple wildcard imports 6 | use std::mem::*; use std::cmp::*; 7 | 8 | pub fn main() { 9 | size_of::(); 10 | size_of::(); 11 | size_of::(); 12 | max(1, 2); 13 | } 14 | -------------------------------------------------------------------------------- /tests/fixtures/dep_fail/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "dep_fail" 3 | version = "0.1.0" 4 | authors = ["Nick Cameron "] 5 | 6 | [dependencies] 7 | compile_fail = { path = "../compile_fail" } 8 | -------------------------------------------------------------------------------- /tests/fixtures/dep_fail/src/main.rs: -------------------------------------------------------------------------------- 1 | extern crate compile_fail; 2 | 3 | fn main() { 4 | compile_fail::foo(); 5 | } 6 | -------------------------------------------------------------------------------- /tests/fixtures/features/Cargo.lock: -------------------------------------------------------------------------------- 1 | [[package]] 2 | name = "features" 3 | version = "0.1.0" 4 | 5 | -------------------------------------------------------------------------------- /tests/fixtures/features/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "features" 3 | version = "0.1.0" 4 | authors = ["Bastien Orivel "] 5 | 6 | [features] 7 | default = ["baz"] 8 | foo = [] 9 | bar = [] 10 | baz = [] 11 | -------------------------------------------------------------------------------- /tests/fixtures/features/src/main.rs: -------------------------------------------------------------------------------- 1 | #[cfg(feature = "foo")] 2 | pub struct Foo; 3 | 4 | #[cfg(feature = "bar")] 5 | pub struct Bar; 6 | 7 | #[cfg(feature = "baz")] 8 | pub struct Baz; 9 | 10 | fn main() { 11 | Foo {}; 12 | Bar {}; 13 | Baz {}; 14 | } 15 | -------------------------------------------------------------------------------- /tests/fixtures/find_all_refs_no_cfg_test/Cargo.lock: -------------------------------------------------------------------------------- 1 | [[package]] 2 | name = "find_all_refs_no_cfg_test" 3 | version = "0.1.0" 4 | 5 | -------------------------------------------------------------------------------- /tests/fixtures/find_all_refs_no_cfg_test/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "find_all_refs_no_cfg_test" 3 | version = "0.1.0" 4 | authors = ["Nick Cameron "] 5 | 6 | [dependencies] 7 | -------------------------------------------------------------------------------- /tests/fixtures/find_all_refs_no_cfg_test/src/main.rs: -------------------------------------------------------------------------------- 1 | struct Bar { 2 | x: u64, 3 | } 4 | 5 | #[test] 6 | struct Bar { 7 | x: u64, 8 | } 9 | 10 | pub fn main() { 11 | let world = "world"; 12 | println!("Hello, {}!", world); 13 | 14 | let bar2 = Bar { x: 5 }; 15 | println!("bar2: {}", bar2.x); 16 | } 17 | -------------------------------------------------------------------------------- /tests/fixtures/find_impls/Cargo.lock: -------------------------------------------------------------------------------- 1 | [[package]] 2 | name = "find_impls" 3 | version = "0.1.0" 4 | 5 | -------------------------------------------------------------------------------- /tests/fixtures/find_impls/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "find_impls" 3 | version = "0.1.0" 4 | authors = ["Jonas Bushart "] 5 | 6 | [dependencies] 7 | -------------------------------------------------------------------------------- /tests/fixtures/find_impls/src/main.rs: -------------------------------------------------------------------------------- 1 | #![allow(dead_code)] 2 | 3 | #[derive(PartialEq)] 4 | struct Bar; 5 | struct Foo; 6 | 7 | trait Super{} 8 | trait Sub: Super {} 9 | 10 | impl Super for Bar {} 11 | impl Eq for Bar {} 12 | 13 | impl Sub for Foo {} 14 | impl Super for Foo {} 15 | -------------------------------------------------------------------------------- /tests/fixtures/hover/Cargo.lock: -------------------------------------------------------------------------------- 1 | [[package]] 2 | name = "fnv" 3 | version = "1.0.6" 4 | source = "registry+https://github.com/rust-lang/crates.io-index" 5 | 6 | [[package]] 7 | name = "hover" 8 | version = "0.1.0" 9 | dependencies = [ 10 | "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", 11 | ] 12 | 13 | [metadata] 14 | "checksum fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2fad85553e09a6f881f739c29f0b00b0f01357c743266d478b68951ce23285f3" 15 | -------------------------------------------------------------------------------- /tests/fixtures/hover/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "hover" 3 | version = "0.1.0" 4 | authors = ["hover "] 5 | 6 | [dependencies] 7 | fnv = "1.0.6" -------------------------------------------------------------------------------- /tests/fixtures/hover/save_data/test_tooltip_01.rs.0003_011.json: -------------------------------------------------------------------------------- 1 | { 2 | "test": { 3 | "file": "test_tooltip_01.rs", 4 | "line": 3, 5 | "col": 11 6 | }, 7 | "data": { 8 | "Ok": [ 9 | { 10 | "language": "rust", 11 | "value": "pub enum Foo" 12 | }, 13 | "Foo enum" 14 | ] 15 | } 16 | } -------------------------------------------------------------------------------- /tests/fixtures/hover/save_data/test_tooltip_01.rs.0005_007.json: -------------------------------------------------------------------------------- 1 | { 2 | "test": { 3 | "file": "test_tooltip_01.rs", 4 | "line": 5, 5 | "col": 7 6 | }, 7 | "data": { 8 | "Ok": [ 9 | { 10 | "language": "rust", 11 | "value": "Foo::Bar" 12 | }, 13 | "Bar variant" 14 | ] 15 | } 16 | } -------------------------------------------------------------------------------- /tests/fixtures/hover/save_data/test_tooltip_01.rs.0007_007.json: -------------------------------------------------------------------------------- 1 | { 2 | "test": { 3 | "file": "test_tooltip_01.rs", 4 | "line": 7, 5 | "col": 7 6 | }, 7 | "data": { 8 | "Ok": [ 9 | { 10 | "language": "rust", 11 | "value": "Foo::Baz" 12 | }, 13 | "Baz variant" 14 | ] 15 | } 16 | } -------------------------------------------------------------------------------- /tests/fixtures/hover/save_data/test_tooltip_01.rs.0011_013.json: -------------------------------------------------------------------------------- 1 | { 2 | "test": { 3 | "file": "test_tooltip_01.rs", 4 | "line": 11, 5 | "col": 13 6 | }, 7 | "data": { 8 | "Ok": [ 9 | { 10 | "language": "rust", 11 | "value": "pub struct Bar" 12 | }, 13 | "Bar struct" 14 | ] 15 | } 16 | } -------------------------------------------------------------------------------- /tests/fixtures/hover/save_data/test_tooltip_01.rs.0013_009.json: -------------------------------------------------------------------------------- 1 | { 2 | "test": { 3 | "file": "test_tooltip_01.rs", 4 | "line": 13, 5 | "col": 9 6 | }, 7 | "data": { 8 | "Ok": [ 9 | { 10 | "language": "rust", 11 | "value": "test_tooltip_01::Tuple" 12 | }, 13 | "The first field" 14 | ] 15 | } 16 | } -------------------------------------------------------------------------------- /tests/fixtures/hover/save_data/test_tooltip_01.rs.0013_016.json: -------------------------------------------------------------------------------- 1 | { 2 | "test": { 3 | "file": "test_tooltip_01.rs", 4 | "line": 13, 5 | "col": 16 6 | }, 7 | "data": { 8 | "Ok": [ 9 | { 10 | "language": "rust", 11 | "value": "pub struct Tuple(pub u32, _)" 12 | }, 13 | "Tuple struct" 14 | ] 15 | } 16 | } -------------------------------------------------------------------------------- /tests/fixtures/hover/save_data/test_tooltip_01.rs.0015_008.json: -------------------------------------------------------------------------------- 1 | { 2 | "test": { 3 | "file": "test_tooltip_01.rs", 4 | "line": 15, 5 | "col": 8 6 | }, 7 | "data": { 8 | "Ok": [ 9 | { 10 | "language": "rust", 11 | "value": "T" 12 | }, 13 | "The second field" 14 | ] 15 | } 16 | } -------------------------------------------------------------------------------- /tests/fixtures/hover/save_data/test_tooltip_01.rs.0017_008.json: -------------------------------------------------------------------------------- 1 | { 2 | "test": { 3 | "file": "test_tooltip_01.rs", 4 | "line": 17, 5 | "col": 8 6 | }, 7 | "data": { 8 | "Ok": [ 9 | { 10 | "language": "rust", 11 | "value": "test_tooltip_01::Foo" 12 | }, 13 | "The third field" 14 | ] 15 | } 16 | } -------------------------------------------------------------------------------- /tests/fixtures/hover/save_data/test_tooltip_01.rs.0020_011.json: -------------------------------------------------------------------------------- 1 | { 2 | "test": { 3 | "file": "test_tooltip_01.rs", 4 | "line": 20, 5 | "col": 11 6 | }, 7 | "data": { 8 | "Ok": [ 9 | { 10 | "language": "rust", 11 | "value": "pub struct Bar" 12 | }, 13 | "Bar struct" 14 | ] 15 | } 16 | } -------------------------------------------------------------------------------- /tests/fixtures/hover/save_data/test_tooltip_01.rs.0022_010.json: -------------------------------------------------------------------------------- 1 | { 2 | "test": { 3 | "file": "test_tooltip_01.rs", 4 | "line": 22, 5 | "col": 10 6 | }, 7 | "data": { 8 | "Ok": [ 9 | { 10 | "language": "rust", 11 | "value": "fn new(one: Tuple, two: T, three: Foo) -> Bar" 12 | }, 13 | "Create a new Bar" 14 | ] 15 | } 16 | } -------------------------------------------------------------------------------- /tests/fixtures/hover/save_data/test_tooltip_01.rs.0022_019.json: -------------------------------------------------------------------------------- 1 | { 2 | "test": { 3 | "file": "test_tooltip_01.rs", 4 | "line": 22, 5 | "col": 19 6 | }, 7 | "data": { 8 | "Ok": [ 9 | { 10 | "language": "rust", 11 | "value": "pub struct Tuple(pub u32, _)" 12 | }, 13 | "Tuple struct" 14 | ] 15 | } 16 | } -------------------------------------------------------------------------------- /tests/fixtures/hover/save_data/test_tooltip_01.rs.0022_026.json: -------------------------------------------------------------------------------- 1 | { 2 | "test": { 3 | "file": "test_tooltip_01.rs", 4 | "line": 22, 5 | "col": 26 6 | }, 7 | "data": { 8 | "Ok": [ 9 | { 10 | "language": "rust", 11 | "value": "T" 12 | } 13 | ] 14 | } 15 | } -------------------------------------------------------------------------------- /tests/fixtures/hover/save_data/test_tooltip_01.rs.0022_035.json: -------------------------------------------------------------------------------- 1 | { 2 | "test": { 3 | "file": "test_tooltip_01.rs", 4 | "line": 22, 5 | "col": 35 6 | }, 7 | "data": { 8 | "Ok": [ 9 | { 10 | "language": "rust", 11 | "value": "test_tooltip_01::Foo" 12 | } 13 | ] 14 | } 15 | } -------------------------------------------------------------------------------- /tests/fixtures/hover/save_data/test_tooltip_01.rs.0022_049.json: -------------------------------------------------------------------------------- 1 | { 2 | "test": { 3 | "file": "test_tooltip_01.rs", 4 | "line": 22, 5 | "col": 49 6 | }, 7 | "data": { 8 | "Ok": [ 9 | { 10 | "language": "rust", 11 | "value": "pub struct Bar" 12 | }, 13 | "Bar struct" 14 | ] 15 | } 16 | } -------------------------------------------------------------------------------- /tests/fixtures/hover/save_data/test_tooltip_01.rs.0023_011.json: -------------------------------------------------------------------------------- 1 | { 2 | "test": { 3 | "file": "test_tooltip_01.rs", 4 | "line": 23, 5 | "col": 11 6 | }, 7 | "data": { 8 | "Ok": [ 9 | { 10 | "language": "rust", 11 | "value": "pub struct Bar" 12 | }, 13 | "Bar struct" 14 | ] 15 | } 16 | } -------------------------------------------------------------------------------- /tests/fixtures/hover/save_data/test_tooltip_01.rs.0024_016.json: -------------------------------------------------------------------------------- 1 | { 2 | "test": { 3 | "file": "test_tooltip_01.rs", 4 | "line": 24, 5 | "col": 16 6 | }, 7 | "data": { 8 | "Ok": [ 9 | { 10 | "language": "rust", 11 | "value": "test_tooltip_01::Tuple" 12 | }, 13 | "The first field" 14 | ] 15 | } 16 | } -------------------------------------------------------------------------------- /tests/fixtures/hover/save_data/test_tooltip_01.rs.0024_023.json: -------------------------------------------------------------------------------- 1 | { 2 | "test": { 3 | "file": "test_tooltip_01.rs", 4 | "line": 24, 5 | "col": 23 6 | }, 7 | "data": { 8 | "Ok": [ 9 | { 10 | "language": "rust", 11 | "value": "test_tooltip_01::Tuple" 12 | } 13 | ] 14 | } 15 | } -------------------------------------------------------------------------------- /tests/fixtures/hover/save_data/test_tooltip_01.rs.0025_016.json: -------------------------------------------------------------------------------- 1 | { 2 | "test": { 3 | "file": "test_tooltip_01.rs", 4 | "line": 25, 5 | "col": 16 6 | }, 7 | "data": { 8 | "Ok": [ 9 | { 10 | "language": "rust", 11 | "value": "T" 12 | }, 13 | "The second field" 14 | ] 15 | } 16 | } -------------------------------------------------------------------------------- /tests/fixtures/hover/save_data/test_tooltip_01.rs.0025_023.json: -------------------------------------------------------------------------------- 1 | { 2 | "test": { 3 | "file": "test_tooltip_01.rs", 4 | "line": 25, 5 | "col": 23 6 | }, 7 | "data": { 8 | "Ok": [ 9 | { 10 | "language": "rust", 11 | "value": "T" 12 | } 13 | ] 14 | } 15 | } -------------------------------------------------------------------------------- /tests/fixtures/hover/save_data/test_tooltip_01.rs.0026_016.json: -------------------------------------------------------------------------------- 1 | { 2 | "test": { 3 | "file": "test_tooltip_01.rs", 4 | "line": 26, 5 | "col": 16 6 | }, 7 | "data": { 8 | "Ok": [ 9 | { 10 | "language": "rust", 11 | "value": "test_tooltip_01::Foo" 12 | }, 13 | "The third field" 14 | ] 15 | } 16 | } -------------------------------------------------------------------------------- /tests/fixtures/hover/save_data/test_tooltip_01.rs.0026_023.json: -------------------------------------------------------------------------------- 1 | { 2 | "test": { 3 | "file": "test_tooltip_01.rs", 4 | "line": 26, 5 | "col": 23 6 | }, 7 | "data": { 8 | "Ok": [ 9 | { 10 | "language": "rust", 11 | "value": "test_tooltip_01::Foo" 12 | } 13 | ] 14 | } 15 | } -------------------------------------------------------------------------------- /tests/fixtures/hover/save_data/test_tooltip_01.rs.0032_015.json: -------------------------------------------------------------------------------- 1 | { 2 | "test": { 3 | "file": "test_tooltip_01.rs", 4 | "line": 32, 5 | "col": 15 6 | }, 7 | "data": { 8 | "Ok": [ 9 | { 10 | "language": "rust", 11 | "value": "pub struct Tuple(pub u32, _)" 12 | }, 13 | "Tuple struct" 14 | ] 15 | } 16 | } -------------------------------------------------------------------------------- /tests/fixtures/hover/save_data/test_tooltip_01.rs.0046_006.json: -------------------------------------------------------------------------------- 1 | { 2 | "test": { 3 | "file": "test_tooltip_01.rs", 4 | "line": 46, 5 | "col": 6 6 | }, 7 | "data": { 8 | "Ok": [ 9 | { 10 | "language": "rust", 11 | "value": "fn bar(thing: T) -> Bar" 12 | }, 13 | "Bar function\n\n# Examples\n\n```rust\nuse does_not_exist::other;\n\nlet foo = bar(1.0);\nother(foo);\n```" 14 | ] 15 | } 16 | } -------------------------------------------------------------------------------- /tests/fixtures/hover/save_data/test_tooltip_01.rs.0056_006.json: -------------------------------------------------------------------------------- 1 | { 2 | "test": { 3 | "file": "test_tooltip_01.rs", 4 | "line": 56, 5 | "col": 6 6 | }, 7 | "data": { 8 | "Ok": [] 9 | } 10 | } -------------------------------------------------------------------------------- /tests/fixtures/hover/save_data/test_tooltip_01.rs.0057_030.json: -------------------------------------------------------------------------------- 1 | { 2 | "test": { 3 | "file": "test_tooltip_01.rs", 4 | "line": 57, 5 | "col": 30 6 | }, 7 | "data": { 8 | "Ok": [ 9 | { 10 | "language": "rust", 11 | "value": "test_tooltip_01::Foo" 12 | }, 13 | "The third field" 14 | ] 15 | } 16 | } -------------------------------------------------------------------------------- /tests/fixtures/hover/save_data/test_tooltip_01.rs.0058_011.json: -------------------------------------------------------------------------------- 1 | { 2 | "test": { 3 | "file": "test_tooltip_01.rs", 4 | "line": 58, 5 | "col": 11 6 | }, 7 | "data": { 8 | "Ok": [ 9 | { 10 | "language": "rust", 11 | "value": "&mut test_tooltip_01::Bar" 12 | } 13 | ] 14 | } 15 | } -------------------------------------------------------------------------------- /tests/fixtures/hover/save_data/test_tooltip_01.rs.0058_026.json: -------------------------------------------------------------------------------- 1 | { 2 | "test": { 3 | "file": "test_tooltip_01.rs", 4 | "line": 58, 5 | "col": 26 6 | }, 7 | "data": { 8 | "Ok": [ 9 | { 10 | "language": "rust", 11 | "value": "test_tooltip_01::Foo" 12 | } 13 | ] 14 | } 15 | } -------------------------------------------------------------------------------- /tests/fixtures/hover/save_data/test_tooltip_01.rs.0065_010.json: -------------------------------------------------------------------------------- 1 | { 2 | "test": { 3 | "file": "test_tooltip_01.rs", 4 | "line": 65, 5 | "col": 10 6 | }, 7 | "data": { 8 | "Ok": [ 9 | { 10 | "language": "rust", 11 | "value": "fn bar(thing: T) -> Bar" 12 | }, 13 | "Bar function\n\n# Examples\n\n```rust\nuse does_not_exist::other;\n\nlet foo = bar(1.0);\nother(foo);\n```" 14 | ] 15 | } 16 | } -------------------------------------------------------------------------------- /tests/fixtures/hover/save_data/test_tooltip_01.rs.0070_011.json: -------------------------------------------------------------------------------- 1 | { 2 | "test": { 3 | "file": "test_tooltip_01.rs", 4 | "line": 70, 5 | "col": 11 6 | }, 7 | "data": { 8 | "Ok": [ 9 | { 10 | "language": "rust", 11 | "value": "pub struct Bar" 12 | }, 13 | "Bar struct" 14 | ] 15 | } 16 | } -------------------------------------------------------------------------------- /tests/fixtures/hover/save_data/test_tooltip_01.rs.0075_014.json: -------------------------------------------------------------------------------- 1 | { 2 | "test": { 3 | "file": "test_tooltip_01.rs", 4 | "line": 75, 5 | "col": 14 6 | }, 7 | "data": { 8 | "Ok": [ 9 | { 10 | "language": "rust", 11 | "value": "test_tooltip_01::Bar" 12 | } 13 | ] 14 | } 15 | } -------------------------------------------------------------------------------- /tests/fixtures/hover/save_data/test_tooltip_01.rs.0075_050.json: -------------------------------------------------------------------------------- 1 | { 2 | "test": { 3 | "file": "test_tooltip_01.rs", 4 | "line": 75, 5 | "col": 50 6 | }, 7 | "data": { 8 | "Ok": [ 9 | { 10 | "language": "rust", 11 | "value": "pub enum Foo" 12 | }, 13 | "Foo enum" 14 | ] 15 | } 16 | } -------------------------------------------------------------------------------- /tests/fixtures/hover/save_data/test_tooltip_01.rs.0075_054.json: -------------------------------------------------------------------------------- 1 | { 2 | "test": { 3 | "file": "test_tooltip_01.rs", 4 | "line": 75, 5 | "col": 54 6 | }, 7 | "data": { 8 | "Ok": [ 9 | { 10 | "language": "rust", 11 | "value": "Foo::Bar" 12 | }, 13 | "Bar variant" 14 | ] 15 | } 16 | } -------------------------------------------------------------------------------- /tests/fixtures/hover/save_data/test_tooltip_01.rs.0076_007.json: -------------------------------------------------------------------------------- 1 | { 2 | "test": { 3 | "file": "test_tooltip_01.rs", 4 | "line": 76, 5 | "col": 7 6 | }, 7 | "data": { 8 | "Ok": [ 9 | { 10 | "language": "rust", 11 | "value": "test_tooltip_01::Bar" 12 | }, 13 | { 14 | "language": "rust", 15 | "value": "let mut bar = Bar::new(Tuple(3, 1.0), 2.0, Foo::Bar);" 16 | } 17 | ] 18 | } 19 | } -------------------------------------------------------------------------------- /tests/fixtures/hover/save_data/test_tooltip_01.rs.0076_010.json: -------------------------------------------------------------------------------- 1 | { 2 | "test": { 3 | "file": "test_tooltip_01.rs", 4 | "line": 76, 5 | "col": 10 6 | }, 7 | "data": { 8 | "Ok": [ 9 | { 10 | "language": "rust", 11 | "value": "fn bar(&mut self, thing: T) -> Bar\nwhere\n T: Copy," 12 | }, 13 | "Bar method" 14 | ] 15 | } 16 | } -------------------------------------------------------------------------------- /tests/fixtures/hover/save_data/test_tooltip_01.rs.0077_020.json: -------------------------------------------------------------------------------- 1 | { 2 | "test": { 3 | "file": "test_tooltip_01.rs", 4 | "line": 77, 5 | "col": 20 6 | }, 7 | "data": { 8 | "Ok": [ 9 | { 10 | "language": "rust", 11 | "value": "Foo::Baz" 12 | }, 13 | "Baz variant" 14 | ] 15 | } 16 | } -------------------------------------------------------------------------------- /tests/fixtures/hover/save_data/test_tooltip_01.rs.0078_018.json: -------------------------------------------------------------------------------- 1 | { 2 | "test": { 3 | "file": "test_tooltip_01.rs", 4 | "line": 78, 5 | "col": 18 6 | }, 7 | "data": { 8 | "Ok": [ 9 | { 10 | "language": "rust", 11 | "value": "pub struct Tuple(pub u32, _)" 12 | }, 13 | "Tuple struct" 14 | ] 15 | } 16 | } -------------------------------------------------------------------------------- /tests/fixtures/hover/save_data/test_tooltip_01.rs.0083_011.json: -------------------------------------------------------------------------------- 1 | { 2 | "test": { 3 | "file": "test_tooltip_01.rs", 4 | "line": 83, 5 | "col": 11 6 | }, 7 | "data": { 8 | "Ok": [ 9 | { 10 | "language": "rust", 11 | "value": "type Foo: Other" 12 | }, 13 | "Foo other type" 14 | ] 15 | } 16 | } -------------------------------------------------------------------------------- /tests/fixtures/hover/save_data/test_tooltip_01.rs.0083_018.json: -------------------------------------------------------------------------------- 1 | { 2 | "test": { 3 | "file": "test_tooltip_01.rs", 4 | "line": 83, 5 | "col": 18 6 | }, 7 | "data": { 8 | "Ok": [ 9 | { 10 | "language": "rust", 11 | "value": "trait Other" 12 | }, 13 | "The other trait" 14 | ] 15 | } 16 | } -------------------------------------------------------------------------------- /tests/fixtures/hover/save_data/test_tooltip_01.rs.0085_025.json: -------------------------------------------------------------------------------- 1 | { 2 | "test": { 3 | "file": "test_tooltip_01.rs", 4 | "line": 85, 5 | "col": 25 6 | }, 7 | "data": { 8 | "Ok": [ 9 | { 10 | "language": "rust", 11 | "value": "type Foo: Other" 12 | }, 13 | "Foo other type" 14 | ] 15 | } 16 | } -------------------------------------------------------------------------------- /tests/fixtures/hover/save_data/test_tooltip_01.rs.0099_021.json: -------------------------------------------------------------------------------- 1 | { 2 | "test": { 3 | "file": "test_tooltip_01.rs", 4 | "line": 99, 5 | "col": 21 6 | }, 7 | "data": { 8 | "Ok": [ 9 | { 10 | "language": "rust", 11 | "value": "const FOO: &'static str = \"FOO\"" 12 | }, 13 | "The constant FOO" 14 | ] 15 | } 16 | } -------------------------------------------------------------------------------- /tests/fixtures/hover/save_data/test_tooltip_01.rs.0103_021.json: -------------------------------------------------------------------------------- 1 | { 2 | "test": { 3 | "file": "test_tooltip_01.rs", 4 | "line": 103, 5 | "col": 21 6 | }, 7 | "data": { 8 | "Ok": [ 9 | { 10 | "language": "rust", 11 | "value": "static BAR: u32 = 123" 12 | }, 13 | "The static BAR" 14 | ] 15 | } 16 | } -------------------------------------------------------------------------------- /tests/fixtures/hover/save_data/test_tooltip_mod.rs.0012_014.json: -------------------------------------------------------------------------------- 1 | { 2 | "test": { 3 | "file": "test_tooltip_mod.rs", 4 | "line": 12, 5 | "col": 14 6 | }, 7 | "data": { 8 | "Ok": [ 9 | { 10 | "language": "rust", 11 | "value": "pub struct First" 12 | }, 13 | "Begin first item docs\n\nThe first item docs should not pick up the module docs." 14 | ] 15 | } 16 | } -------------------------------------------------------------------------------- /tests/fixtures/hover/save_data/test_tooltip_mod_use.rs.0001_014.json: -------------------------------------------------------------------------------- 1 | { 2 | "test": { 3 | "file": "test_tooltip_mod_use.rs", 4 | "line": 1, 5 | "col": 14 6 | }, 7 | "data": { 8 | "Ok": [ 9 | { 10 | "language": "rust", 11 | "value": "src/test_tooltip_mod.rs" 12 | }, 13 | "Begin module docs\n\nLorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas\ntincidunt tristique maximus. Sed venenatis urna vel sagittis tempus.\nIn hac habitasse platea dictumst.\n\nEnd module docs." 14 | ] 15 | } 16 | } -------------------------------------------------------------------------------- /tests/fixtures/hover/save_data/test_tooltip_mod_use.rs.0002_014.json: -------------------------------------------------------------------------------- 1 | { 2 | "test": { 3 | "file": "test_tooltip_mod_use.rs", 4 | "line": 2, 5 | "col": 14 6 | }, 7 | "data": { 8 | "Ok": [ 9 | { 10 | "language": "rust", 11 | "value": "src/test_tooltip_mod.rs" 12 | }, 13 | "Begin module docs\n\nLorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas\ntincidunt tristique maximus. Sed venenatis urna vel sagittis tempus.\nIn hac habitasse platea dictumst.\n\nEnd module docs." 14 | ] 15 | } 16 | } -------------------------------------------------------------------------------- /tests/fixtures/hover/save_data/test_tooltip_mod_use.rs.0002_025.json: -------------------------------------------------------------------------------- 1 | { 2 | "test": { 3 | "file": "test_tooltip_mod_use.rs", 4 | "line": 2, 5 | "col": 25 6 | }, 7 | "data": { 8 | "Ok": [ 9 | { 10 | "language": "rust", 11 | "value": "pub struct First" 12 | }, 13 | "Begin first item docs\n\nThe first item docs should not pick up the module docs." 14 | ] 15 | } 16 | } -------------------------------------------------------------------------------- /tests/fixtures/hover/save_data/test_tooltip_mod_use.rs.0003_028.json: -------------------------------------------------------------------------------- 1 | { 2 | "test": { 3 | "file": "test_tooltip_mod_use.rs", 4 | "line": 3, 5 | "col": 28 6 | }, 7 | "data": { 8 | "Ok": [ 9 | { 10 | "language": "rust", 11 | "value": "src/test_tooltip_mod.rs" 12 | }, 13 | "Submodule first line\n\nMauris vel lobortis lacus, in condimentum dolor.\n\nSubmodule last line" 14 | ] 15 | } 16 | } -------------------------------------------------------------------------------- /tests/fixtures/hover/save_data/test_tooltip_mod_use_external.rs.0001_007.json: -------------------------------------------------------------------------------- 1 | { 2 | "test": { 3 | "file": "test_tooltip_mod_use_external.rs", 4 | "line": 1, 5 | "col": 7 6 | }, 7 | "data": { 8 | "Ok": [ 9 | { 10 | "language": "rust", 11 | "value": "fnv-1.0.6/lib.rs" 12 | }, 13 | "An implementation of the [Fowler–Noll–Vo hash function][chongo].\n\n## About\n\nThe FNV hash function is a custom `Hasher` implementation that is more\nefficient for smaller hash keys.\n\n[The Rust FAQ states that][faq] while the default `Hasher` implementation,\nSipHash, is good in many cases, it is notably slower than other algorithms\nwith short keys, such as when you have a map of integers to other values.\nIn cases like these, [FNV is demonstrably faster][graphs].\n\nIts disadvantages are that it performs badly on larger inputs, and\nprovides no protection against collision attacks, where a malicious user\ncan craft specific keys designed to slow a hasher down. Thus, it is\nimportant to profile your program to ensure that you are using small hash\nkeys, and be certain that your program could not be exposed to malicious\ninputs (including being a networked server).\n\nThe Rust compiler itself uses FNV, as it is not worried about\ndenial-of-service attacks, and can assume that its inputs are going to be\nsmall—a perfect use case for FNV.\n\n\n## Using FNV in a `HashMap`\n\nThe `FnvHashMap` type alias is the easiest way to use the standard library’s\n`HashMap` with FNV.\n\n```rust\nuse fnv::FnvHashMap;\n\nlet mut map = FnvHashMap::default();\nmap.insert(1, \"one\");\nmap.insert(2, \"two\");\n\nmap = FnvHashMap::with_capacity_and_hasher(10, Default::default());\nmap.insert(1, \"one\");\nmap.insert(2, \"two\");\n```\n\nNote, the standard library’s `HashMap::new` and `HashMap::with_capacity`\nare only implemented for the `RandomState` hasher, so using `Default` to\nget the hasher is the next best option.\n\n## Using FNV in a `HashSet`\n\nSimilarly, `FnvHashSet` is a type alias for the standard library’s `HashSet`\nwith FNV.\n\n```rust\nuse fnv::FnvHashSet;\n\nlet mut set = FnvHashSet::default();\nset.insert(1);\nset.insert(2);\n\nset = FnvHashSet::with_capacity_and_hasher(10, Default::default());\nset.insert(1);\nset.insert(2);\n```\n\n[chongo]: http://www.isthe.com/chongo/tech/comp/fnv/index.html\n[faq]: https://www.rust-lang.org/en-US/faq.html#why-are-rusts-hashmaps-slow\n[graphs]: http://cglab.ca/~abeinges/blah/hash-rs/" 14 | ] 15 | } 16 | } -------------------------------------------------------------------------------- /tests/fixtures/hover/save_data/test_tooltip_mod_use_external.rs.0002_007.json: -------------------------------------------------------------------------------- 1 | { 2 | "test": { 3 | "file": "test_tooltip_mod_use_external.rs", 4 | "line": 2, 5 | "col": 7 6 | }, 7 | "data": { 8 | "Ok": [ 9 | { 10 | "language": "rust", 11 | "value": "fnv-1.0.6/lib.rs" 12 | }, 13 | "An implementation of the [Fowler–Noll–Vo hash function][chongo].\n\n## About\n\nThe FNV hash function is a custom `Hasher` implementation that is more\nefficient for smaller hash keys.\n\n[The Rust FAQ states that][faq] while the default `Hasher` implementation,\nSipHash, is good in many cases, it is notably slower than other algorithms\nwith short keys, such as when you have a map of integers to other values.\nIn cases like these, [FNV is demonstrably faster][graphs].\n\nIts disadvantages are that it performs badly on larger inputs, and\nprovides no protection against collision attacks, where a malicious user\ncan craft specific keys designed to slow a hasher down. Thus, it is\nimportant to profile your program to ensure that you are using small hash\nkeys, and be certain that your program could not be exposed to malicious\ninputs (including being a networked server).\n\nThe Rust compiler itself uses FNV, as it is not worried about\ndenial-of-service attacks, and can assume that its inputs are going to be\nsmall—a perfect use case for FNV.\n\n\n## Using FNV in a `HashMap`\n\nThe `FnvHashMap` type alias is the easiest way to use the standard library’s\n`HashMap` with FNV.\n\n```rust\nuse fnv::FnvHashMap;\n\nlet mut map = FnvHashMap::default();\nmap.insert(1, \"one\");\nmap.insert(2, \"two\");\n\nmap = FnvHashMap::with_capacity_and_hasher(10, Default::default());\nmap.insert(1, \"one\");\nmap.insert(2, \"two\");\n```\n\nNote, the standard library’s `HashMap::new` and `HashMap::with_capacity`\nare only implemented for the `RandomState` hasher, so using `Default` to\nget the hasher is the next best option.\n\n## Using FNV in a `HashSet`\n\nSimilarly, `FnvHashSet` is a type alias for the standard library’s `HashSet`\nwith FNV.\n\n```rust\nuse fnv::FnvHashSet;\n\nlet mut set = FnvHashSet::default();\nset.insert(1);\nset.insert(2);\n\nset = FnvHashSet::with_capacity_and_hasher(10, Default::default());\nset.insert(1);\nset.insert(2);\n```\n\n[chongo]: http://www.isthe.com/chongo/tech/comp/fnv/index.html\n[faq]: https://www.rust-lang.org/en-US/faq.html#why-are-rusts-hashmaps-slow\n[graphs]: http://cglab.ca/~abeinges/blah/hash-rs/" 14 | ] 15 | } 16 | } -------------------------------------------------------------------------------- /tests/fixtures/hover/save_data/test_tooltip_mod_use_external.rs.0002_012.json: -------------------------------------------------------------------------------- 1 | { 2 | "test": { 3 | "file": "test_tooltip_mod_use_external.rs", 4 | "line": 2, 5 | "col": 12 6 | }, 7 | "data": { 8 | "Ok": [ 9 | { 10 | "language": "rust", 11 | "value": "pub struct FnvHasher" 12 | }, 13 | "An implementation of the Fowler–Noll–Vo hash function.\n\nSee the [crate documentation](index.html) for more details." 14 | ] 15 | } 16 | } -------------------------------------------------------------------------------- /tests/fixtures/hover/save_data/test_tooltip_mod_use_external.rs.0004_012.json: -------------------------------------------------------------------------------- 1 | { 2 | "test": { 3 | "file": "test_tooltip_mod_use_external.rs", 4 | "line": 4, 5 | "col": 12 6 | }, 7 | "data": { 8 | "Ok": [ 9 | { 10 | "language": "rust", 11 | "value": "std/src/sync/mod.rs" 12 | }, 13 | "Useful synchronization primitives.\n\n## The need for synchronization\n\nConceptually, a Rust program is a series of operations which will\nbe executed on a computer. The timeline of events happening in the\nprogram is consistent with the order of the operations in the code.\n\nConsider the following code, operating on some global static variables:\n\n```rust\nstatic mut A: u32 = 0;" 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/fixtures/hover/save_data/test_tooltip_mod_use_external.rs.0005_012.json: -------------------------------------------------------------------------------- 1 | { 2 | "test": { 3 | "file": "test_tooltip_mod_use_external.rs", 4 | "line": 5, 5 | "col": 12 6 | }, 7 | "data": { 8 | "Ok": [ 9 | { 10 | "language": "rust", 11 | "value": "std/src/sync/mod.rs" 12 | }, 13 | "Useful synchronization primitives.\n\n## The need for synchronization\n\nConceptually, a Rust program is a series of operations which will\nbe executed on a computer. The timeline of events happening in the\nprogram is consistent with the order of the operations in the code.\n\nConsider the following code, operating on some global static variables:\n\n```rust\nstatic mut A: u32 = 0;" 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/fixtures/hover/save_data/test_tooltip_std.rs.0008_015.json: -------------------------------------------------------------------------------- 1 | { 2 | "test": { 3 | "file": "test_tooltip_std.rs", 4 | "line": 8, 5 | "col": 15 6 | }, 7 | "data": { 8 | "Ok": [ 9 | { 10 | "language": "rust", 11 | "value": "std::vec::Vec" 12 | } 13 | ] 14 | } 15 | } -------------------------------------------------------------------------------- /tests/fixtures/hover/save_data/test_tooltip_std.rs.0008_027.json: -------------------------------------------------------------------------------- 1 | { 2 | "test": { 3 | "file": "test_tooltip_std.rs", 4 | "line": 8, 5 | "col": 27 6 | }, 7 | "data": { 8 | "Ok": [ 9 | { 10 | "language": "rust", 11 | "value": "pub const fn new() -> Self" 12 | }, 13 | "Constructs a new, empty `Vec`.\n\nThe vector will not allocate until elements are pushed onto it.\n\n# Examples\n\n```rust\nlet mut vec: Vec = Vec::new();\n```" 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /tests/fixtures/hover/save_data/test_tooltip_std.rs.0009_007.json: -------------------------------------------------------------------------------- 1 | { 2 | "test": { 3 | "file": "test_tooltip_std.rs", 4 | "line": 9, 5 | "col": 7 6 | }, 7 | "data": { 8 | "Ok": [ 9 | { 10 | "language": "rust", 11 | "value": "std::vec::Vec" 12 | }, 13 | { 14 | "language": "rust", 15 | "value": "let mut vec1 = Vec::new();" 16 | } 17 | ] 18 | } 19 | } -------------------------------------------------------------------------------- /tests/fixtures/hover/save_data/test_tooltip_std.rs.0009_012.json: -------------------------------------------------------------------------------- 1 | { 2 | "test": { 3 | "file": "test_tooltip_std.rs", 4 | "line": 9, 5 | "col": 12 6 | }, 7 | "data": { 8 | "Ok": [ 9 | { 10 | "language": "rust", 11 | "value": "pub fn push(&mut self, value: T)" 12 | }, 13 | "Appends an element to the back of a collection.\n\n# Panics\n\nPanics if the new capacity exceeds `isize::MAX` bytes.\n\n# Examples\n\n```rust\nlet mut vec = vec![1, 2];\nvec.push(3);\nassert_eq!(vec, [1, 2, 3]);\n```" 14 | ] 15 | } 16 | } -------------------------------------------------------------------------------- /tests/fixtures/hover/save_data/test_tooltip_std.rs.0010_012.json: -------------------------------------------------------------------------------- 1 | { 2 | "test": { 3 | "file": "test_tooltip_std.rs", 4 | "line": 10, 5 | "col": 12 6 | }, 7 | "data": { 8 | "Ok": [ 9 | { 10 | "language": "rust", 11 | "value": "&[i32]" 12 | } 13 | ] 14 | } 15 | } -------------------------------------------------------------------------------- /tests/fixtures/hover/save_data/test_tooltip_std.rs.0010_020.json: -------------------------------------------------------------------------------- 1 | { 2 | "test": { 3 | "file": "test_tooltip_std.rs", 4 | "line": 10, 5 | "col": 20 6 | }, 7 | "data": { 8 | "Ok": [ 9 | { 10 | "language": "rust", 11 | "value": "std::vec::Vec" 12 | }, 13 | { 14 | "language": "rust", 15 | "value": "let mut vec1 = Vec::new();" 16 | } 17 | ] 18 | } 19 | } -------------------------------------------------------------------------------- /tests/fixtures/hover/save_data/test_tooltip_std.rs.0011_025.json: -------------------------------------------------------------------------------- 1 | { 2 | "test": { 3 | "file": "test_tooltip_std.rs", 4 | "line": 11, 5 | "col": 25 6 | }, 7 | "data": { 8 | "Ok": [ 9 | { 10 | "language": "rust", 11 | "value": "fn clone(&self) -> Self" 12 | }, 13 | "https://doc.rust-lang.org/nightly/core/clone/Clone.t.html#clone.v", 14 | "Returns a copy of the value.\n\n# Examples\n\n```rust\nlet hello = \"Hello\"; // &str implements Clone\n\nassert_eq!(\"Hello\", hello.clone());\n```" 15 | ] 16 | } 17 | } -------------------------------------------------------------------------------- /tests/fixtures/hover/save_data/test_tooltip_std.rs.0012_033.json: -------------------------------------------------------------------------------- 1 | { 2 | "test": { 3 | "file": "test_tooltip_std.rs", 4 | "line": 12, 5 | "col": 33 6 | }, 7 | "data": { 8 | "Ok": [ 9 | { 10 | "language": "rust", 11 | "value": "fn default() -> Self" 12 | }, 13 | "https://doc.rust-lang.org/nightly/core/default/Default.t.html#default.v", 14 | "Returns the \"default value\" for a type.\n\nDefault values are often some kind of initial value, identity value, or anything else that\nmay make sense as a default.\n\n# Examples\n\nUsing built-in default values:\n\n```rust\nlet i: i8 = Default::default();\nlet (x, y): (Option, f64) = Default::default();\nlet (a, b, (c, d)): (i32, u32, (bool, bool)) = Default::default();\n```\n\nMaking your own:\n\n```rust\nenum Kind {\n A,\n B,\n C,\n}\n\nimpl Default for Kind {\n fn default() -> Self { Kind::A }\n}\n```" 15 | ] 16 | } 17 | } -------------------------------------------------------------------------------- /tests/fixtures/hover/save_data/test_tooltip_std.rs.0013_011.json: -------------------------------------------------------------------------------- 1 | { 2 | "test": { 3 | "file": "test_tooltip_std.rs", 4 | "line": 13, 5 | "col": 11 6 | }, 7 | "data": { 8 | "Ok": [ 9 | { 10 | "language": "rust", 11 | "value": "i32" 12 | } 13 | ] 14 | } 15 | } -------------------------------------------------------------------------------- /tests/fixtures/hover/save_data/test_tooltip_std.rs.0013_018.json: -------------------------------------------------------------------------------- 1 | { 2 | "test": { 3 | "file": "test_tooltip_std.rs", 4 | "line": 13, 5 | "col": 18 6 | }, 7 | "data": { 8 | "Ok": [ 9 | { 10 | "language": "rust", 11 | "value": "&[i32]" 12 | }, 13 | { 14 | "language": "rust", 15 | "value": "let slice = &vec1[0..];" 16 | } 17 | ] 18 | } 19 | } -------------------------------------------------------------------------------- /tests/fixtures/hover/save_data/test_tooltip_std.rs.0014_024.json: -------------------------------------------------------------------------------- 1 | { 2 | "test": { 3 | "file": "test_tooltip_std.rs", 4 | "line": 14, 5 | "col": 24 6 | }, 7 | "data": { 8 | "Ok": [ 9 | { 10 | "language": "rust", 11 | "value": "&[i32]" 12 | }, 13 | { 14 | "language": "rust", 15 | "value": "let slice = &vec1[0..];" 16 | } 17 | ] 18 | } 19 | } -------------------------------------------------------------------------------- /tests/fixtures/hover/save_data/test_tooltip_std.rs.0015_017.json: -------------------------------------------------------------------------------- 1 | { 2 | "test": { 3 | "file": "test_tooltip_std.rs", 4 | "line": 15, 5 | "col": 17 6 | }, 7 | "data": { 8 | "Ok": [ 9 | { 10 | "language": "rust", 11 | "value": "library/alloc/src/string.rs" 12 | }, 13 | "https://doc.rust-lang.org/nightly/alloc/string/", 14 | "A UTF-8–encoded, growable string.\n\nThis module contains the [`String`] type, the [`ToString`] trait for\nconverting to strings, and several error types that may result from\nworking with [`String`]s.\n\n# Examples\n\nThere are multiple ways to create a new [`String`] from a string literal:\n\n```rust\nlet s = \"Hello\".to_string();\n\nlet s = String::from(\"world\");\nlet s: String = \"also this\".into();\n```\n\nYou can create a new [`String`] from an existing one by concatenating with\n`+`:\n\n```rust\nlet s = \"Hello\".to_string();\n\nlet message = s + \" world!\";\n```\n\nIf you have a vector of valid UTF-8 bytes, you can make a [`String`] out of\nit. You can do the reverse too.\n\n```rust\nlet sparkle_heart = vec![240, 159, 146, 150];\n\n// We know these bytes are valid, so we'll use `unwrap()`.\nlet sparkle_heart = String::from_utf8(sparkle_heart).unwrap();\n\nassert_eq!(\"💖\", sparkle_heart);\n\nlet bytes = sparkle_heart.into_bytes();\n\nassert_eq!(bytes, [240, 159, 146, 150]);\n```" 15 | ] 16 | } 17 | } -------------------------------------------------------------------------------- /tests/fixtures/hover/save_data/test_tooltip_std.rs.0015_025.json: -------------------------------------------------------------------------------- 1 | { 2 | "test": { 3 | "file": "test_tooltip_std.rs", 4 | "line": 15, 5 | "col": 25 6 | }, 7 | "data": { 8 | "Ok": [ 9 | { 10 | "language": "rust", 11 | "value": "pub trait ToString" 12 | }, 13 | "https://doc.rust-lang.org/nightly/alloc/string/ToString.t.html", 14 | "A trait for converting a value to a `String`.\n\nThis trait is automatically implemented for any type which implements the\n[`Display`] trait. As such, `ToString` shouldn't be implemented directly:\n[`Display`] should be implemented instead, and you get the `ToString`\nimplementation for free.\n\n[`Display`]: fmt::Display" 15 | ] 16 | } 17 | } -------------------------------------------------------------------------------- /tests/fixtures/hover/src/lib.rs: -------------------------------------------------------------------------------- 1 | #![allow(dead_code, unused_imports)] 2 | 3 | extern crate fnv; 4 | 5 | pub mod test_tooltip_01; 6 | pub mod test_tooltip_mod; 7 | pub mod test_tooltip_mod_use; 8 | pub mod test_tooltip_std; -------------------------------------------------------------------------------- /tests/fixtures/hover/src/test_extract_decl.rs: -------------------------------------------------------------------------------- 1 | pub fn foo() -> Foo { 2 | Foo { t: 1 } 3 | } 4 | 5 | #[derive(Debug)] 6 | pub struct Foo { 7 | pub t: T 8 | } 9 | 10 | #[derive(Debug)] 11 | pub enum Bar { 12 | Baz 13 | } 14 | 15 | #[derive(Debug)] 16 | pub struct NewType(pub u32, f32); 17 | 18 | impl NewType { 19 | pub fn new() -> NewType { 20 | NewType(1, 2.0) 21 | } 22 | 23 | pub fn bar(&self, the_really_long_name_string: String, the_really_long_name_foo: Foo) -> Vec<(String, Foo)> { 24 | Vec::default() 25 | } 26 | } 27 | 28 | pub trait Baz where T: Copy { 29 | fn make_copy(&self) -> Self; 30 | } 31 | 32 | impl Baz for Foo where T: Copy { 33 | fn make_copy(&self) -> Self { 34 | Foo { t: self.t } 35 | } 36 | } 37 | 38 | pub trait Qeh 39 | where T: Copy, 40 | U: Clone { 41 | 42 | } 43 | 44 | pub fn multiple_lines( 45 | s: String, 46 | i: i32 47 | ) { 48 | drop(s); 49 | drop(i); 50 | } 51 | 52 | pub fn bar() -> Bar { 53 | Bar::Baz 54 | } 55 | -------------------------------------------------------------------------------- /tests/fixtures/hover/src/test_extract_decl_multiline_empty_function.rs: -------------------------------------------------------------------------------- 1 | /// Do nothing with matrices. 2 | fn matrix_something( 3 | _a_matrix: [[f32; 4]; 4], 4 | _b_matrix: [[f32; 4]; 4], 5 | _c_matrix: [[f32; 4]; 4], 6 | _d_matrix: [[f32; 4]; 4], 7 | ) {} -------------------------------------------------------------------------------- /tests/fixtures/hover/src/test_extract_docs_attributes.rs: -------------------------------------------------------------------------------- 1 | /// Begin multiline attribute 2 | /// 3 | /// Cras malesuada mattis massa quis ornare. Suspendisse in ex maximus, 4 | /// iaculis ante non, ultricies nulla. Nam ultrices convallis ex, vel 5 | /// lacinia est rhoncus sed. Nullam sollicitudin finibus ex at placerat. 6 | /// 7 | /// End multiline attribute 8 | #[derive( 9 | Copy, 10 | Clone 11 | )] 12 | struct MultilineAttribute; 13 | 14 | 15 | /// Begin single line attribute 16 | /// 17 | /// Cras malesuada mattis massa quis ornare. Suspendisse in ex maximus, 18 | /// iaculis ante non, ultricies nulla. Nam ultrices convallis ex, vel 19 | /// lacinia est rhoncus sed. Nullam sollicitudin finibus ex at placerat. 20 | /// 21 | /// End single line attribute. 22 | #[derive(Debug)] 23 | struct SingleLineAttribute; -------------------------------------------------------------------------------- /tests/fixtures/hover/src/test_extract_docs_comment_block.rs: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////////////////// 2 | // Free functions 3 | //////////////////////////////////////////////////////////////////////////////// 4 | 5 | /// The standard library often has comment header blocks that should not be 6 | /// included. 7 | /// 8 | /// Nam efficitur dapibus lectus consequat porta. Pellentesque augue metus, 9 | /// vestibulum nec massa at, aliquet consequat ex. 10 | /// 11 | /// End of spawn docs 12 | pub fn spawn(_f: F) -> JoinHandle where 13 | F: FnOnce() -> T, F: Send + 'static, T: Send + 'static 14 | { 15 | unimplemented!() 16 | } -------------------------------------------------------------------------------- /tests/fixtures/hover/src/test_extract_docs_comment_first_line.rs: -------------------------------------------------------------------------------- 1 | /// First line comment 2 | fn hover() { 3 | unimplemented!(); 4 | } -------------------------------------------------------------------------------- /tests/fixtures/hover/src/test_extract_docs_empty_line_before_decl.rs: -------------------------------------------------------------------------------- 1 | /// Begin empty before decl 2 | /// 3 | /// Cras malesuada mattis massa quis ornare. Suspendisse in ex maximus, 4 | /// iaculis ante non, ultricies nulla. Nam ultrices convallis ex, vel 5 | /// lacinia est rhoncus sed. Nullam sollicitudin finibus ex at placerat. 6 | /// 7 | /// End empty line before decl. 8 | 9 | struct EmptyLineBeforeDecl; -------------------------------------------------------------------------------- /tests/fixtures/hover/src/test_extract_docs_module_docs.rs: -------------------------------------------------------------------------------- 1 | //! Begin module docs 2 | //! 3 | //! Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas 4 | //! tincidunt tristique maximus. Sed venenatis urna vel sagittis tempus. 5 | //! In hac habitasse platea dictumst. 6 | //! 7 | //! End module docs. 8 | 9 | /// Begin first item docs 10 | /// 11 | /// The first item docs should not pick up the module docs. 12 | struct First; -------------------------------------------------------------------------------- /tests/fixtures/hover/src/test_extract_docs_module_docs_no_copyright.rs: -------------------------------------------------------------------------------- 1 | //! Begin module docs 2 | //! 3 | //! Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas 4 | //! tincidunt tristique maximus. Sed venenatis urna vel sagittis tempus. 5 | //! In hac habitasse platea dictumst. 6 | //! 7 | //! End module docs. 8 | 9 | /// Begin first item docs 10 | /// 11 | /// The first item docs should not pick up the module docs. 12 | struct First; -------------------------------------------------------------------------------- /tests/fixtures/hover/src/test_extract_docs_module_docs_with_attribute.rs: -------------------------------------------------------------------------------- 1 | //! Begin module docs 2 | //! 3 | //! Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas 4 | //! tincidunt tristique maximus. Sed venenatis urna vel sagittis tempus. 5 | //! In hac habitasse platea dictumst. 6 | //! 7 | //! End module docs. 8 | 9 | #![allow(dead_code, unused_imports)] 10 | 11 | /// Begin first item docs 12 | /// 13 | /// The first item docs should not pick up the module docs. 14 | struct First; -------------------------------------------------------------------------------- /tests/fixtures/hover/src/test_tooltip_01.rs: -------------------------------------------------------------------------------- 1 | /// Foo enum 2 | #[derive(Copy, Clone)] 3 | pub enum Foo { 4 | /// Bar variant 5 | Bar, 6 | /// Baz variant 7 | Baz 8 | } 9 | 10 | /// Bar struct 11 | pub struct Bar { 12 | /// The first field 13 | field_1: Tuple, 14 | /// The second field 15 | field_2: T, 16 | /// The third field 17 | field_3: Foo, 18 | } 19 | 20 | impl Bar { 21 | /// Create a new Bar 22 | fn new(one: Tuple, two: T, three: Foo) -> Bar { 23 | Bar { 24 | field_1: one, 25 | field_2: two, 26 | field_3: three, 27 | } 28 | } 29 | } 30 | 31 | /// Tuple struct 32 | pub struct Tuple(pub u32, f32); 33 | 34 | /// Bar function 35 | /// 36 | /// # Examples 37 | /// 38 | /// ```no_run,ignore 39 | /// # extern crate does_not_exist; 40 | /// 41 | /// use does_not_exist::other; 42 | /// 43 | /// let foo = bar(1.0); 44 | /// other(foo); 45 | /// ``` 46 | fn bar(thing: T) -> Bar { 47 | Bar { 48 | field_1: Tuple(1, 3.0), 49 | field_2: thing, 50 | field_3: Foo::Bar, 51 | } 52 | } 53 | 54 | impl Bar { 55 | /// Foo method 56 | fn foo(&mut self, foo: Foo) -> Foo { 57 | let other = self.field_3; 58 | self.field_3 = foo; 59 | other 60 | } 61 | 62 | /// Bar method 63 | fn bar(&mut self, thing: T) -> Bar where T: Copy { 64 | self.field_2 = thing; 65 | bar(self.field_2) 66 | } 67 | 68 | /// Other method 69 | fn other(&self, tuple: Tuple) -> Bar { 70 | Bar::new(Tuple(3, 1.0), tuple.1, Foo::Bar) 71 | } 72 | } 73 | 74 | fn foo() { 75 | let mut bar = Bar::new(Tuple(3, 1.0), 2.0, Foo::Bar); 76 | bar.bar(4.0); 77 | bar.foo(Foo::Baz); 78 | bar.other(Tuple(4, 5.0)); 79 | } 80 | 81 | trait Baz { 82 | /// Foo other type 83 | type Foo: Other; 84 | 85 | fn foo() -> Self::Foo; 86 | 87 | } 88 | 89 | /// The other trait 90 | trait Other {} 91 | 92 | /// The constant FOO 93 | const FOO: &'static str = "FOO"; 94 | 95 | /// The static BAR 96 | static BAR: u32 = 123; 97 | 98 | pub fn print_foo() { 99 | println!("{}", FOO); 100 | } 101 | 102 | pub fn print_bar() { 103 | println!("{}", BAR); 104 | } -------------------------------------------------------------------------------- /tests/fixtures/hover/src/test_tooltip_mod.rs: -------------------------------------------------------------------------------- 1 | //! Begin module docs 2 | //! 3 | //! Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas 4 | //! tincidunt tristique maximus. Sed venenatis urna vel sagittis tempus. 5 | //! In hac habitasse platea dictumst. 6 | //! 7 | //! End module docs. 8 | 9 | /// Begin first item docs 10 | /// 11 | /// The first item docs should not pick up the module docs. 12 | pub struct First; 13 | 14 | /// Submodule first line 15 | /// 16 | /// Mauris vel lobortis lacus, in condimentum dolor. 17 | /// 18 | /// Submodule last line 19 | pub mod sub_module { 20 | 21 | } -------------------------------------------------------------------------------- /tests/fixtures/hover/src/test_tooltip_mod_use.rs: -------------------------------------------------------------------------------- 1 | use test_tooltip_mod; 2 | use test_tooltip_mod::First; 3 | use test_tooltip_mod::sub_module; -------------------------------------------------------------------------------- /tests/fixtures/hover/src/test_tooltip_mod_use_external.rs: -------------------------------------------------------------------------------- 1 | use fnv; 2 | use fnv::FnvHasher; 3 | 4 | use std::sync; 5 | use std::sync::Arc; -------------------------------------------------------------------------------- /tests/fixtures/hover/src/test_tooltip_std.rs: -------------------------------------------------------------------------------- 1 | // Spot check several stdlib items and verify that the the doc_url 2 | // is correctly included for traits. The tests around the stdlib 3 | // are subject to breakage due to changes in docs, so these tests 4 | // are not very comprehensive. 5 | 6 | 7 | fn test() { 8 | let mut vec1 = Vec::new(); 9 | vec1.push(1); 10 | let slice = &vec1[0..]; 11 | let _vec2 = vec1.clone(); 12 | let _vec3 = Vec::::default(); 13 | let _one = slice[0]; 14 | let _one_ref = &slice[0]; 15 | use std::string::ToString; 16 | } -------------------------------------------------------------------------------- /tests/fixtures/infer_bin/Cargo.lock: -------------------------------------------------------------------------------- 1 | [[package]] 2 | name = "infer_bin" 3 | version = "0.1.0" 4 | 5 | -------------------------------------------------------------------------------- /tests/fixtures/infer_bin/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "infer_bin" 3 | version = "0.1.0" 4 | authors = ["Igor Matuszewski "] 5 | 6 | [dependencies] 7 | -------------------------------------------------------------------------------- /tests/fixtures/infer_bin/src/main.rs: -------------------------------------------------------------------------------- 1 | struct UnusedBin; 2 | 3 | fn main() { 4 | println!("Hello, world!"); 5 | } 6 | -------------------------------------------------------------------------------- /tests/fixtures/infer_custom_bin/Cargo.lock: -------------------------------------------------------------------------------- 1 | [[package]] 2 | name = "infer_custom_bin" 3 | version = "0.1.0" 4 | 5 | -------------------------------------------------------------------------------- /tests/fixtures/infer_custom_bin/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "infer_custom_bin" 3 | version = "0.1.0" 4 | authors = ["Igor Matuszewski "] 5 | 6 | [[bin]] 7 | name = "custom_bin" 8 | path = "src/custom_bin.rs" 9 | 10 | [dependencies] 11 | -------------------------------------------------------------------------------- /tests/fixtures/infer_custom_bin/src/custom_bin.rs: -------------------------------------------------------------------------------- 1 | struct UnusedCustomBin; 2 | 3 | fn main() { 4 | println!("Hello, world!"); 5 | } 6 | -------------------------------------------------------------------------------- /tests/fixtures/infer_lib/Cargo.lock: -------------------------------------------------------------------------------- 1 | [[package]] 2 | name = "infer_lib" 3 | version = "0.1.0" 4 | 5 | -------------------------------------------------------------------------------- /tests/fixtures/infer_lib/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "infer_lib" 3 | version = "0.1.0" 4 | authors = ["Igor Matuszewski "] 5 | 6 | [dependencies] 7 | -------------------------------------------------------------------------------- /tests/fixtures/infer_lib/src/lib.rs: -------------------------------------------------------------------------------- 1 | struct UnusedLib; 2 | 3 | #[cfg(test)] 4 | mod tests { 5 | #[test] 6 | fn it_works() { 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /tests/fixtures/lens_run/Cargo.lock: -------------------------------------------------------------------------------- 1 | [[package]] 2 | name = "run" 3 | version = "0.1.0" 4 | 5 | -------------------------------------------------------------------------------- /tests/fixtures/lens_run/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "run" 3 | version = "0.1.0" 4 | authors = ["Nick Cameron "] 5 | 6 | [dependencies] 7 | -------------------------------------------------------------------------------- /tests/fixtures/lens_run/src/main.rs: -------------------------------------------------------------------------------- 1 | pub fn main() { 2 | } 3 | 4 | #[test] 5 | fn test_foo() { 6 | 7 | } 8 | 9 | #[tokio::test] 10 | fn test_bar() { 11 | 12 | } 13 | 14 | #[dummy_ext] 15 | fn test_baz() { 16 | 17 | } 18 | -------------------------------------------------------------------------------- /tests/fixtures/multiple_bins/Cargo.lock: -------------------------------------------------------------------------------- 1 | [[package]] 2 | name = "multiple_bins" 3 | version = "0.1.0" 4 | 5 | -------------------------------------------------------------------------------- /tests/fixtures/multiple_bins/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "multiple_bins" 3 | version = "0.1.0" 4 | authors = ["Igor Matuszewski "] 5 | 6 | [[bin]] 7 | name = "bin1" 8 | path = "src/main.rs" 9 | 10 | [[bin]] 11 | name = "bin2" 12 | path = "src/main2.rs" 13 | 14 | [dependencies] 15 | -------------------------------------------------------------------------------- /tests/fixtures/multiple_bins/src/main.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | let bin_name1 = "bin1"; 3 | 4 | println!("Hello, world!"); 5 | } 6 | -------------------------------------------------------------------------------- /tests/fixtures/multiple_bins/src/main2.rs: -------------------------------------------------------------------------------- 1 | fn main() { 2 | let bin_name2 = "bin2"; 3 | 4 | println!("Hello, world!"); 5 | } 6 | -------------------------------------------------------------------------------- /tests/fixtures/reformat/Cargo.lock: -------------------------------------------------------------------------------- 1 | [[package]] 2 | name = "reformat" 3 | version = "0.1.0" 4 | 5 | -------------------------------------------------------------------------------- /tests/fixtures/reformat/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "reformat" 3 | version = "0.1.0" 4 | authors = ["Nick Cameron "] 5 | 6 | [dependencies] 7 | -------------------------------------------------------------------------------- /tests/fixtures/reformat/rustfmt.toml: -------------------------------------------------------------------------------- 1 | newline_style = "Unix" 2 | -------------------------------------------------------------------------------- /tests/fixtures/reformat/src/foo.rs: -------------------------------------------------------------------------------- 1 | pub fn bar() { 2 | 3 | } 4 | -------------------------------------------------------------------------------- /tests/fixtures/reformat/src/main.rs: -------------------------------------------------------------------------------- 1 | pub mod foo ; 2 | pub fn main() { let world = "world"; println!("Hello, {}!", world); } 3 | -------------------------------------------------------------------------------- /tests/fixtures/reformat_with_range/Cargo.lock: -------------------------------------------------------------------------------- 1 | [[package]] 2 | name = "reformat_with_range" 3 | version = "0.1.0" 4 | 5 | -------------------------------------------------------------------------------- /tests/fixtures/reformat_with_range/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "reformat_with_range" 3 | version = "0.1.0" 4 | authors = ["Nick Cameron "] 5 | 6 | [dependencies] 7 | -------------------------------------------------------------------------------- /tests/fixtures/reformat_with_range/rustfmt.toml: -------------------------------------------------------------------------------- 1 | # Work around Travis checking files out with autocrlf=true 2 | # https://travis-ci.community/t/files-in-checkout-have-eol-changed-from-lf-to-crlf/349 3 | newline_style = "Native" 4 | 5 | -------------------------------------------------------------------------------- /tests/fixtures/reformat_with_range/src/main.rs: -------------------------------------------------------------------------------- 1 | pub fn main() 2 | { 3 | let world1 = "world"; println!("Hello, {}!", world1); 4 | 5 | // Work around rustfmt#3494 6 | let world2 = "world"; println!("Hello, {}!", world2); 7 | let world3 = "world"; println!("Hello, {}!", world3); 8 | } -------------------------------------------------------------------------------- /tests/fixtures/workspace_symbol/Cargo.lock: -------------------------------------------------------------------------------- 1 | [[package]] 2 | name = "workspace_symbol" 3 | version = "0.1.0" 4 | 5 | -------------------------------------------------------------------------------- /tests/fixtures/workspace_symbol/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "workspace_symbol" 3 | version = "0.1.0" 4 | authors = ["Stuart Hinson "] 5 | 6 | [dependencies] 7 | -------------------------------------------------------------------------------- /tests/fixtures/workspace_symbol/src/foo.rs: -------------------------------------------------------------------------------- 1 | mod nemo {} 2 | -------------------------------------------------------------------------------- /tests/fixtures/workspace_symbol/src/main.rs: -------------------------------------------------------------------------------- 1 | mod x { 2 | pub fn nemo() {} 3 | } 4 | 5 | mod foo; 6 | 7 | pub fn main() { 8 | x::nemo(); 9 | } 10 | -------------------------------------------------------------------------------- /tests/fixtures/workspace_symbol_duplicates/Cargo.lock: -------------------------------------------------------------------------------- 1 | [[package]] 2 | name = "workspace_symbol_duplicates" 3 | version = "0.1.0" 4 | 5 | -------------------------------------------------------------------------------- /tests/fixtures/workspace_symbol_duplicates/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "workspace_symbol_duplicates" 3 | version = "0.1.0" 4 | authors = ["Stuart Hinson "] 5 | 6 | [dependencies] 7 | -------------------------------------------------------------------------------- /tests/fixtures/workspace_symbol_duplicates/src/main.rs: -------------------------------------------------------------------------------- 1 | #[path="shared.rs"] 2 | mod a; 3 | #[path="shared.rs"] 4 | mod b; 5 | -------------------------------------------------------------------------------- /tests/fixtures/workspace_symbol_duplicates/src/shared.rs: -------------------------------------------------------------------------------- 1 | #[allow(unused)] 2 | struct Frobnicator; 3 | -------------------------------------------------------------------------------- /tests/support/client/child_process.rs: -------------------------------------------------------------------------------- 1 | use std::io; 2 | use std::pin::Pin; 3 | use std::process::{Command, Stdio}; 4 | use std::rc::Rc; 5 | use std::task::{Context, Poll}; 6 | 7 | use tokio::io::{AsyncRead, AsyncWrite, ReadBuf}; 8 | 9 | pub struct ChildProcess { 10 | stdin: tokio::process::ChildStdin, 11 | stdout: tokio::process::ChildStdout, 12 | child: Rc, 13 | } 14 | 15 | impl AsyncRead for ChildProcess { 16 | fn poll_read( 17 | mut self: Pin<&mut Self>, 18 | cx: &mut Context<'_>, 19 | buf: &mut ReadBuf<'_>, 20 | ) -> Poll> { 21 | Pin::new(&mut self.stdout).poll_read(cx, buf) 22 | } 23 | } 24 | 25 | impl AsyncWrite for ChildProcess { 26 | fn poll_write( 27 | mut self: Pin<&mut Self>, 28 | cx: &mut Context<'_>, 29 | buf: &[u8], 30 | ) -> Poll> { 31 | Pin::new(&mut self.stdin).poll_write(cx, buf) 32 | } 33 | 34 | fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { 35 | Pin::new(&mut self.stdin).poll_flush(cx) 36 | } 37 | 38 | fn poll_shutdown(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { 39 | Pin::new(&mut self.stdin).poll_shutdown(cx) 40 | } 41 | } 42 | 43 | impl ChildProcess { 44 | pub fn spawn_from_command(mut cmd: Command) -> Result { 45 | cmd.stdin(Stdio::piped()); 46 | cmd.stdout(Stdio::piped()); 47 | let mut child = tokio::process::Command::from(cmd).spawn().expect("to async spawn process"); 48 | 49 | Ok(ChildProcess { 50 | stdout: child.stdout.take().unwrap(), 51 | stdin: child.stdin.take().unwrap(), 52 | child: Rc::new(child), 53 | }) 54 | } 55 | 56 | /// Returns a handle to the underlying `Child` process. 57 | /// Useful when waiting until child process exits. 58 | pub fn child(&self) -> Rc { 59 | Rc::clone(&self.child) 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /tests/support/paths.rs: -------------------------------------------------------------------------------- 1 | #![allow(unknown_lints)] 2 | 3 | use std::cell::Cell; 4 | use std::env; 5 | use std::ffi::OsStr; 6 | use std::fs; 7 | use std::io::{self, ErrorKind}; 8 | use std::path::{Path, PathBuf}; 9 | use std::sync::atomic::{AtomicUsize, Ordering}; 10 | use std::sync::Once; 11 | 12 | static RLS_INTEGRATION_TEST_DIR: &str = "rlsit"; 13 | static NEXT_ID: AtomicUsize = AtomicUsize::new(0); 14 | 15 | thread_local!(static TASK_ID: usize = NEXT_ID.fetch_add(1, Ordering::SeqCst)); 16 | 17 | fn init() { 18 | static GLOBAL_INIT: Once = Once::new(); 19 | thread_local!(static LOCAL_INIT: Cell = Cell::new(false)); 20 | GLOBAL_INIT.call_once(|| { 21 | global_root().mkdir_p(); 22 | }); 23 | LOCAL_INIT.with(|i| { 24 | if i.get() { 25 | return; 26 | } 27 | i.set(true); 28 | root().rm_rf(); 29 | }) 30 | } 31 | 32 | fn global_root() -> PathBuf { 33 | let mut path = env::current_exe().unwrap(); 34 | path.pop(); // chop off exe name 35 | path.pop(); // chop off 'debug' 36 | 37 | // If `cargo test` is run manually then our path looks like 38 | // `target/debug/foo`, in which case our `path` is already pointing at 39 | // `target`. If, however, `cargo test --target $target` is used then the 40 | // output is `target/$target/debug/foo`, so our path is pointing at 41 | // `target/$target`. Here we conditionally pop the `$target` name. 42 | if path.file_name().and_then(OsStr::to_str) != Some("target") { 43 | path.pop(); 44 | } 45 | 46 | path.join(RLS_INTEGRATION_TEST_DIR) 47 | } 48 | 49 | pub fn root() -> PathBuf { 50 | init(); 51 | global_root().join(&TASK_ID.with(|my_id| format!("t{}", my_id))) 52 | } 53 | 54 | pub trait TestPathExt { 55 | fn rm_rf(&self); 56 | fn mkdir_p(&self); 57 | } 58 | 59 | #[allow(clippy::redundant_closure)] // &Path is not AsRef 60 | impl TestPathExt for Path { 61 | /* Technically there is a potential race condition, but we don't 62 | * care all that much for our tests 63 | */ 64 | fn rm_rf(&self) { 65 | if !self.exists() { 66 | return; 67 | } 68 | 69 | for file in fs::read_dir(self).unwrap() { 70 | let file = file.unwrap().path(); 71 | 72 | if file.is_dir() { 73 | file.rm_rf(); 74 | } else { 75 | // On windows we can't remove a readonly file, and git will 76 | // often clone files as readonly. As a result, we have some 77 | // special logic to remove readonly files on windows. 78 | do_op(&file, "remove file", |p| fs::remove_file(p)); 79 | } 80 | } 81 | do_op(self, "remove dir", |p| fs::remove_dir(p)); 82 | } 83 | 84 | fn mkdir_p(&self) { 85 | fs::create_dir_all(self) 86 | .unwrap_or_else(|e| panic!("failed to mkdir_p {}: {}", self.display(), e)) 87 | } 88 | } 89 | 90 | fn do_op(path: &Path, desc: &str, mut f: F) 91 | where 92 | F: FnMut(&Path) -> io::Result<()>, 93 | { 94 | match f(path) { 95 | Ok(()) => {} 96 | Err(ref e) if cfg!(windows) && e.kind() == ErrorKind::PermissionDenied => { 97 | let mut p = path.metadata().unwrap().permissions(); 98 | p.set_readonly(false); 99 | fs::set_permissions(path, p).unwrap(); 100 | f(path).unwrap_or_else(|e| { 101 | panic!("failed to {} {}: {}", desc, path.display(), e); 102 | }) 103 | } 104 | Err(e) => { 105 | panic!("failed to {} {}: {}", desc, path.display(), e); 106 | } 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /tests/support/project_builder.rs: -------------------------------------------------------------------------------- 1 | //! Contains helper types that are capable of dynamically creating project 2 | //! layouts under target/ for testing purposes. 3 | //! This module is currently pulled by main binary and Cargo integration tests. 4 | #![allow(dead_code)] 5 | 6 | use walkdir::WalkDir; 7 | 8 | use std::fs; 9 | use std::io::Write; 10 | use std::path::{Path, PathBuf}; 11 | 12 | use super::paths::{self, TestPathExt}; 13 | 14 | #[derive(PartialEq, Clone)] 15 | struct FileBuilder { 16 | path: PathBuf, 17 | body: String, 18 | } 19 | 20 | impl FileBuilder { 21 | pub fn new(path: PathBuf, body: &str) -> FileBuilder { 22 | FileBuilder { path, body: body.to_string() } 23 | } 24 | 25 | fn mk(&self) { 26 | self.dirname().mkdir_p(); 27 | 28 | let mut file = fs::File::create(&self.path) 29 | .unwrap_or_else(|e| panic!("could not create file {}: {}", self.path.display(), e)); 30 | 31 | file.write_all(self.body.as_bytes()).unwrap(); 32 | } 33 | 34 | fn dirname(&self) -> &Path { 35 | self.path.parent().unwrap() 36 | } 37 | } 38 | 39 | #[derive(PartialEq, Clone)] 40 | pub struct Project { 41 | root: PathBuf, 42 | } 43 | 44 | #[must_use] 45 | #[derive(PartialEq, Clone)] 46 | pub struct ProjectBuilder { 47 | root: Project, 48 | files: Vec, 49 | } 50 | 51 | impl ProjectBuilder { 52 | pub fn new(root: PathBuf) -> ProjectBuilder { 53 | ProjectBuilder { root: Project { root }, files: vec![] } 54 | } 55 | 56 | pub fn try_from_fixture(fixture_dir: impl AsRef) -> std::io::Result { 57 | let fixture_dir = fixture_dir.as_ref(); 58 | 59 | let dirname = fixture_dir 60 | .file_name() 61 | .ok_or_else(|| std::io::Error::new(std::io::ErrorKind::NotFound, "No filename"))?; 62 | 63 | // Generate a new, unique directory for working dir under target/ 64 | let genroot = paths::root(); 65 | let mut builder = ProjectBuilder::new(genroot.join(dirname)); 66 | 67 | // Read existing fixture data to be later copied into scratch genroot 68 | for entry in WalkDir::new(fixture_dir).into_iter() { 69 | let entry = entry?; 70 | let path = entry.path(); 71 | let body = if !std::fs::metadata(path)?.is_dir() { 72 | std::fs::read_to_string(path)? 73 | } else { 74 | continue; 75 | }; 76 | 77 | let relative = entry.path().strip_prefix(fixture_dir).unwrap(); 78 | builder._file(relative, &body); 79 | } 80 | 81 | Ok(builder) 82 | } 83 | 84 | pub fn file>(mut self, path: B, body: &str) -> Self { 85 | self._file(path.as_ref(), body); 86 | self 87 | } 88 | 89 | fn _file(&mut self, path: &Path, body: &str) { 90 | self.files.push(FileBuilder::new(self.root.root.join(path), body)); 91 | } 92 | 93 | pub fn build(self) -> Project { 94 | // First, clean the directory if it already exists 95 | self.rm_root(); 96 | 97 | // Create the empty directory 98 | self.root.root.mkdir_p(); 99 | 100 | for file in &self.files { 101 | file.mk(); 102 | } 103 | 104 | self.root 105 | } 106 | 107 | fn rm_root(&self) { 108 | self.root.root.rm_rf() 109 | } 110 | } 111 | 112 | impl Project { 113 | pub fn root(&self) -> &Path { 114 | &self.root 115 | } 116 | } 117 | 118 | // Generates a project layout 119 | pub fn project(name: &str) -> ProjectBuilder { 120 | ProjectBuilder::new(paths::root().join(name)) 121 | } 122 | --------------------------------------------------------------------------------