diff --git a/src/tools/rust-analyzer/.github/ISSUE_TEMPLATE/bug_report.md b/src/tools/rust-analyzer/.github/ISSUE_TEMPLATE/bug_report.md index 0d99d06bcddee..8333cf08929f8 100644 --- a/src/tools/rust-analyzer/.github/ISSUE_TEMPLATE/bug_report.md +++ b/src/tools/rust-analyzer/.github/ISSUE_TEMPLATE/bug_report.md @@ -8,7 +8,7 @@ assignees: '' --- diff --git a/src/tools/rust-analyzer/.github/workflows/ci.yaml b/src/tools/rust-analyzer/.github/workflows/ci.yaml index 7a6b43a053155..79fb7a2d2ea96 100644 --- a/src/tools/rust-analyzer/.github/workflows/ci.yaml +++ b/src/tools/rust-analyzer/.github/workflows/ci.yaml @@ -15,7 +15,6 @@ env: CARGO_NET_RETRY: 10 CI: 1 RUST_BACKTRACE: short - RUSTFLAGS: "-D warnings -D elided_lifetimes_in_paths -D explicit_outlives_requirements -D unsafe_op_in_unsafe_fn -D unused_extern_crates -D unused_lifetimes -D unreachable_pub" RUSTUP_MAX_RETRIES: 10 jobs: @@ -25,7 +24,6 @@ jobs: pull-requests: read outputs: typescript: ${{ steps.filter.outputs.typescript }} - proc_macros: ${{ steps.filter.outputs.proc_macros }} steps: - uses: actions/checkout@v4 - uses: dorny/paths-filter@1441771bbfdd59dcd748680ee64ebd8faab1a242 @@ -34,52 +32,54 @@ jobs: filters: | typescript: - 'editors/code/**' - proc_macros: - - 'crates/tt/**' - - 'crates/proc-macro-api/**' - - 'crates/proc-macro-srv/**' - - 'crates/proc-macro-srv-cli/**' proc-macro-srv: - needs: changes - if: github.repository == 'rust-lang/rust-analyzer' && needs.changes.outputs.proc_macros == 'true' + if: github.repository == 'rust-lang/rust-analyzer' name: proc-macro-srv runs-on: ubuntu-latest + env: + RUSTFLAGS: "-D warnings" + steps: - name: Checkout repository uses: actions/checkout@v4 with: ref: ${{ github.event.pull_request.head.sha }} + - name: Install rustup-toolchain-install-master + run: cargo install rustup-toolchain-install-master@1.6.0 + + # Install a pinned rustc commit to avoid surprises - name: Install Rust toolchain run: | - rustup update --no-self-update nightly - rustup default nightly - rustup component add --toolchain nightly rust-src rustfmt + RUSTC_VERSION=`cat rust-version` + rustup-toolchain-install-master ${RUSTC_VERSION} -c rust-src -c rustfmt + rustup default ${RUSTC_VERSION} + + # Emulate a nightly toolchain, because the toolchain installed above does not have "nightly" + # in its version string. + - name: Emulate a nightly toolchain + run: echo "RUSTC_BOOTSTRAP=1" >> $GITHUB_ENV + # https://github.com/actions-rust-lang/setup-rust-toolchain/blob/main/rust.json - name: Install Rust Problem Matcher - if: matrix.os == 'ubuntu-latest' run: echo "::add-matcher::.github/rust.json" - - name: Cache Dependencies - uses: Swatinem/rust-cache@9bdad043e88c75890e36ad3bbc8d27f0090dd609 - - - name: Bump opt-level - if: matrix.os == 'ubuntu-latest' - run: sed -i '/\[profile.dev]/a opt-level=1' Cargo.toml - - name: Test - run: cargo test --features sysroot-abi -p rust-analyzer -p proc-macro-srv -p proc-macro-srv-cli -p proc-macro-api -- --quiet + run: cargo test --features sysroot-abi -p proc-macro-srv -p proc-macro-srv-cli -p proc-macro-api -- --quiet + + - name: Check salsa dependency + run: "! (cargo tree -p proc-macro-srv-cli | grep -q salsa)" rust: if: github.repository == 'rust-lang/rust-analyzer' name: Rust runs-on: ${{ matrix.os }} env: + RUSTFLAGS: "-Dwarnings" CC: deny_c strategy: - fail-fast: false matrix: os: [ubuntu-latest, windows-latest, macos-latest] @@ -93,7 +93,7 @@ jobs: run: | rustup update --no-self-update stable rustup default stable - rustup component add --toolchain stable rust-src + rustup component add --toolchain stable rust-src clippy # We always use a nightly rustfmt, regardless of channel, because we need # --file-lines. rustup toolchain install nightly --profile minimal --component rustfmt @@ -102,51 +102,105 @@ jobs: if: matrix.os == 'ubuntu-latest' run: echo "::add-matcher::.github/rust.json" - - name: Cache Dependencies - uses: Swatinem/rust-cache@9bdad043e88c75890e36ad3bbc8d27f0090dd609 + # - name: Cache Dependencies + # uses: Swatinem/rust-cache@9d47c6ad4b02e050fd481d890b2ea34778fd09d6 + # with: + # workspaces: | + # . -> target + # ./crates/proc-macro-srv/proc-macro-test/imp -> target - - name: Bump opt-level - if: matrix.os == 'ubuntu-latest' - run: sed -i '/\[profile.dev]/a opt-level=1' Cargo.toml + - name: Install nextest + uses: taiki-e/install-action@nextest - name: Codegen checks (rust-analyzer) + if: matrix.os == 'ubuntu-latest' run: cargo codegen --check - - name: Compile (tests) - run: cargo test --no-run --locked + - name: Compile tests + run: cargo test --no-run - # It's faster to `test` before `build` ¯\_(ツ)_/¯ - - name: Compile (rust-analyzer) - if: matrix.os == 'ubuntu-latest' - run: cargo build --quiet + - name: Run tests + run: cargo nextest run --no-fail-fast --hide-progress-bar --status-level fail - - name: Test - if: matrix.os == 'ubuntu-latest' || matrix.os == 'windows-latest' || github.event_name == 'push' - run: cargo test -- --quiet + - name: Cancel parallel jobs + if: failure() + run: | + # https://docs.github.com/en/rest/actions/workflow-runs?apiVersion=2022-11-28#cancel-a-workflow-run + curl -L \ + -X POST \ + -H "Accept: application/vnd.github.v3+json" \ + -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" \ + -H "X-GitHub-Api-Version: 2022-11-28" \ + https://api.github.com/repos/${{ github.repository }}/actions/runs/${{ github.run_id }}/cancel + + - name: Run Clippy + if: matrix.os == 'macos-latest' + run: cargo clippy --all-targets -- -D clippy::disallowed_macros -D clippy::dbg_macro -D clippy::todo -D clippy::print_stdout -D clippy::print_stderr - - name: Switch to stable toolchain + analysis-stats: + if: github.repository == 'rust-lang/rust-analyzer' + runs-on: ubuntu-latest + env: + RUSTC_BOOTSTRAP: 1 + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Install Rust toolchain run: | rustup update --no-self-update stable - rustup component add --toolchain stable rust-src clippy rustup default stable + rustup component add rustfmt - - name: Run analysis-stats on rust-analyzer - if: matrix.os == 'ubuntu-latest' - run: target/${{ matrix.target }}/debug/rust-analyzer analysis-stats . + # - name: Cache Dependencies + # uses: Swatinem/rust-cache@9d47c6ad4b02e050fd481d890b2ea34778fd09d6 - - name: Run analysis-stats on the rust standard libraries - if: matrix.os == 'ubuntu-latest' - env: - RUSTC_BOOTSTRAP: 1 - run: target/${{ matrix.target }}/debug/rust-analyzer analysis-stats --with-deps --no-sysroot --no-test $(rustc --print sysroot)/lib/rustlib/src/rust/library/ + - name: Bump opt-level + run: sed -i '/\[profile.dev]/a opt-level=1' Cargo.toml - - name: clippy - if: matrix.os == 'windows-latest' - run: cargo clippy --all-targets -- -D clippy::disallowed_macros -D clippy::dbg_macro -D clippy::todo -D clippy::print_stdout -D clippy::print_stderr + - run: cargo build -p rust-analyzer - - name: rustfmt - if: matrix.os == 'ubuntu-latest' - run: cargo fmt -- --check + - name: ./rust-analyzer + run: ./target/debug/rust-analyzer analysis-stats . -q + + - name: sysroot/lib/rustlib/src/rust/library/ + run: ./target/debug/rust-analyzer analysis-stats --with-deps --no-sysroot --no-test $(rustc --print sysroot)/lib/rustlib/src/rust/library/ -q + + rustfmt: + if: github.repository == 'rust-lang/rust-analyzer' + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Install Rust toolchain + run: | + rustup update --no-self-update stable + rustup default stable + rustup component add rustfmt + + - run: cargo fmt -- --check + + miri: + if: github.repository == 'rust-lang/rust-analyzer' + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Install Rust toolchain + run: | + rustup update --no-self-update nightly + rustup default nightly + rustup component add miri + + # - name: Cache Dependencies + # uses: Swatinem/rust-cache@9d47c6ad4b02e050fd481d890b2ea34778fd09d6 + + - run: cargo miri test -p intern # Weird targets to catch non-portable code rust-cross: @@ -154,11 +208,16 @@ jobs: name: Rust Cross runs-on: ubuntu-latest + strategy: + matrix: + target: [powerpc-unknown-linux-gnu, x86_64-unknown-linux-musl, wasm32-unknown-unknown] + include: + # The rust-analyzer binary is not expected to compile on WASM, but the IDE + # crate should + - target: wasm32-unknown-unknown + ide-only: true env: - targets: "powerpc-unknown-linux-gnu x86_64-unknown-linux-musl" - # The rust-analyzer binary is not expected to compile on WASM, but the IDE - # crate should - targets_ide: "wasm32-unknown-unknown" + RUSTFLAGS: "-Dwarnings" steps: - name: Checkout repository @@ -167,19 +226,15 @@ jobs: - name: Install Rust toolchain run: | rustup update --no-self-update stable - rustup target add ${{ env.targets }} ${{ env.targets_ide }} + rustup target add ${{ matrix.target }} - - name: Cache Dependencies - uses: Swatinem/rust-cache@9bdad043e88c75890e36ad3bbc8d27f0090dd609 + # - name: Cache Dependencies + # uses: Swatinem/rust-cache@9d47c6ad4b02e050fd481d890b2ea34778fd09d6 - - name: Check - run: | - for target in ${{ env.targets }}; do - cargo check --target=$target --all-targets - done - for target in ${{ env.targets_ide }}; do - cargo check -p ide --target=$target --all-targets - done + - run: cargo check --target=${{ matrix.target }} --all-targets -p ide + if: ${{ matrix.ide-only }} + - run: cargo check --target=${{ matrix.target }} --all-targets + if: ${{ !matrix.ide-only }} typescript: needs: changes @@ -261,7 +316,7 @@ jobs: run: typos conclusion: - needs: [rust, rust-cross, typescript, typo-check, proc-macro-srv] + needs: [rust, rust-cross, typescript, typo-check, proc-macro-srv, miri, rustfmt, analysis-stats] # We need to ensure this job does *not* get skipped if its dependencies fail, # because a skipped job is considered a success by GitHub. So we have to # overwrite `if:`. We use `!cancelled()` to ensure the job does still not get run diff --git a/src/tools/rust-analyzer/.github/workflows/release.yaml b/src/tools/rust-analyzer/.github/workflows/release.yaml index c8e6de72ce98f..a758ecfd46796 100644 --- a/src/tools/rust-analyzer/.github/workflows/release.yaml +++ b/src/tools/rust-analyzer/.github/workflows/release.yaml @@ -29,19 +29,25 @@ jobs: - os: windows-latest target: x86_64-pc-windows-msvc code-target: win32-x64 + pgo: clap-rs/clap@v4.5.36 - os: windows-latest target: i686-pc-windows-msvc + pgo: clap-rs/clap@v4.5.36 - os: windows-latest target: aarch64-pc-windows-msvc code-target: win32-arm64 - os: ubuntu-latest target: x86_64-unknown-linux-gnu - zig_target: x86_64-unknown-linux-gnu.2.28 + # Use a container with glibc 2.28 + # Zig is not used because it doesn't work with PGO + container: quay.io/pypa/manylinux_2_28_x86_64 code-target: linux-x64 - - os: ubuntu-latest + pgo: clap-rs/clap@v4.5.36 + - os: ubuntu-24.04-arm target: aarch64-unknown-linux-gnu - zig_target: aarch64-unknown-linux-gnu.2.28 + container: quay.io/pypa/manylinux_2_28_aarch64 code-target: linux-arm64 + pgo: clap-rs/clap@v4.5.36 - os: ubuntu-latest target: arm-unknown-linux-gnueabihf zig_target: arm-unknown-linux-gnueabihf.2.28 @@ -49,9 +55,11 @@ jobs: - os: macos-13 target: x86_64-apple-darwin code-target: darwin-x64 - - os: macos-13 + pgo: clap-rs/clap@v4.5.36 + - os: macos-14 target: aarch64-apple-darwin code-target: darwin-arm64 + pgo: clap-rs/clap@v4.5.36 name: dist (${{ matrix.target }}) runs-on: ${{ matrix.os }} @@ -71,10 +79,17 @@ jobs: with: node-version: 22 + - name: Install rustup + if: ${{ matrix.container }} + run: | + curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --profile minimal + echo "$HOME/.cargo/bin" >> $GITHUB_PATH + - name: Install Rust toolchain run: | rustup update --no-self-update stable - rustup component add rust-src + # llvm-tools contain the llvm-profdata tool which is needed for PGO + rustup component add rust-src ${{ matrix.pgo && 'llvm-tools' || '' }} rustup target add ${{ matrix.target }} - name: Install Zig toolchain @@ -87,11 +102,11 @@ jobs: - name: Dist (plain) if: ${{ !matrix.zig_target }} - run: cargo xtask dist --client-patch-version ${{ github.run_number }} + run: cargo xtask dist --client-patch-version ${{ github.run_number }} ${{ matrix.pgo && format('--pgo {0}', matrix.pgo) || ''}} - name: Dist (using zigbuild) if: ${{ matrix.zig_target }} - run: RA_TARGET=${{ matrix.zig_target}} cargo xtask dist --client-patch-version ${{ github.run_number }} --zig + run: RA_TARGET=${{ matrix.zig_target}} cargo xtask dist --client-patch-version ${{ github.run_number }} --zig ${{ matrix.pgo && format('--pgo {0}', matrix.pgo) || ''}} - run: npm ci working-directory: editors/code diff --git a/src/tools/rust-analyzer/Cargo.lock b/src/tools/rust-analyzer/Cargo.lock index 2dbb3f5d69ca3..9f6b80c63790f 100644 --- a/src/tools/rust-analyzer/Cargo.lock +++ b/src/tools/rust-analyzer/Cargo.lock @@ -1,65 +1,77 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] name = "addr2line" -version = "0.22.0" +version = "0.24.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e4503c46a5c0c7844e948c9a4d6acd9f50cccb4de1c48eb9e291ea17470c678" +checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" dependencies = [ "gimli", ] [[package]] -name = "adler" -version = "1.0.2" +name = "adler2" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" +checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" [[package]] -name = "always-assert" -version = "0.2.0" +name = "aho-corasick" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +dependencies = [ + "memchr", +] + +[[package]] +name = "allocator-api2" +version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1078fa1ce1e34b1872d8611ad921196d76bdd7027e949fbe31231abde201892" +checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" [[package]] name = "anyhow" -version = "1.0.86" +version = "1.0.97" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" +checksum = "dcfed56ad506cb2c684a14971b8861fdc3baaaae314b9e5f9bb532cbe3ba7a4f" [[package]] name = "arbitrary" -version = "1.3.2" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d5a26814d8dcb93b0e5a0ff3c6d80a8843bafb21b39e8e18a6f05471870e110" +checksum = "dde20b3d026af13f561bdd0f15edf01fc734f0dafcedbaf42bba506a9517f223" +dependencies = [ + "derive_arbitrary", +] [[package]] name = "arrayvec" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "autocfg" -version = "1.3.0" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" [[package]] name = "backtrace" -version = "0.3.73" +version = "0.3.74" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cc23269a4f8976d0a4d2e7109211a419fe30e8d88d677cd60b6bc79c5732e0a" +checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" dependencies = [ "addr2line", - "cc", "cfg-if", "libc", "miniz_oxide", - "object 0.36.3", + "object", "rustc-demangle", + "windows-targets 0.52.6", ] [[package]] @@ -67,14 +79,14 @@ name = "base-db" version = "0.0.0" dependencies = [ "cfg", + "dashmap", "intern", "la-arena 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "lz4_flex", - "rustc-hash 2.0.0", + "query-group-macro", + "rustc-hash 2.1.1", "salsa", "semver", "span", - "stdx", "syntax", "tracing", "triomphe", @@ -95,62 +107,65 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.7.0" +version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1be3f42a67d6d345ecd59f675f3f012d6974981560836e938c22b424b85ce1be" +checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd" [[package]] name = "borsh" -version = "1.5.1" +version = "1.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6362ed55def622cddc70a4746a68554d7b687713770de539e59a739b249f8ed" +checksum = "5430e3be710b68d984d1391c854eb431a9d548640711faa54eecb1df93db91cc" dependencies = [ - "cfg_aliases 0.2.1", + "cfg_aliases", ] [[package]] -name = "byteorder" -version = "1.5.0" +name = "boxcar" +version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" +checksum = "6740c6e2fc6360fa57c35214c7493826aee95993926092606f27c983b40837be" +dependencies = [ + "loom", +] [[package]] name = "camino" -version = "1.1.7" +version = "1.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0ec6b951b160caa93cc0c7b209e5a3bff7aae9062213451ac99493cd844c239" +checksum = "8b96ec4966b5813e2c0507c1f86115c8c5abaadc3980879c3424042a02fd1ad3" dependencies = [ "serde", ] [[package]] name = "cargo-platform" -version = "0.1.8" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24b1f0365a6c6bb4020cd05806fd0d33c44d38046b8bd7f0e40814b9763cabfc" +checksum = "e35af189006b9c0f00a064685c727031e3ed2d8020f7ba284d78cc2671bd36ea" dependencies = [ "serde", ] [[package]] name = "cargo_metadata" -version = "0.18.1" +version = "0.19.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d886547e41f740c616ae73108f6eb70afe6d940c7bc697cb30f13daec073037" +checksum = "dd5eb614ed4c27c5d706420e4320fbe3216ab31fa1c33cd8246ac36dae4479ba" dependencies = [ "camino", "cargo-platform", "semver", "serde", "serde_json", - "thiserror", + "thiserror 2.0.12", ] [[package]] name = "cc" -version = "1.1.22" +version = "1.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9540e661f81799159abee814118cc139a2004b3a3aa3ea37724a1b66530b90e0" +checksum = "be714c154be609ec7f5dad223a33bf1482fff90472de28f7362806e6d4832b8c" dependencies = [ "shlex", ] @@ -164,7 +179,7 @@ dependencies = [ "expect-test", "intern", "oorandom", - "rustc-hash 2.0.0", + "rustc-hash 2.1.1", "syntax", "syntax-bridge", "tracing", @@ -177,12 +192,6 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" -[[package]] -name = "cfg_aliases" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e" - [[package]] name = "cfg_aliases" version = "0.2.1" @@ -191,9 +200,9 @@ checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" [[package]] name = "chalk-derive" -version = "0.100.0" +version = "0.102.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab2d131019373f0d0d1f2af0abd4f719739f6583c1b33965112455f643a910af" +checksum = "feb14e3ff0ebac26d8e58b6ed1417afb60c4a0a44b6425546ee7eb9c75ebb336" dependencies = [ "proc-macro2", "quote", @@ -203,19 +212,19 @@ dependencies = [ [[package]] name = "chalk-ir" -version = "0.100.0" +version = "0.102.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f114996bda14c0213f014a4ef31a7867dcf5f539a3900477fc6b20138e7a17b" +checksum = "72f0a61621a088af69fee8df39ec63cf5b6d0b9ab663a740cdeb376aabf2f244" dependencies = [ - "bitflags 2.7.0", + "bitflags 2.9.0", "chalk-derive", ] [[package]] name = "chalk-recursive" -version = "0.100.0" +version = "0.102.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "551e956e031c09057c7b21f17d48d91de99c9b6b6e34bceaf5e7202d71021268" +checksum = "cbd3415cc540015533aa4a8ad007696d585dd9c5f81e7c099872f1dd4bf14894" dependencies = [ "chalk-derive", "chalk-ir", @@ -226,15 +235,15 @@ dependencies = [ [[package]] name = "chalk-solve" -version = "0.100.0" +version = "0.102.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd7ca50181156ce649efe8e5dd00580f573651554e4dcd11afa4e2ac93f53324" +checksum = "747707b0c082b3ecf4b1ae28d0d8df708a46cddd22a386f9cc85a312a4de25ff" dependencies = [ "chalk-derive", "chalk-ir", "ena", "indexmap", - "itertools", + "itertools 0.12.1", "petgraph", "rustc-hash 1.1.0", "tracing", @@ -263,18 +272,18 @@ dependencies = [ [[package]] name = "crossbeam-channel" -version = "0.5.13" +version = "0.5.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33480d6946193aa8033910124896ca395333cae7e2d1113d1fef6c3272217df2" +checksum = "82b8f8f868b36967f9606790d1903570de9ceaf870a7bf9fbbd3016d636a2cb2" dependencies = [ "crossbeam-utils", ] [[package]] name = "crossbeam-deque" -version = "0.8.5" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" +checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" dependencies = [ "crossbeam-epoch", "crossbeam-utils", @@ -289,30 +298,40 @@ dependencies = [ "crossbeam-utils", ] +[[package]] +name = "crossbeam-queue" +version = "0.3.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f58bbc28f91df819d0aa2a2c00cd19754769c2fad90579b3592b1c9ba7a3115" +dependencies = [ + "crossbeam-utils", +] + [[package]] name = "crossbeam-utils" -version = "0.8.20" +version = "0.8.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" +checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" [[package]] name = "ctrlc" -version = "3.4.4" +version = "3.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "672465ae37dc1bc6380a6547a8883d5dd397b0f1faaad4f265726cc7042a5345" +checksum = "90eeab0aa92f3f9b4e87f258c72b139c207d251f9cbc1080a0086b86a8870dd3" dependencies = [ "nix", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] name = "dashmap" -version = "5.5.3" +version = "6.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" +checksum = "5041cc499144891f3790297212f32a74fb938e5136a14943f338ef9e0ae276cf" dependencies = [ "cfg-if", - "hashbrown", + "crossbeam-utils", + "hashbrown 0.14.5", "lock_api", "once_cell", "parking_lot_core", @@ -320,18 +339,18 @@ dependencies = [ [[package]] name = "deranged" -version = "0.3.11" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" +checksum = "9c9e6a11ca8224451684bc0d7d5a7adbf8f2fd6887261a1cfc3c0432f9d4068e" dependencies = [ "powerfmt", ] [[package]] name = "derive_arbitrary" -version = "1.3.2" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67e77553c4162a157adbf834ebae5b415acbecbeafc7a74b0e886657506a7611" +checksum = "30542c1ad912e0e3d22a1935c290e12e8a29d704a420177a31faad4a601a0800" dependencies = [ "proc-macro2", "quote", @@ -340,39 +359,50 @@ dependencies = [ [[package]] name = "directories" -version = "5.0.1" +version = "6.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a49173b84e034382284f27f1af4dcbbd231ffa358c0fe316541a7337f376a35" +checksum = "16f5094c54661b38d03bd7e50df373292118db60b585c08a411c6d840017fe7d" dependencies = [ "dirs-sys", ] [[package]] name = "dirs" -version = "5.0.1" +version = "6.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44c45a9d03d6676652bcb5e724c7e988de1acad23a711b5217ab9cbecbec2225" +checksum = "c3e8aa94d75141228480295a7d0e7feb620b1a5ad9f12bc40be62411e38cce4e" dependencies = [ "dirs-sys", ] [[package]] name = "dirs-sys" -version = "0.4.1" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c" +checksum = "e01a3366d27ee9890022452ee61b2b63a67e6f13f58900b651ff5665f0bb1fab" dependencies = [ "libc", "option-ext", "redox_users", - "windows-sys 0.48.0", + "windows-sys 0.59.0", +] + +[[package]] +name = "displaydoc" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" +dependencies = [ + "proc-macro2", + "quote", + "syn", ] [[package]] name = "dissimilar" -version = "1.0.9" +version = "1.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59f8e79d1fbf76bdfbde321e902714bf6c49df88a7dda6fc682fc2979226962d" +checksum = "8975ffdaa0ef3661bfe02dbdcc06c9f829dfafe6a3c474de366a8d5e44276921" [[package]] name = "dot" @@ -392,9 +422,9 @@ version = "0.0.0" [[package]] name = "either" -version = "1.13.0" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" +checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" [[package]] name = "ena" @@ -407,15 +437,15 @@ dependencies = [ [[package]] name = "equivalent" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" [[package]] name = "expect-test" -version = "1.5.0" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e0be0a561335815e06dab7c62e50353134c796e7a6155402a64bcff66b6a5e0" +checksum = "63af43ff4431e848fb47472a920f14fa71c24de13255a5692e93d4e90302acb0" dependencies = [ "dissimilar", "once_cell", @@ -423,9 +453,9 @@ dependencies = [ [[package]] name = "filetime" -version = "0.2.24" +version = "0.2.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf401df4a4e3872c4fe8151134cf483738e74b67fc934d6532c882b3d24a4550" +checksum = "35c0522e981e68cbfa8c3f978441a5f34b30b96e146b33cd3359176b50fe8586" dependencies = [ "cfg-if", "libc", @@ -441,14 +471,20 @@ checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" [[package]] name = "flate2" -version = "1.0.31" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f211bbe8e69bbd0cfdea405084f128ae8b4aaa6b0b522fc8f2b009084797920" +checksum = "11faaf5a5236997af9848be0bef4db95824b1d534ebc64d0f0c6cf3e67bd38dc" dependencies = [ "crc32fast", "miniz_oxide", ] +[[package]] +name = "foldhash" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0d2fde1f7b3d48b8395d5f2de76c18a528bd6a9cdde438df747bfcba3e05d6f" + [[package]] name = "form_urlencoded" version = "1.2.1" @@ -473,6 +509,19 @@ version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ab85b9b05e3978cc9a9cf8fea7f01b494e1a09ed3037e16ba39edc7a29eb61a" +[[package]] +name = "generator" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc6bd114ceda131d3b1d665eba35788690ad37f5916457286b32ab6fd3c438dd" +dependencies = [ + "cfg-if", + "libc", + "log", + "rustversion", + "windows 0.58.0", +] + [[package]] name = "getrandom" version = "0.2.15" @@ -486,9 +535,9 @@ dependencies = [ [[package]] name = "gimli" -version = "0.29.0" +version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd" +checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" [[package]] name = "hashbrown" @@ -496,11 +545,31 @@ version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" +[[package]] +name = "hashbrown" +version = "0.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" +dependencies = [ + "allocator-api2", + "equivalent", + "foldhash", +] + +[[package]] +name = "hashlink" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7382cf6263419f2d8df38c55d7da83da5c18aef87fc7a7fc1fb1e344edfe14c1" +dependencies = [ + "hashbrown 0.15.2", +] + [[package]] name = "heck" -version = "0.4.1" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" [[package]] name = "hermit-abi" @@ -522,8 +591,8 @@ dependencies = [ "hir-ty", "indexmap", "intern", - "itertools", - "rustc-hash 2.0.0", + "itertools 0.14.0", + "rustc-hash 2.1.1", "smallvec", "span", "stdx", @@ -542,26 +611,25 @@ version = "0.0.0" dependencies = [ "arrayvec", "base-db", - "bitflags 2.7.0", + "bitflags 2.9.0", "cfg", "cov-mark", - "dashmap", "drop_bomb", "either", "expect-test", "fst", - "hashbrown", "hir-expand", "indexmap", "intern", - "itertools", + "itertools 0.14.0", "la-arena 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "mbe", + "query-group-macro", "ra-ap-rustc_abi", - "ra-ap-rustc_hashes", "ra-ap-rustc_parse_format", - "rustc-hash 2.0.0", + "rustc-hash 2.1.1", "rustc_apfloat", + "salsa", "smallvec", "span", "stdx", @@ -570,6 +638,7 @@ dependencies = [ "test-fixture", "test-utils", "text-size", + "thin-vec", "tracing", "triomphe", "tt", @@ -584,13 +653,13 @@ dependencies = [ "cov-mark", "either", "expect-test", - "hashbrown", "intern", - "itertools", - "la-arena 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", + "itertools 0.14.0", "mbe", "parser", - "rustc-hash 2.0.0", + "query-group-macro", + "rustc-hash 2.1.1", + "salsa", "smallvec", "span", "stdx", @@ -607,7 +676,7 @@ version = "0.0.0" dependencies = [ "arrayvec", "base-db", - "bitflags 2.7.0", + "bitflags 2.9.0", "chalk-derive", "chalk-ir", "chalk-recursive", @@ -620,16 +689,17 @@ dependencies = [ "hir-expand", "indexmap", "intern", - "itertools", + "itertools 0.14.0", "la-arena 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "nohash-hasher", "oorandom", "project-model", + "query-group-macro", "ra-ap-rustc_abi", "ra-ap-rustc_index", "ra-ap-rustc_pattern_analysis", - "rustc-hash 2.0.0", + "rustc-hash 2.1.1", "rustc_apfloat", + "salsa", "scoped-tls", "smallvec", "span", @@ -646,11 +716,129 @@ dependencies = [ [[package]] name = "home" -version = "0.5.9" +version = "0.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5" +checksum = "589533453244b0995c858700322199b2becb13b627df2851f64a2775d024abcf" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.59.0", +] + +[[package]] +name = "icu_collections" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526" +dependencies = [ + "displaydoc", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_locid" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637" +dependencies = [ + "displaydoc", + "litemap", + "tinystr", + "writeable", + "zerovec", +] + +[[package]] +name = "icu_locid_transform" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01d11ac35de8e40fdeda00d9e1e9d92525f3f9d887cdd7aa81d727596788b54e" +dependencies = [ + "displaydoc", + "icu_locid", + "icu_locid_transform_data", + "icu_provider", + "tinystr", + "zerovec", +] + +[[package]] +name = "icu_locid_transform_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdc8ff3388f852bede6b579ad4e978ab004f139284d7b28715f773507b946f6e" + +[[package]] +name = "icu_normalizer" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_normalizer_data", + "icu_properties", + "icu_provider", + "smallvec", + "utf16_iter", + "utf8_iter", + "write16", + "zerovec", +] + +[[package]] +name = "icu_normalizer_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8cafbf7aa791e9b22bec55a167906f9e1215fd475cd22adfcf660e03e989516" + +[[package]] +name = "icu_properties" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93d6020766cfc6302c15dbbc9c8778c37e62c14427cb7f6e601d849e092aeef5" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_locid_transform", + "icu_properties_data", + "icu_provider", + "tinystr", + "zerovec", +] + +[[package]] +name = "icu_properties_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67a8effbc3dd3e4ba1afa8ad918d5684b8868b3b26500753effea8d2eed19569" + +[[package]] +name = "icu_provider" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9" +dependencies = [ + "displaydoc", + "icu_locid", + "icu_provider_macros", + "stable_deref_trait", + "tinystr", + "writeable", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_provider_macros" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" +dependencies = [ + "proc-macro2", + "quote", + "syn", ] [[package]] @@ -669,7 +857,7 @@ dependencies = [ "ide-db", "ide-diagnostics", "ide-ssr", - "itertools", + "itertools 0.14.0", "nohash-hasher", "oorandom", "profile", @@ -697,7 +885,7 @@ dependencies = [ "expect-test", "hir", "ide-db", - "itertools", + "itertools 0.14.0", "smallvec", "stdx", "syntax", @@ -715,7 +903,7 @@ dependencies = [ "expect-test", "hir", "ide-db", - "itertools", + "itertools 0.14.0", "smallvec", "stdx", "syntax", @@ -730,7 +918,7 @@ version = "0.0.0" dependencies = [ "arrayvec", "base-db", - "bitflags 2.7.0", + "bitflags 2.9.0", "cov-mark", "crossbeam-channel", "either", @@ -738,14 +926,16 @@ dependencies = [ "fst", "hir", "indexmap", - "itertools", + "itertools 0.14.0", "line-index 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "memchr", "nohash-hasher", "parser", "profile", + "query-group-macro", "rayon", - "rustc-hash 2.0.0", + "rustc-hash 2.1.1", + "salsa", "span", "stdx", "syntax", @@ -753,6 +943,7 @@ dependencies = [ "test-utils", "tracing", "triomphe", + "vfs", ] [[package]] @@ -765,7 +956,7 @@ dependencies = [ "expect-test", "hir", "ide-db", - "itertools", + "itertools 0.14.0", "paths", "serde_json", "stdx", @@ -783,10 +974,8 @@ dependencies = [ "expect-test", "hir", "ide-db", - "itertools", - "nohash-hasher", + "itertools 0.14.0", "parser", - "stdx", "syntax", "test-fixture", "test-utils", @@ -795,22 +984,34 @@ dependencies = [ [[package]] name = "idna" -version = "0.5.0" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e" +dependencies = [ + "idna_adapter", + "smallvec", + "utf8_iter", +] + +[[package]] +name = "idna_adapter" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" +checksum = "daca1df1c957320b2cf139ac61e7bd64fed304c5040df000a745aa1de3b4ef71" dependencies = [ - "unicode-bidi", - "unicode-normalization", + "icu_normalizer", + "icu_properties", ] [[package]] name = "indexmap" -version = "2.3.0" +version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de3fc2e30ba82dd1b3911c8de1ffc143c74a914a14e99514d7637e3099df5ea0" +checksum = "3954d50fe15b02142bf25d3b8bdadb634ec3948f103d04ffe3031bc8fe9d7058" dependencies = [ "equivalent", - "hashbrown", + "hashbrown 0.15.2", + "serde", ] [[package]] @@ -819,7 +1020,7 @@ version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f37dccff2791ab604f9babef0ba14fbe0be30bd368dc541e2b08d07c8aa908f3" dependencies = [ - "bitflags 2.7.0", + "bitflags 2.9.0", "inotify-sys", "libc", ] @@ -838,8 +1039,8 @@ name = "intern" version = "0.0.0" dependencies = [ "dashmap", - "hashbrown", - "rustc-hash 2.0.0", + "hashbrown 0.14.5", + "rustc-hash 2.1.1", "triomphe", ] @@ -852,17 +1053,26 @@ dependencies = [ "either", ] +[[package]] +name = "itertools" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285" +dependencies = [ + "either", +] + [[package]] name = "itoa" -version = "1.0.11" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" +checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" [[package]] name = "jod-thread" -version = "0.1.2" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b23360e99b8717f20aaa4598f5a6541efbe30630039fbc7706cf954a87947ae" +checksum = "a037eddb7d28de1d0fc42411f501b53b75838d313908078d6698d064f3029b24" [[package]] name = "kqueue" @@ -908,9 +1118,9 @@ checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa" [[package]] name = "libloading" -version = "0.8.5" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4" +checksum = "fc2f4eb4bc735547cfed7c0a4922cbd04a4655978c09b54f1f7b228750664c34" dependencies = [ "cfg-if", "windows-targets 0.52.6", @@ -918,9 +1128,9 @@ dependencies = [ [[package]] name = "libmimalloc-sys" -version = "0.1.39" +version = "0.1.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23aa6811d3bd4deb8a84dde645f943476d13b248d818edcf8ce0b2f37f036b44" +checksum = "07d0e07885d6a754b9c7993f2625187ad694ee985d60f23355ff0e7077261502" dependencies = [ "cc", "libc", @@ -932,7 +1142,7 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" dependencies = [ - "bitflags 2.7.0", + "bitflags 2.9.0", "libc", "redox_syscall", ] @@ -957,10 +1167,10 @@ dependencies = [ ] [[package]] -name = "linked-hash-map" -version = "0.5.6" +name = "litemap" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" +checksum = "23fb14cb19457329c82206317a5663005a4d404783dc74f4252769b0d5f42856" [[package]] name = "load-cargo" @@ -971,8 +1181,7 @@ dependencies = [ "hir-expand", "ide-db", "intern", - "itertools", - "paths", + "itertools 0.14.0", "proc-macro-api", "project-model", "span", @@ -994,30 +1203,44 @@ dependencies = [ [[package]] name = "log" -version = "0.4.22" +version = "0.4.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" +checksum = "30bde2b3dc3671ae49d8e2e9f044c7c005836e7a023ee57cffa25ab82764bb9e" [[package]] -name = "lsp-server" -version = "0.7.7" +name = "loom" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "550446e84739dcaf6d48a4a093973850669e13e8a34d8f8d64851041be267cd9" +checksum = "419e0dc8046cb947daa77eb95ae174acfbddb7673b4151f56d1eed8e93fbfaca" +dependencies = [ + "cfg-if", + "generator", + "scoped-tls", + "tracing", + "tracing-subscriber", +] + +[[package]] +name = "lsp-server" +version = "0.7.8" dependencies = [ "crossbeam-channel", + "ctrlc", "log", + "lsp-types", "serde", + "serde_derive", "serde_json", ] [[package]] name = "lsp-server" version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9462c4dc73e17f971ec1f171d44bfffb72e65a130117233388a0ebc7ec5656f9" dependencies = [ "crossbeam-channel", - "ctrlc", "log", - "lsp-types", "serde", "serde_derive", "serde_json", @@ -1037,10 +1260,13 @@ dependencies = [ ] [[package]] -name = "lz4_flex" -version = "0.11.3" +name = "matchers" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75761162ae2b0e580d7e7c390558127e5f01b4194debd6221fd8c207fc80e3f5" +checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" +dependencies = [ + "regex-automata 0.1.10", +] [[package]] name = "mbe" @@ -1052,14 +1278,13 @@ dependencies = [ "intern", "parser", "ra-ap-rustc_lexer", - "rustc-hash 2.0.0", + "rustc-hash 2.1.1", "smallvec", "span", "stdx", "syntax", "syntax-bridge", "test-utils", - "tracing", "tt", ] @@ -1071,9 +1296,9 @@ checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" [[package]] name = "memmap2" -version = "0.5.10" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83faa42c0a078c393f6b29d5db232d8be22776a891f8f56e5284faee4a20b327" +checksum = "fd3f7eed9d3848f8b98834af67102b720745c4ec028fcd0aa0239277e7de374f" dependencies = [ "libc", ] @@ -1089,20 +1314,20 @@ dependencies = [ [[package]] name = "mimalloc" -version = "0.1.43" +version = "0.1.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68914350ae34959d83f732418d51e2427a794055d0b9529f48259ac07af65633" +checksum = "99585191385958383e13f6b822e6b6d8d9cf928e7d286ceb092da92b43c87bc1" dependencies = [ "libmimalloc-sys", ] [[package]] name = "miniz_oxide" -version = "0.7.4" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08" +checksum = "8e3e04debbb59698c15bacbb6d93584a8c0ca9cc3213cb423d31f760d8843ce5" dependencies = [ - "adler", + "adler2", ] [[package]] @@ -1128,13 +1353,13 @@ dependencies = [ [[package]] name = "nix" -version = "0.28.0" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab2156c4fce2f8df6c499cc1c763e4394b7482525bf2a9701c9d79d215f519e4" +checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46" dependencies = [ - "bitflags 2.7.0", + "bitflags 2.9.0", "cfg-if", - "cfg_aliases 0.1.1", + "cfg_aliases", "libc", ] @@ -1150,7 +1375,7 @@ version = "8.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2fee8403b3d66ac7b26aee6e40a897d85dc5ce26f44da36b8b73e987cc52e943" dependencies = [ - "bitflags 2.7.0", + "bitflags 2.9.0", "filetime", "fsevent-sys", "inotify", @@ -1169,6 +1394,16 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5e0826a989adedc2a244799e823aece04662b66609d96af8dff7ac6df9a8925d" +[[package]] +name = "nu-ansi-term" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" +dependencies = [ + "overload", + "winapi", +] + [[package]] name = "nu-ansi-term" version = "0.50.1" @@ -1205,33 +1440,24 @@ dependencies = [ [[package]] name = "object" -version = "0.33.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8dd6c0cdf9429bce006e1362bfce61fa1bfd8c898a643ed8d2b471934701d3d" -dependencies = [ - "memchr", -] - -[[package]] -name = "object" -version = "0.36.3" +version = "0.36.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27b64972346851a39438c60b341ebc01bba47464ae329e55cf343eb93964efd9" +checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" dependencies = [ "memchr", ] [[package]] name = "once_cell" -version = "1.19.0" +version = "1.21.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" +checksum = "d75b0bedcc4fe52caa0e03d9f1151a323e4aa5e2d78ba3580400cd3c9e2bc4bc" [[package]] name = "oorandom" -version = "11.1.4" +version = "11.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b410bbe7e14ab526a0e86877eb47c6996a2bd7746f027ba551028c925390e4e9" +checksum = "d6790f58c7ff633d8771f42965289203411a5e5c68388703c06e14f24770b41e" [[package]] name = "option-ext" @@ -1239,6 +1465,12 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" +[[package]] +name = "overload" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" + [[package]] name = "parking_lot" version = "0.12.3" @@ -1325,24 +1557,21 @@ dependencies = [ [[package]] name = "pin-project-lite" -version = "0.2.14" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" +checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" [[package]] -name = "powerfmt" -version = "0.2.0" +name = "portable-atomic" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" +checksum = "350e9b48cbc6b0e028b0473b114454c6316e57336ee184ceab6e53f72c178b3e" [[package]] -name = "ppv-lite86" -version = "0.2.20" +name = "powerfmt" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" -dependencies = [ - "zerocopy", -] +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" [[package]] name = "proc-macro-api" @@ -1351,7 +1580,7 @@ dependencies = [ "indexmap", "intern", "paths", - "rustc-hash 2.0.0", + "rustc-hash 2.1.1", "serde", "serde_derive", "serde_json", @@ -1370,12 +1599,11 @@ dependencies = [ "libc", "libloading", "memmap2", - "object 0.33.0", + "object", "paths", "proc-macro-test", "ra-ap-rustc_lexer", "span", - "stdx", "syntax-bridge", "tt", ] @@ -1398,23 +1626,23 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.93" +version = "1.0.94" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60946a68e5f9d28b0dc1c21bb8a97ee7d018a8b322fa57838ba31cc878e22d99" +checksum = "a31971752e70b8b2686d7e46ec17fb38dad4051d94024c88df49b667caea9c84" dependencies = [ "unicode-ident", ] [[package]] name = "process-wrap" -version = "8.0.2" +version = "8.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38ee68ae331824036479c84060534b18254c864fa73366c58d86db3b7b811619" +checksum = "d35f4dc9988d1326b065b4def5e950c3ed727aa03e3151b86cc9e2aec6b03f54" dependencies = [ "indexmap", "nix", "tracing", - "windows", + "windows 0.59.0", ] [[package]] @@ -1438,10 +1666,10 @@ dependencies = [ "cfg", "expect-test", "intern", - "itertools", + "itertools 0.14.0", "la-arena 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "paths", - "rustc-hash 2.0.0", + "rustc-hash 2.1.1", "semver", "serde", "serde_derive", @@ -1461,7 +1689,7 @@ checksum = "a3a7c64d9bf75b1b8d981124c14c179074e8caa7dfe7b6a12e6222ddcd0c8f72" dependencies = [ "once_cell", "protobuf-support", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -1470,7 +1698,7 @@ version = "3.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b088fd20b938a875ea00843b6faf48579462630015c3788d397ad6a786663252" dependencies = [ - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -1479,7 +1707,7 @@ version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "57206b407293d2bcd3af849ce869d52068623f19e1b5ff8e8778e3309439682b" dependencies = [ - "bitflags 2.7.0", + "bitflags 2.9.0", "memchr", "unicase", ] @@ -1493,22 +1721,33 @@ dependencies = [ "pulldown-cmark", ] +[[package]] +name = "query-group-macro" +version = "0.0.0" +dependencies = [ + "expect-test", + "proc-macro2", + "quote", + "salsa", + "syn", +] + [[package]] name = "quote" -version = "1.0.36" +version = "1.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" dependencies = [ "proc-macro2", ] [[package]] name = "ra-ap-rustc_abi" -version = "0.100.0" +version = "0.110.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1651b0f7e8c3eb7c27a88f39d277e69c32bfe58e3be174d286c1a24d6a7a4d8" +checksum = "912228bd8ed3beff1f6f9e5e2d4b37c0827ba3e2070060bf3858a311d0e29e30" dependencies = [ - "bitflags 2.7.0", + "bitflags 2.9.0", "ra-ap-rustc_hashes", "ra-ap-rustc_index", "tracing", @@ -1516,18 +1755,18 @@ dependencies = [ [[package]] name = "ra-ap-rustc_hashes" -version = "0.100.0" +version = "0.110.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bcd85e93dc0ea850bcfe7957a115957df799ccbc9eea488bdee5ec6780d212b" +checksum = "ba520764daf057a9d963fa769f4762eaf87ac5d4900ae76195eeead64cd35afd" dependencies = [ "rustc-stable-hash", ] [[package]] name = "ra-ap-rustc_index" -version = "0.100.0" +version = "0.110.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b295fc0640cd9fe0ecab872ee4a17a96f90a3998ec9f0c4765e9b8415c12cc" +checksum = "b76b5f9ee55f2d0e5a65bea23f6d738893349ce8d3d17a6720933e647ab04978" dependencies = [ "ra-ap-rustc_index_macros", "smallvec", @@ -1535,9 +1774,9 @@ dependencies = [ [[package]] name = "ra-ap-rustc_index_macros" -version = "0.100.0" +version = "0.110.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c675f4257023aa933882906f13802cae287e88cc39ab13cbb96809083db0c801" +checksum = "ddd972eb1face2fcaa0d94c01d97862fb955b5561d4f5932003bce8a6cadd8c6" dependencies = [ "proc-macro2", "quote", @@ -1546,9 +1785,9 @@ dependencies = [ [[package]] name = "ra-ap-rustc_lexer" -version = "0.100.0" +version = "0.110.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8358702c2a510ea84ba5801ddc047d9ad9520902cfb0e6173277610cdce2c9c" +checksum = "ba3a9876456fb2521097deef33ddeac1c18260c8eafb68054d986f8b9d6ce9fa" dependencies = [ "memchr", "unicode-properties", @@ -1557,97 +1796,111 @@ dependencies = [ [[package]] name = "ra-ap-rustc_parse_format" -version = "0.100.0" +version = "0.110.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b98f402011d46732c35c47bfd111dec0495747fef2ec900ddee7fe15d78449a7" +checksum = "8e85de58dfcc60a5f9d5ec0157a657e3f84abd8f22c8a0c4d707cfb42c9011f4" dependencies = [ - "ra-ap-rustc_index", "ra-ap-rustc_lexer", + "rustc-literal-escaper", ] [[package]] name = "ra-ap-rustc_pattern_analysis" -version = "0.100.0" +version = "0.110.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef3ff73fa4653252ffe1d1e9177a446f49ef46d97140e4816b7ff2dad59ed53" +checksum = "ceadf9db550db67deff7eff2e2765109b860c9d7e5bdfca144863020289c823d" dependencies = [ "ra-ap-rustc_index", - "rustc-hash 2.0.0", + "rustc-hash 2.1.1", "rustc_apfloat", "smallvec", "tracing", ] [[package]] -name = "rand" -version = "0.8.5" +name = "rayon" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" dependencies = [ - "libc", - "rand_chacha", - "rand_core", + "either", + "rayon-core", ] [[package]] -name = "rand_chacha" -version = "0.3.1" +name = "rayon-core" +version = "1.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" dependencies = [ - "ppv-lite86", - "rand_core", + "crossbeam-deque", + "crossbeam-utils", ] [[package]] -name = "rand_core" -version = "0.6.4" +name = "redox_syscall" +version = "0.5.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +checksum = "0b8c0c260b63a8219631167be35e6a988e9554dbd323f8bd08439c8ed1302bd1" dependencies = [ - "getrandom", + "bitflags 2.9.0", ] [[package]] -name = "rayon" -version = "1.10.0" +name = "redox_users" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" +checksum = "dd6f9d3d47bdd2ad6945c5015a226ec6155d0bcdfd8f7cd29f86b71f8de99d2b" dependencies = [ - "either", - "rayon-core", + "getrandom", + "libredox", + "thiserror 2.0.12", ] [[package]] -name = "rayon-core" -version = "1.12.1" +name = "regex" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" +checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" dependencies = [ - "crossbeam-deque", - "crossbeam-utils", + "aho-corasick", + "memchr", + "regex-automata 0.4.9", + "regex-syntax 0.8.5", ] [[package]] -name = "redox_syscall" -version = "0.5.3" +name = "regex-automata" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a908a6e00f1fdd0dfd9c0eb08ce85126f6d8bbda50017e74bc4a4b7d4a926a4" +checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" dependencies = [ - "bitflags 2.7.0", + "regex-syntax 0.6.29", ] [[package]] -name = "redox_users" -version = "0.4.5" +name = "regex-automata" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd283d9651eeda4b2a83a43c1c91b266c40fd76ecd39a50a8c630ae69dc72891" +checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" dependencies = [ - "getrandom", - "libredox", - "thiserror", + "aho-corasick", + "memchr", + "regex-syntax 0.8.5", ] +[[package]] +name = "regex-syntax" +version = "0.6.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" + +[[package]] +name = "regex-syntax" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" + [[package]] name = "rowan" version = "0.15.15" @@ -1655,7 +1908,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a58fa8a7ccff2aec4f39cc45bf5f985cec7125ab271cf681c279fd00192b49" dependencies = [ "countme", - "hashbrown", + "hashbrown 0.14.5", "memoffset", "rustc-hash 1.1.0", "text-size", @@ -1665,7 +1918,6 @@ dependencies = [ name = "rust-analyzer" version = "0.0.0" dependencies = [ - "always-assert", "anyhow", "base64", "cargo_metadata", @@ -1681,10 +1933,11 @@ dependencies = [ "ide-completion", "ide-db", "ide-ssr", + "indexmap", "intern", - "itertools", + "itertools 0.14.0", "load-cargo", - "lsp-server 0.7.7", + "lsp-server 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)", "lsp-types", "memchr", "mimalloc", @@ -1699,7 +1952,7 @@ dependencies = [ "profile", "project-model", "rayon", - "rustc-hash 2.0.0", + "rustc-hash 2.1.1", "scip", "semver", "serde", @@ -1740,9 +1993,9 @@ checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" [[package]] name = "rustc-hash" -version = "2.0.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "583034fd73374156e66797ed8e5b0d5690409c9226b22d87cb7f19821c05d152" +checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" [[package]] name = "rustc-literal-escaper" @@ -1752,54 +2005,72 @@ checksum = "0041b6238913c41fe704213a4a9329e2f685a156d1781998128b4149c230ad04" [[package]] name = "rustc-stable-hash" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2febf9acc5ee5e99d1ad0afcdbccc02d87aa3f857a1f01f825b80eacf8edfcd1" +checksum = "781442f29170c5c93b7185ad559492601acdc71d5bb0706f5868094f45cfcd08" [[package]] name = "rustc_apfloat" -version = "0.2.1+llvm-462a31f5a5ab" +version = "0.2.2+llvm-462a31f5a5ab" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "886d94c63c812a8037c4faca2607453a0fa4cf82f734665266876b022244543f" +checksum = "121e2195ff969977a4e2b5c9965ea867fce7e4cb5aee5b09dee698a7932d574f" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.9.0", "smallvec", ] +[[package]] +name = "rustversion" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eded382c5f5f786b989652c49544c4877d9f015cc22e145a5ea8ea66c2921cd2" + [[package]] name = "ryu" -version = "1.0.18" +version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" +checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" [[package]] name = "salsa" -version = "0.0.0" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1be22155f8d9732518b2db2bf379fe6f0b2375e76b08b7c8fe6c1b887d548c24" dependencies = [ - "dissimilar", - "expect-test", + "boxcar", + "crossbeam-queue", + "dashmap", + "hashbrown 0.15.2", + "hashlink", "indexmap", - "itertools", - "linked-hash-map", - "lock_api", - "oorandom", "parking_lot", - "rand", - "rustc-hash 2.0.0", + "portable-atomic", + "rayon", + "rustc-hash 2.1.1", + "salsa-macro-rules", "salsa-macros", "smallvec", + "thin-vec", "tracing", - "triomphe", ] +[[package]] +name = "salsa-macro-rules" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f55a7ef0a84e336f7c5f0332d81727f5629fe042d2aa556c75307afebc9f78a5" + [[package]] name = "salsa-macros" -version = "0.0.0" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d0e88a9c0c0d231a63f83dcd1a2c5e5d11044fac4b65bc9ad3b68ab48b0a0ab" dependencies = [ "heck", "proc-macro2", "quote", "syn", + "synstructure", ] [[package]] @@ -1813,9 +2084,9 @@ dependencies = [ [[package]] name = "scip" -version = "0.5.1" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8dfafd2fa14c6237fa1fc4310f739d02fa915d92977fa069426591f1de046f81" +checksum = "fb2b449a5e4660ce817676a0871cd1b4e2ff1023e33a1ac046670fa594b543a2" dependencies = [ "protobuf", ] @@ -1834,27 +2105,27 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "semver" -version = "1.0.23" +version = "1.0.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" +checksum = "56e6fa9c48d24d85fb3de5ad847117517440f6beceb7798af16b4a87d616b8d0" dependencies = [ "serde", ] [[package]] name = "serde" -version = "1.0.216" +version = "1.0.219" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b9781016e935a97e8beecf0c933758c97a5520d32930e460142b4cd80c6338e" +checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.216" +version = "1.0.219" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46f859dbbf73865c6627ed570e78961cd3ac92407a2d117204c49232485da55e" +checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" dependencies = [ "proc-macro2", "quote", @@ -1863,9 +2134,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.124" +version = "1.0.140" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66ad62847a56b3dba58cc891acd13884b9c61138d330c0d7b6181713d4fce38d" +checksum = "20068b6e96dc6c9bd23e01df8827e6c7e1f2fddd43c21810382803c136b99373" dependencies = [ "indexmap", "itoa", @@ -1876,9 +2147,9 @@ dependencies = [ [[package]] name = "serde_repr" -version = "0.1.19" +version = "0.1.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9" +checksum = "175ee3e80ae9982737ca543e96133087cbd9a485eecc3bc4de9c1a37b47ea59c" dependencies = [ "proc-macro2", "quote", @@ -1887,9 +2158,9 @@ dependencies = [ [[package]] name = "serde_spanned" -version = "0.6.7" +version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb5b1b31579f3811bf615c144393417496f152e12ac8b7663bf664f4a815306d" +checksum = "87607cb1398ed59d48732e575a4c28a7a8ebf2454b964fe3f224f2afc07909e1" dependencies = [ "serde", ] @@ -1911,9 +2182,9 @@ checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" [[package]] name = "smallvec" -version = "1.13.2" +version = "1.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" +checksum = "7fcf8323ef1faaee30a44a340193b1ac6814fd9b7b4e88e9d4519a3e4abe1cfd" [[package]] name = "smol_str" @@ -1929,9 +2200,9 @@ dependencies = [ name = "span" version = "0.0.0" dependencies = [ - "hashbrown", + "hashbrown 0.14.5", "la-arena 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rustc-hash 2.0.0", + "rustc-hash 2.1.1", "salsa", "stdx", "syntax", @@ -1939,13 +2210,19 @@ dependencies = [ "vfs", ] +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + [[package]] name = "stdx" version = "0.0.0" dependencies = [ "backtrace", "crossbeam-channel", - "itertools", + "itertools 0.14.0", "jod-thread", "libc", "miow", @@ -1955,9 +2232,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.87" +version = "2.0.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25aa4ce346d03a6dcd68dd8b4010bcb74e54e62c90c573f394c46eae99aba32d" +checksum = "b09a44accad81e1ba1cd74a32461ba89dee89095ba17b32f5d03683b1b1fc2a0" dependencies = [ "proc-macro2", "quote", @@ -1979,15 +2256,13 @@ dependencies = [ name = "syntax" version = "0.0.0" dependencies = [ - "cov-mark", "either", "expect-test", - "indexmap", - "itertools", + "itertools 0.14.0", "parser", "rayon", "rowan", - "rustc-hash 2.0.0", + "rustc-hash 2.1.1", "rustc-literal-escaper", "rustc_apfloat", "smol_str", @@ -2003,12 +2278,11 @@ version = "0.0.0" dependencies = [ "intern", "parser", - "rustc-hash 2.0.0", + "rustc-hash 2.1.1", "span", "stdx", "syntax", "test-utils", - "tracing", "tt", ] @@ -2026,10 +2300,12 @@ dependencies = [ "cfg", "hir-expand", "intern", - "rustc-hash 2.0.0", + "paths", + "rustc-hash 2.1.1", "span", "stdx", "test-utils", + "triomphe", "tt", ] @@ -2040,10 +2316,9 @@ dependencies = [ "dissimilar", "paths", "profile", - "rustc-hash 2.0.0", + "rustc-hash 2.1.1", "stdx", "text-size", - "tracing", ] [[package]] @@ -2052,20 +2327,46 @@ version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f18aa187839b2bdb1ad2fa35ead8c4c2976b64e4363c386d45ac0f7ee85c9233" +[[package]] +name = "thin-vec" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "144f754d318415ac792f9d69fc87abbbfc043ce2ef041c60f16ad828f638717d" + [[package]] name = "thiserror" -version = "1.0.63" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" dependencies = [ - "thiserror-impl", + "thiserror-impl 1.0.69", +] + +[[package]] +name = "thiserror" +version = "2.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708" +dependencies = [ + "thiserror-impl 2.0.12", ] [[package]] name = "thiserror-impl" -version = "1.0.63" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "thiserror-impl" +version = "2.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d" dependencies = [ "proc-macro2", "quote", @@ -2115,9 +2416,9 @@ dependencies = [ [[package]] name = "time" -version = "0.3.36" +version = "0.3.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" +checksum = "9d9c75b47bdff86fa3334a3db91356b8d7d86a9b839dab7d0bdc5c3d3a077618" dependencies = [ "deranged", "itoa", @@ -2132,40 +2433,35 @@ dependencies = [ [[package]] name = "time-core" -version = "0.1.2" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" +checksum = "c9e9a38711f559d9e3ce1cdb06dd7c5b8ea546bc90052da6d06bb76da74bb07c" [[package]] name = "time-macros" -version = "0.2.18" +version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf" +checksum = "29aa485584182073ed57fd5004aa09c371f021325014694e432313345865fd04" dependencies = [ "num-conv", "time-core", ] [[package]] -name = "tinyvec" -version = "1.8.0" +name = "tinystr" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "445e881f4f6d382d5f27c034e25eb92edd7c784ceab92a0937db7f2e9471b938" +checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f" dependencies = [ - "tinyvec_macros", + "displaydoc", + "zerovec", ] -[[package]] -name = "tinyvec_macros" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" - [[package]] name = "toml" -version = "0.8.19" +version = "0.8.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1ed1f98e3fdc28d6d910e6737ae6ab1a93bf1985935a1193e68f93eeb68d24e" +checksum = "cd87a5cdd6ffab733b2f74bc4fd7ee5fff6634124999ac278c35fc78c6120148" dependencies = [ "serde", "serde_spanned", @@ -2184,9 +2480,9 @@ dependencies = [ [[package]] name = "toml_edit" -version = "0.22.20" +version = "0.22.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "583c44c02ad26b0c3f3066fe629275e50627026c51ac2e595cca4c230ce1ce1d" +checksum = "17b4795ff5edd201c7cd6dca065ae59972ce77d1b80fa0a84d94950ece7d1474" dependencies = [ "indexmap", "serde", @@ -2205,9 +2501,9 @@ dependencies = [ [[package]] name = "tracing" -version = "0.1.40" +version = "0.1.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" dependencies = [ "pin-project-lite", "tracing-attributes", @@ -2216,9 +2512,9 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.27" +version = "0.1.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" +checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d" dependencies = [ "proc-macro2", "quote", @@ -2227,9 +2523,9 @@ dependencies = [ [[package]] name = "tracing-core" -version = "0.1.32" +version = "0.1.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c" dependencies = [ "once_cell", "valuable", @@ -2248,24 +2544,30 @@ dependencies = [ [[package]] name = "tracing-subscriber" -version = "0.3.18" +version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" +checksum = "e8189decb5ac0fa7bc8b96b7cb9b2701d60d48805aca84a238004d665fcc4008" dependencies = [ + "matchers", + "nu-ansi-term 0.46.0", + "once_cell", + "regex", "sharded-slab", + "smallvec", "thread_local", "time", + "tracing", "tracing-core", "tracing-log", ] [[package]] name = "tracing-tree" -version = "0.3.1" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b56c62d2c80033cb36fae448730a2f2ef99410fe3ecbffc916681a32f6807dbe" +checksum = "f459ca79f1b0d5f71c54ddfde6debfc59c8b6eeb46808ae492077f739dc7b49c" dependencies = [ - "nu-ansi-term", + "nu-ansi-term 0.50.1", "tracing-core", "tracing-log", "tracing-subscriber", @@ -2302,51 +2604,33 @@ checksum = "a3e5df347f0bf3ec1d670aad6ca5c6a1859cd9ea61d2113125794654ccced68f" [[package]] name = "unicase" -version = "2.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7d2d4dafb69621809a81864c9c1b864479e1235c0dd4e199924b9742439ed89" -dependencies = [ - "version_check", -] - -[[package]] -name = "unicode-bidi" -version = "0.3.15" +version = "2.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" +checksum = "75b844d17643ee918803943289730bec8aac480150456169e647ed0b576ba539" [[package]] name = "unicode-ident" -version = "1.0.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" - -[[package]] -name = "unicode-normalization" -version = "0.1.23" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5" -dependencies = [ - "tinyvec", -] +checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" [[package]] name = "unicode-properties" -version = "0.1.1" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4259d9d4425d9f0661581b804cb85fe66a4c631cadd8f490d1c13a35d5d9291" +checksum = "e70f2a8b45122e719eb623c01822704c4e0907e7e426a05927e1a1cfff5b75d0" [[package]] name = "unicode-xid" -version = "0.2.4" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" +checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" [[package]] name = "url" -version = "2.5.2" +version = "2.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c" +checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60" dependencies = [ "form_urlencoded", "idna", @@ -2355,16 +2639,22 @@ dependencies = [ ] [[package]] -name = "valuable" -version = "0.1.0" +name = "utf16_iter" +version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" +checksum = "c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246" [[package]] -name = "version_check" -version = "0.9.5" +name = "utf8_iter" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" + +[[package]] +name = "valuable" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" +checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" [[package]] name = "vfs" @@ -2375,7 +2665,7 @@ dependencies = [ "indexmap", "nohash-hasher", "paths", - "rustc-hash 2.0.0", + "rustc-hash 2.1.1", "stdx", "tracing", ] @@ -2388,7 +2678,7 @@ dependencies = [ "notify", "paths", "rayon", - "rustc-hash 2.0.0", + "rustc-hash 2.1.1", "stdx", "tracing", "vfs", @@ -2411,6 +2701,22 @@ version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + [[package]] name = "winapi-util" version = "0.1.9" @@ -2420,33 +2726,85 @@ dependencies = [ "windows-sys 0.59.0", ] +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + [[package]] name = "windows" -version = "0.56.0" +version = "0.58.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1de69df01bdf1ead2f4ac895dc77c9351aefff65b2f3db429a343f9cbf05e132" +checksum = "dd04d41d93c4992d421894c18c8b43496aa748dd4c081bac0dc93eb0489272b6" dependencies = [ - "windows-core", + "windows-core 0.58.0", "windows-targets 0.52.6", ] +[[package]] +name = "windows" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f919aee0a93304be7f62e8e5027811bbba96bcb1de84d6618be56e43f8a32a1" +dependencies = [ + "windows-core 0.59.0", + "windows-targets 0.53.0", +] + [[package]] name = "windows-core" -version = "0.56.0" +version = "0.58.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4698e52ed2d08f8658ab0c39512a7c00ee5fe2688c65f8c0a4f06750d729f2a6" +checksum = "6ba6d44ec8c2591c134257ce647b7ea6b20335bf6379a27dac5f1641fcf59f99" dependencies = [ - "windows-implement", - "windows-interface", - "windows-result", + "windows-implement 0.58.0", + "windows-interface 0.58.0", + "windows-result 0.2.0", + "windows-strings 0.1.0", "windows-targets 0.52.6", ] +[[package]] +name = "windows-core" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "810ce18ed2112484b0d4e15d022e5f598113e220c53e373fb31e67e21670c1ce" +dependencies = [ + "windows-implement 0.59.0", + "windows-interface 0.59.0", + "windows-result 0.3.1", + "windows-strings 0.3.1", + "windows-targets 0.53.0", +] + [[package]] name = "windows-implement" -version = "0.56.0" +version = "0.58.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6fc35f58ecd95a9b71c4f2329b911016e6bec66b3f2e6a4aad86bd2e99e2f9b" +checksum = "2bbd5b46c938e506ecbce286b6628a02171d56153ba733b6c741fc627ec9579b" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "windows-implement" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83577b051e2f49a058c308f17f273b570a6a758386fc291b5f6a934dd84e48c1" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "windows-interface" +version = "0.58.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "053c4c462dc91d3b1504c6fe5a726dd15e216ba718e84a0e46a88fbe5ded3515" dependencies = [ "proc-macro2", "quote", @@ -2455,24 +2813,58 @@ dependencies = [ [[package]] name = "windows-interface" -version = "0.56.0" +version = "0.59.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08990546bf4edef8f431fa6326e032865f27138718c587dc21bc0265bbcb57cc" +checksum = "cb26fd936d991781ea39e87c3a27285081e3c0da5ca0fcbc02d368cc6f52ff01" dependencies = [ "proc-macro2", "quote", "syn", ] +[[package]] +name = "windows-link" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dccfd733ce2b1753b03b6d3c65edf020262ea35e20ccdf3e288043e6dd620e3" + +[[package]] +name = "windows-result" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e" +dependencies = [ + "windows-targets 0.52.6", +] + [[package]] name = "windows-result" -version = "0.1.2" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06374efe858fab7e4f881500e6e86ec8bc28f9462c47e5a9941a0142ad86b189" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-strings" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e383302e8ec8515204254685643de10811af0ed97ea37210dc26fb0032647f8" +checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10" dependencies = [ + "windows-result 0.2.0", "windows-targets 0.52.6", ] +[[package]] +name = "windows-strings" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87fa48cc5d406560701792be122a10132491cff9d0aeb23583cc2dcafc847319" +dependencies = [ + "windows-link", +] + [[package]] name = "windows-sys" version = "0.48.0" @@ -2524,13 +2916,29 @@ dependencies = [ "windows_aarch64_gnullvm 0.52.6", "windows_aarch64_msvc 0.52.6", "windows_i686_gnu 0.52.6", - "windows_i686_gnullvm", + "windows_i686_gnullvm 0.52.6", "windows_i686_msvc 0.52.6", "windows_x86_64_gnu 0.52.6", "windows_x86_64_gnullvm 0.52.6", "windows_x86_64_msvc 0.52.6", ] +[[package]] +name = "windows-targets" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1e4c7e8ceaaf9cb7d7507c974735728ab453b67ef8f18febdd7c11fe59dca8b" +dependencies = [ + "windows_aarch64_gnullvm 0.53.0", + "windows_aarch64_msvc 0.53.0", + "windows_i686_gnu 0.53.0", + "windows_i686_gnullvm 0.53.0", + "windows_i686_msvc 0.53.0", + "windows_x86_64_gnu 0.53.0", + "windows_x86_64_gnullvm 0.53.0", + "windows_x86_64_msvc 0.53.0", +] + [[package]] name = "windows_aarch64_gnullvm" version = "0.48.5" @@ -2543,6 +2951,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764" + [[package]] name = "windows_aarch64_msvc" version = "0.48.5" @@ -2555,6 +2969,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" +[[package]] +name = "windows_aarch64_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c" + [[package]] name = "windows_i686_gnu" version = "0.48.5" @@ -2567,12 +2987,24 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" +[[package]] +name = "windows_i686_gnu" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3" + [[package]] name = "windows_i686_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" +[[package]] +name = "windows_i686_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11" + [[package]] name = "windows_i686_msvc" version = "0.48.5" @@ -2585,6 +3017,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" +[[package]] +name = "windows_i686_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d" + [[package]] name = "windows_x86_64_gnu" version = "0.48.5" @@ -2597,6 +3035,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" +[[package]] +name = "windows_x86_64_gnu" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba" + [[package]] name = "windows_x86_64_gnullvm" version = "0.48.5" @@ -2609,6 +3053,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57" + [[package]] name = "windows_x86_64_msvc" version = "0.48.5" @@ -2621,11 +3071,17 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" +[[package]] +name = "windows_x86_64_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486" + [[package]] name = "winnow" -version = "0.6.18" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68a9bda4691f099d435ad181000724da8e5899daa10713c2d432552b9ccd3a6f" +checksum = "0e7f4ea97f6f78012141bcdb6a216b2609f0979ada50b20ca5b52dde2eac2bb1" dependencies = [ "memchr", ] @@ -2636,6 +3092,18 @@ version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "23f6174b2566cc4a74f95e1367ec343e7fa80c93cc8087f5c4a3d6a1088b2118" +[[package]] +name = "write16" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936" + +[[package]] +name = "writeable" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51" + [[package]] name = "xflags" version = "0.3.2" @@ -2675,7 +3143,7 @@ dependencies = [ "edition", "either", "flate2", - "itertools", + "itertools 0.14.0", "proc-macro2", "quote", "stdx", @@ -2688,20 +3156,66 @@ dependencies = [ ] [[package]] -name = "zerocopy" -version = "0.7.35" +name = "yoke" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" +checksum = "120e6aef9aa629e3d4f52dc8cc43a015c7724194c97dfaf45180d2daf2b77f40" dependencies = [ - "byteorder", - "zerocopy-derive", + "serde", + "stable_deref_trait", + "yoke-derive", + "zerofrom", ] [[package]] -name = "zerocopy-derive" -version = "0.7.35" +name = "yoke-derive" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" +checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "synstructure", +] + +[[package]] +name = "zerofrom" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5" +dependencies = [ + "zerofrom-derive", +] + +[[package]] +name = "zerofrom-derive" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "synstructure", +] + +[[package]] +name = "zerovec" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa2b893d79df23bfb12d5461018d408ea19dfafe76c2c7ef6d4eba614f8ff079" +dependencies = [ + "yoke", + "zerofrom", + "zerovec-derive", +] + +[[package]] +name = "zerovec-derive" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" dependencies = [ "proc-macro2", "quote", @@ -2710,13 +3224,17 @@ dependencies = [ [[package]] name = "zip" -version = "0.6.6" +version = "2.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "760394e246e4c28189f19d488c058bf16f564016aefac5d32bb1f3b51d5e9261" +checksum = "fabe6324e908f85a1c52063ce7aa26b68dcb7eb6dbc83a2d148403c9bc3eba50" dependencies = [ - "byteorder", + "arbitrary", "crc32fast", "crossbeam-utils", + "displaydoc", "flate2", + "indexmap", + "memchr", + "thiserror 2.0.12", "time", ] diff --git a/src/tools/rust-analyzer/Cargo.toml b/src/tools/rust-analyzer/Cargo.toml index e22191397655d..6fa171702dd48 100644 --- a/src/tools/rust-analyzer/Cargo.toml +++ b/src/tools/rust-analyzer/Cargo.toml @@ -4,8 +4,8 @@ exclude = ["crates/proc-macro-srv/proc-macro-test/imp"] resolver = "2" [workspace.package] -rust-version = "1.84" -edition = "2021" +rust-version = "1.86" +edition = "2024" license = "MIT OR Apache-2.0" authors = ["rust-analyzer team"] repository = "https://github.com/rust-lang/rust-analyzer" @@ -46,7 +46,7 @@ debug = 2 # ungrammar = { path = "../ungrammar" } -# rust-analyzer-salsa = { path = "../salsa" } +# salsa = { path = "../salsa" } [workspace.dependencies] # local crates @@ -72,7 +72,7 @@ proc-macro-srv = { path = "./crates/proc-macro-srv", version = "0.0.0" } proc-macro-srv-cli = { path = "./crates/proc-macro-srv-cli", version = "0.0.0" } profile = { path = "./crates/profile", version = "0.0.0" } project-model = { path = "./crates/project-model", version = "0.0.0" } -ra-salsa = { path = "./crates/ra-salsa", package = "salsa", version = "0.0.0" } +query-group = { package = "query-group-macro", path = "./crates/query-group-macro", version = "0.0.0" } span = { path = "./crates/span", version = "0.0.0" } stdx = { path = "./crates/stdx", version = "0.0.0" } syntax = { path = "./crates/syntax", version = "0.0.0" } @@ -85,72 +85,69 @@ vfs-notify = { path = "./crates/vfs-notify", version = "0.0.0" } vfs = { path = "./crates/vfs", version = "0.0.0" } edition = { path = "./crates/edition", version = "0.0.0" } -ra-ap-rustc_hashes = { version = "0.100", default-features = false } -ra-ap-rustc_lexer = { version = "0.100", default-features = false } -ra-ap-rustc_parse_format = { version = "0.100", default-features = false } -ra-ap-rustc_index = { version = "0.100", default-features = false } -ra-ap-rustc_abi = { version = "0.100", default-features = false } -ra-ap-rustc_pattern_analysis = { version = "0.100", default-features = false } +ra-ap-rustc_lexer = { version = "0.110", default-features = false } +ra-ap-rustc_parse_format = { version = "0.110", default-features = false } +ra-ap-rustc_index = { version = "0.110", default-features = false } +ra-ap-rustc_abi = { version = "0.110", default-features = false } +ra-ap-rustc_pattern_analysis = { version = "0.110", default-features = false } # local crates that aren't published to crates.io. These should not have versions. # in-tree crates that are published separately and follow semver. See lib/README.md line-index = { version = "0.1.2" } la-arena = { version = "0.3.1" } -lsp-server = { version = "0.7.6" } +lsp-server = { version = "0.7.8" } # non-local crates -anyhow = "1.0.75" -arrayvec = "0.7.4" -bitflags = "2.4.1" -cargo_metadata = "0.18.1" -camino = "1.1.6" -chalk-solve = { version = "0.100.0", default-features = false } -chalk-ir = "0.100.0" -chalk-recursive = { version = "0.100.0", default-features = false } -chalk-derive = "0.100.0" -crossbeam-channel = "0.5.8" -dissimilar = "1.0.7" +anyhow = "1.0.97" +arrayvec = "0.7.6" +bitflags = "2.9.0" +cargo_metadata = "0.19.2" +camino = "1.1.9" +chalk-solve = { version = "0.102.0", default-features = false } +chalk-ir = "0.102.0" +chalk-recursive = { version = "0.102.0", default-features = false } +chalk-derive = "0.102.0" +crossbeam-channel = "0.5.15" +dissimilar = "1.0.10" dot = "0.1.4" -either = "1.9.0" -expect-test = "1.4.0" -hashbrown = { version = "0.14", features = [ - "inline-more", -], default-features = false } -indexmap = "2.1.0" -itertools = "0.12.0" -libc = "0.2.150" -libloading = "0.8.0" -memmap2 = "0.5.4" +either = "1.15.0" +expect-test = "1.5.1" +indexmap = { version = "2.8.0", features = ["serde"] } +itertools = "0.14.0" +libc = "0.2.171" +libloading = "0.8.6" +memmap2 = "0.9.5" nohash-hasher = "0.2.0" -oorandom = "11.1.3" -object = { version = "0.33.0", default-features = false, features = [ +oorandom = "11.1.5" +object = { version = "0.36.7", default-features = false, features = [ "std", "read_core", "elf", "macho", "pe", ] } -process-wrap = { version = "8.0.2", features = ["std"] } +process-wrap = { version = "8.2.0", features = ["std"] } pulldown-cmark-to-cmark = "10.0.4" -pulldown-cmark = { version = "0.9.0", default-features = false } -rayon = "1.8.0" -rustc-hash = "2.0.0" +pulldown-cmark = { version = "0.9.6", default-features = false } +rayon = "1.10.0" +salsa = "0.20.0" +semver = "1.0.26" +serde = { version = "1.0.219" } +serde_derive = { version = "1.0.219" } +serde_json = "1.0.140" +rustc-hash = "2.1.1" rustc-literal-escaper = "0.0.2" -semver = "1.0.14" -serde = { version = "1.0.192" } -serde_derive = { version = "1.0.192" } -serde_json = "1.0.108" -smallvec = { version = "1.10.0", features = [ +smallvec = { version = "1.14.0", features = [ "const_new", "union", "const_generics", ] } smol_str = "0.3.2" text-size = "1.1.1" -tracing = "0.1.40" -tracing-tree = "0.3.0" -tracing-subscriber = { version = "0.3.18", default-features = false, features = [ +tracing = "0.1.41" +tracing-tree = "0.4.0" +tracing-subscriber = { version = "0.3.19", default-features = false, features = [ "registry", "fmt", "local-time", @@ -159,12 +156,15 @@ tracing-subscriber = { version = "0.3.18", default-features = false, features = "tracing-log", ] } triomphe = { version = "0.1.14", default-features = false, features = ["std"] } -url = "2.3.1" -xshell = "0.2.5" - +url = "2.5.4" +xshell = "0.2.7" # We need to freeze the version of the crate, as the raw-api feature is considered unstable -dashmap = { version = "=5.5.3", features = ["raw-api"] } +dashmap = { version = "=6.1.0", features = ["raw-api", "inline"] } +# We need to freeze the version of the crate, as it needs to match with dashmap +hashbrown = { version = "0.14.0", features = [ + "inline-more", +], default-features = false } [workspace.lints.rust] # remember to update RUSTFLAGS in ci.yml if you add something here @@ -172,6 +172,7 @@ dashmap = { version = "=5.5.3", features = ["raw-api"] } elided_lifetimes_in_paths = "warn" explicit_outlives_requirements = "warn" unsafe_op_in_unsafe_fn = "warn" +unexpected_cfgs = { level = "warn", check-cfg = ['cfg(bootstrap)'] } unused_extern_crates = "warn" unused_lifetimes = "warn" unreachable_pub = "warn" diff --git a/src/tools/rust-analyzer/bench_data/numerous_macro_rules b/src/tools/rust-analyzer/bench_data/numerous_macro_rules index 7610a3ae1e3cb..60997065b2408 100644 --- a/src/tools/rust-analyzer/bench_data/numerous_macro_rules +++ b/src/tools/rust-analyzer/bench_data/numerous_macro_rules @@ -528,7 +528,7 @@ macro_rules! __ra_macro_fixture526 {($expr : expr )=>{|| -> _ { Some ($expr )}( macro_rules! __ra_macro_fixture527 {($($arg : tt )*)=>($crate :: io :: _print ($crate :: format_args ! ($($arg )*))); } macro_rules! __ra_macro_fixture528 {($fmt : literal , $($tt : tt ),*)=>{ mbe :: ExpandError :: ProcMacroError ( tt :: ExpansionError :: Unknown ( format ! ($fmt , $($tt ),*)))}; ($fmt : literal )=>{ mbe :: ExpandError :: ProcMacroError ( tt :: ExpansionError :: Unknown ($fmt . to_string ()))}} macro_rules! __ra_macro_fixture529 {($($tt : tt )* )=>{$crate :: quote :: IntoTt :: to_subtree ($crate :: __quote ! ($($tt )*))}} -macro_rules! __ra_macro_fixture530 {()=>{ Vec ::< tt :: TokenTree >:: new ()}; (@ SUBTREE $delim : ident $($tt : tt )* )=>{{ let children = $crate :: __quote ! ($($tt )*); tt :: Subtree { delimiter : Some ( tt :: Delimiter { kind : tt :: DelimiterKind ::$delim , id : tt :: TokenId :: unspecified (), }), token_trees : $crate :: quote :: IntoTt :: to_tokens ( children ), }}}; (@ PUNCT $first : literal )=>{{ vec ! [ tt :: Leaf :: Punct ( tt :: Punct { char : $first , spacing : tt :: Spacing :: Alone , id : tt :: TokenId :: unspecified (), }). into ()]}}; (@ PUNCT $first : literal , $sec : literal )=>{{ vec ! [ tt :: Leaf :: Punct ( tt :: Punct { char : $first , spacing : tt :: Spacing :: Joint , id : tt :: TokenId :: unspecified (), }). into (), tt :: Leaf :: Punct ( tt :: Punct { char : $sec , spacing : tt :: Spacing :: Alone , id : tt :: TokenId :: unspecified (), }). into ()]}}; (# $first : ident $($tail : tt )* )=>{{ let token = $crate :: quote :: ToTokenTree :: to_token ($first ); let mut tokens = vec ! [ token . into ()]; let mut tail_tokens = $crate :: quote :: IntoTt :: to_tokens ($crate :: __quote ! ($($tail )*)); tokens . append (& mut tail_tokens ); tokens }}; (## $first : ident $($tail : tt )* )=>{{ let mut tokens = $first . into_iter (). map ($crate :: quote :: ToTokenTree :: to_token ). collect ::< Vec < tt :: TokenTree >> (); let mut tail_tokens = $crate :: quote :: IntoTt :: to_tokens ($crate :: __quote ! ($($tail )*)); tokens . append (& mut tail_tokens ); tokens }}; ({$($tt : tt )* })=>{$crate :: __quote ! (@ SUBTREE Brace $($tt )*)}; ([$($tt : tt )* ])=>{$crate :: __quote ! (@ SUBTREE Bracket $($tt )*)}; (($($tt : tt )* ))=>{$crate :: __quote ! (@ SUBTREE Parenthesis $($tt )*)}; ($tt : literal )=>{ vec ! [$crate :: quote :: ToTokenTree :: to_token ($tt ). into ()]}; ($tt : ident )=>{ vec ! [{ tt :: Leaf :: Ident ( tt :: Ident { text : stringify ! ($tt ). into (), id : tt :: TokenId :: unspecified (), }). into ()}]}; (-> )=>{$crate :: __quote ! (@ PUNCT '-' , '>' )}; (& )=>{$crate :: __quote ! (@ PUNCT '&' )}; (, )=>{$crate :: __quote ! (@ PUNCT ',' )}; (: )=>{$crate :: __quote ! (@ PUNCT ':' )}; (; )=>{$crate :: __quote ! (@ PUNCT ';' )}; (:: )=>{$crate :: __quote ! (@ PUNCT ':' , ':' )}; (. )=>{$crate :: __quote ! (@ PUNCT '.' )}; (< )=>{$crate :: __quote ! (@ PUNCT '<' )}; (> )=>{$crate :: __quote ! (@ PUNCT '>' )}; ($first : tt $($tail : tt )+ )=>{{ let mut tokens = $crate :: quote :: IntoTt :: to_tokens ($crate :: __quote ! ($first )); let mut tail_tokens = $crate :: quote :: IntoTt :: to_tokens ($crate :: __quote ! ($($tail )*)); tokens . append (& mut tail_tokens ); tokens }}; } +macro_rules! __ra_macro_fixture530 {()=>{ Vec ::< tt :: TokenTree >:: new ()}; (@ SUBTREE $delim : ident $($tt : tt )* )=>{{ let children = $crate :: __quote ! ($($tt )*); tt :: Subtree { delimiter : Some ( tt :: Delimiter { kind : tt :: DelimiterKind ::$delim , id : tt :: TokenId :: unspecified (), }), token_trees : $crate :: quote :: IntoTt :: to_tokens ( children ), }}}; (@ PUNCT $first : literal )=>{{ vec ! [ tt :: Leaf :: Punct ( tt :: Punct { char : $first , spacing : tt :: Spacing :: Alone , id : tt :: TokenId :: unspecified (), }). into ()]}}; (@ PUNCT $first : literal , $sec : literal )=>{{ vec ! [ tt :: Leaf :: Punct ( tt :: Punct { char : $first , spacing : tt :: Spacing :: Joint , id : tt :: TokenId :: unspecified (), }). into (), tt :: Leaf :: Punct ( tt :: Punct { char : $sec , spacing : tt :: Spacing :: Alone , id : tt :: TokenId :: unspecified (), }). into ()]}}; (# $first : ident $($tail : tt )* )=>{{ let token = $crate :: quote :: ToTokenTree :: to_token ($first ); let mut tokens = vec ! [ token . into ()]; let mut tail_tokens = $crate :: quote :: IntoTt :: to_tokens ($crate :: __quote ! ($($tail )*)); tokens . append (& mut tail_tokens ); tokens }}; (# # $first : ident $($tail : tt )* )=>{{ let mut tokens = $first . into_iter (). map ($crate :: quote :: ToTokenTree :: to_token ). collect ::< Vec < tt :: TokenTree >> (); let mut tail_tokens = $crate :: quote :: IntoTt :: to_tokens ($crate :: __quote ! ($($tail )*)); tokens . append (& mut tail_tokens ); tokens }}; ({$($tt : tt )* })=>{$crate :: __quote ! (@ SUBTREE Brace $($tt )*)}; ([$($tt : tt )* ])=>{$crate :: __quote ! (@ SUBTREE Bracket $($tt )*)}; (($($tt : tt )* ))=>{$crate :: __quote ! (@ SUBTREE Parenthesis $($tt )*)}; ($tt : literal )=>{ vec ! [$crate :: quote :: ToTokenTree :: to_token ($tt ). into ()]}; ($tt : ident )=>{ vec ! [{ tt :: Leaf :: Ident ( tt :: Ident { text : stringify ! ($tt ). into (), id : tt :: TokenId :: unspecified (), }). into ()}]}; (-> )=>{$crate :: __quote ! (@ PUNCT '-' , '>' )}; (& )=>{$crate :: __quote ! (@ PUNCT '&' )}; (, )=>{$crate :: __quote ! (@ PUNCT ',' )}; (: )=>{$crate :: __quote ! (@ PUNCT ':' )}; (; )=>{$crate :: __quote ! (@ PUNCT ';' )}; (:: )=>{$crate :: __quote ! (@ PUNCT ':' , ':' )}; (. )=>{$crate :: __quote ! (@ PUNCT '.' )}; (< )=>{$crate :: __quote ! (@ PUNCT '<' )}; (> )=>{$crate :: __quote ! (@ PUNCT '>' )}; ($first : tt $($tail : tt )+ )=>{{ let mut tokens = $crate :: quote :: IntoTt :: to_tokens ($crate :: __quote ! ($first )); let mut tail_tokens = $crate :: quote :: IntoTt :: to_tokens ($crate :: __quote ! ($($tail )*)); tokens . append (& mut tail_tokens ); tokens }}; } macro_rules! __ra_macro_fixture531 {($($name : ident )*)=>{$(if let Some ( it )= & self .$name { f . field ( stringify ! ($name ), it ); })*}} macro_rules! __ra_macro_fixture532 {($fmt : expr )=>{ RenameError ( format ! ($fmt ))}; ($fmt : expr , $($arg : tt )+)=>{ RenameError ( format ! ($fmt , $($arg )+))}} macro_rules! __ra_macro_fixture533 {($($tokens : tt )*)=>{ return Err ( format_err ! ($($tokens )*))}} diff --git a/src/tools/rust-analyzer/crates/base-db/Cargo.toml b/src/tools/rust-analyzer/crates/base-db/Cargo.toml index 042dd36488aa9..441434504c293 100644 --- a/src/tools/rust-analyzer/crates/base-db/Cargo.toml +++ b/src/tools/rust-analyzer/crates/base-db/Cargo.toml @@ -12,10 +12,10 @@ rust-version.workspace = true [lib] [dependencies] -lz4_flex = { version = "0.11", default-features = false } - la-arena.workspace = true -ra-salsa.workspace = true +dashmap.workspace = true +salsa.workspace = true +query-group.workspace = true rustc-hash.workspace = true triomphe.workspace = true semver.workspace = true @@ -23,7 +23,6 @@ tracing.workspace = true # local deps cfg.workspace = true -stdx.workspace = true syntax.workspace = true vfs.workspace = true span.workspace = true diff --git a/src/tools/rust-analyzer/crates/base-db/src/change.rs b/src/tools/rust-analyzer/crates/base-db/src/change.rs index 7e40f5408f144..da2fb27571c2f 100644 --- a/src/tools/rust-analyzer/crates/base-db/src/change.rs +++ b/src/tools/rust-analyzer/crates/base-db/src/change.rs @@ -3,23 +3,18 @@ use std::fmt; -use ra_salsa::Durability; -use rustc_hash::FxHashMap; +use salsa::Durability; use triomphe::Arc; use vfs::FileId; -use crate::{ - CrateGraph, CrateId, CrateWorkspaceData, SourceDatabaseFileInputExt, SourceRoot, - SourceRootDatabase, SourceRootId, -}; +use crate::{CrateGraphBuilder, CratesIdMap, RootQueryDb, SourceRoot, SourceRootId}; /// Encapsulate a bunch of raw `.set` calls on the database. #[derive(Default)] pub struct FileChange { pub roots: Option>, pub files_changed: Vec<(FileId, Option)>, - pub crate_graph: Option, - pub ws_data: Option>>, + pub crate_graph: Option, } impl fmt::Debug for FileChange { @@ -39,10 +34,6 @@ impl fmt::Debug for FileChange { } impl FileChange { - pub fn new() -> Self { - FileChange::default() - } - pub fn set_roots(&mut self, roots: Vec) { self.roots = Some(roots); } @@ -51,48 +42,45 @@ impl FileChange { self.files_changed.push((file_id, new_text)) } - pub fn set_crate_graph(&mut self, graph: CrateGraph) { + pub fn set_crate_graph(&mut self, graph: CrateGraphBuilder) { self.crate_graph = Some(graph); } - pub fn set_ws_data(&mut self, data: FxHashMap>) { - self.ws_data = Some(data); - } - - pub fn apply(self, db: &mut dyn SourceRootDatabase) { + pub fn apply(self, db: &mut dyn RootQueryDb) -> Option { let _p = tracing::info_span!("FileChange::apply").entered(); if let Some(roots) = self.roots { for (idx, root) in roots.into_iter().enumerate() { let root_id = SourceRootId(idx as u32); - let durability = durability(&root); + let durability = source_root_durability(&root); for file_id in root.iter() { db.set_file_source_root_with_durability(file_id, root_id, durability); } + db.set_source_root_with_durability(root_id, Arc::new(root), durability); } } for (file_id, text) in self.files_changed { let source_root_id = db.file_source_root(file_id); - let source_root = db.source_root(source_root_id); - let durability = durability(&source_root); + let source_root = db.source_root(source_root_id.source_root_id(db)); + + let durability = file_text_durability(&source_root.source_root(db)); // XXX: can't actually remove the file, just reset the text let text = text.unwrap_or_default(); db.set_file_text_with_durability(file_id, &text, durability) } + if let Some(crate_graph) = self.crate_graph { - db.set_crate_graph_with_durability(Arc::new(crate_graph), Durability::HIGH); - } - if let Some(data) = self.ws_data { - db.set_crate_workspace_data_with_durability(Arc::new(data), Durability::HIGH); + return Some(crate_graph.set_in_db(db)); } + None } } -fn durability(source_root: &SourceRoot) -> Durability { - if source_root.is_library { - Durability::HIGH - } else { - Durability::LOW - } +fn source_root_durability(source_root: &SourceRoot) -> Durability { + if source_root.is_library { Durability::MEDIUM } else { Durability::LOW } +} + +fn file_text_durability(source_root: &SourceRoot) -> Durability { + if source_root.is_library { Durability::HIGH } else { Durability::LOW } } diff --git a/src/tools/rust-analyzer/crates/base-db/src/input.rs b/src/tools/rust-analyzer/crates/base-db/src/input.rs index bd08387b58219..499c9b3716b26 100644 --- a/src/tools/rust-analyzer/crates/base-db/src/input.rs +++ b/src/tools/rust-analyzer/crates/base-db/src/input.rs @@ -6,17 +6,23 @@ //! actual IO. See `vfs` and `project_model` in the `rust-analyzer` crate for how //! actual IO is done and lowered to input. +use std::hash::BuildHasherDefault; use std::{fmt, mem, ops}; -use cfg::CfgOptions; +use cfg::{CfgOptions, HashableCfgOptions}; +use dashmap::DashMap; +use dashmap::mapref::entry::Entry; use intern::Symbol; use la_arena::{Arena, Idx, RawIdx}; -use rustc_hash::{FxHashMap, FxHashSet}; -use span::{Edition, EditionedFileId}; +use rustc_hash::{FxHashMap, FxHashSet, FxHasher}; +use salsa::{Durability, Setter}; +use span::Edition; use triomphe::Arc; -use vfs::{file_set::FileSet, AbsPathBuf, AnchoredPath, FileId, VfsPath}; +use vfs::{AbsPathBuf, AnchoredPath, FileId, VfsPath, file_set::FileSet}; -pub type ProcMacroPaths = FxHashMap>; +use crate::{CrateWorkspaceData, EditionedFileId, RootQueryDb}; + +pub type ProcMacroPaths = FxHashMap>; #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)] pub struct SourceRootId(pub u32); @@ -64,30 +70,31 @@ impl SourceRoot { } } -/// `CrateGraph` is a bit of information which turns a set of text files into a -/// number of Rust crates. -/// -/// Each crate is defined by the `FileId` of its root module, the set of enabled -/// `cfg` flags and the set of dependencies. -/// -/// Note that, due to cfg's, there might be several crates for a single `FileId`! -/// -/// For the purposes of analysis, a crate does not have a name. Instead, names -/// are specified on dependency edges. That is, a crate might be known under -/// different names in different dependent crates. -/// -/// Note that `CrateGraph` is build-system agnostic: it's a concept of the Rust -/// language proper, not a concept of the build system. In practice, we get -/// `CrateGraph` by lowering `cargo metadata` output. -/// -/// `CrateGraph` is `!Serialize` by design, see -/// -#[derive(Clone, Default)] -pub struct CrateGraph { - arena: Arena, +#[derive(Default, Clone)] +pub struct CrateGraphBuilder { + arena: Arena, +} + +pub type CrateBuilderId = Idx; + +impl ops::Index for CrateGraphBuilder { + type Output = CrateBuilder; + + fn index(&self, index: CrateBuilderId) -> &Self::Output { + &self.arena[index] + } } -impl fmt::Debug for CrateGraph { +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct CrateBuilder { + pub basic: CrateDataBuilder, + pub extra: ExtraCrateData, + pub cfg_options: CfgOptions, + pub env: Env, + ws_data: Arc, +} + +impl fmt::Debug for CrateGraphBuilder { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_map() .entries(self.arena.iter().map(|(id, data)| (u32::from(id.into_raw()), data))) @@ -95,8 +102,6 @@ impl fmt::Debug for CrateGraph { } } -pub type CrateId = Idx; - #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct CrateName(Symbol); @@ -105,11 +110,7 @@ impl CrateName { /// Dashes are not allowed in the crate names, /// hence the input string is returned as `Err` for those cases. pub fn new(name: &str) -> Result { - if name.contains('-') { - Err(name) - } else { - Ok(Self(Symbol::intern(name))) - } + if name.contains('-') { Err(name) } else { Ok(Self(Symbol::intern(name))) } } /// Creates a crate name, unconditionally replacing the dashes with underscores. @@ -272,10 +273,49 @@ impl ReleaseChannel { } } -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct CrateData { +/// The crate data from which we derive the `Crate`. +/// +/// We want this to contain as little data as possible, because if it contains dependencies and +/// something changes, this crate and all of its dependencies ids are invalidated, which causes +/// pretty much everything to be recomputed. If the crate id is not invalidated, only this crate's +/// information needs to be recomputed. +/// +/// *Most* different crates have different root files (actually, pretty much all of them). +/// Still, it is possible to have crates distinguished by other factors (e.g. dependencies). +/// So we store only the root file - unless we find that this crate has the same root file as +/// another crate, in which case we store all data for one of them (if one is a dependency of +/// the other, we store for it, because it has more dependencies to be invalidated). +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct UniqueCrateData { + root_file_id: FileId, + disambiguator: Option>, +} + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct CrateData { pub root_file_id: FileId, pub edition: Edition, + /// The dependencies of this crate. + /// + /// Note that this may contain more dependencies than the crate actually uses. + /// A common example is the test crate which is included but only actually is active when + /// declared in source via `extern crate test`. + pub dependencies: Vec>, + pub origin: CrateOrigin, + pub is_proc_macro: bool, + /// The working directory to run proc-macros in invoked in the context of this crate. + /// This is the workspace root of the cargo workspace for workspace members, the crate manifest + /// dir otherwise. + // FIXME: This ought to be a `VfsPath` or something opaque. + pub proc_macro_cwd: Arc, +} + +pub type CrateDataBuilder = CrateData; +pub type BuiltCrateData = CrateData; + +/// Crate data unrelated to analysis. +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct ExtraCrateData { pub version: Option, /// A name used in the package's project declaration: for Cargo projects, /// its `[package].name` can be different for other project types or even @@ -284,21 +324,8 @@ pub struct CrateData { /// For purposes of analysis, crates are anonymous (only names in /// `Dependency` matters), this name should only be used for UI. pub display_name: Option, - pub cfg_options: Arc, /// The cfg options that could be used by the crate - pub potential_cfg_options: Option>, - pub env: Env, - /// The dependencies of this crate. - /// - /// Note that this may contain more dependencies than the crate actually uses. - /// A common example is the test crate which is included but only actually is active when - /// declared in source via `extern crate test`. - pub dependencies: Vec, - pub origin: CrateOrigin, - pub is_proc_macro: bool, - /// The working directory to run proc-macros in. This is the workspace root of the cargo workspace - /// for workspace members, the crate manifest dir otherwise. - pub proc_macro_cwd: Option, + pub potential_cfg_options: Option, } #[derive(Default, Clone, PartialEq, Eq)] @@ -326,22 +353,32 @@ impl fmt::Debug for Env { } #[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct Dependency { - pub crate_id: CrateId, +pub struct Dependency { + pub crate_id: Id, pub name: CrateName, prelude: bool, sysroot: bool, } -impl Dependency { - pub fn new(name: CrateName, crate_id: CrateId) -> Self { +pub type DependencyBuilder = Dependency; +pub type BuiltDependency = Dependency; + +impl DependencyBuilder { + pub fn new(name: CrateName, crate_id: CrateBuilderId) -> Self { Self { name, crate_id, prelude: true, sysroot: false } } - pub fn with_prelude(name: CrateName, crate_id: CrateId, prelude: bool, sysroot: bool) -> Self { + pub fn with_prelude( + name: CrateName, + crate_id: CrateBuilderId, + prelude: bool, + sysroot: bool, + ) -> Self { Self { name, crate_id, prelude, sysroot } } +} +impl BuiltDependency { /// Whether this dependency is to be added to the depending crate's extern prelude. pub fn is_prelude(&self) -> bool { self.prelude @@ -353,41 +390,71 @@ impl Dependency { } } -impl CrateGraph { +pub type CratesIdMap = FxHashMap; + +#[salsa::input] +#[derive(Debug)] +pub struct Crate { + #[return_ref] + pub data: BuiltCrateData, + /// Crate data that is not needed for analysis. + /// + /// This is split into a separate field to increase incrementality. + #[return_ref] + pub extra_data: ExtraCrateData, + // This is in `Arc` because it is shared for all crates in a workspace. + #[return_ref] + pub workspace_data: Arc, + #[return_ref] + pub cfg_options: CfgOptions, + #[return_ref] + pub env: Env, +} + +/// The mapping from [`UniqueCrateData`] to their [`Crate`] input. +#[derive(Debug, Default)] +pub struct CratesMap(DashMap>); + +impl CrateGraphBuilder { pub fn add_crate_root( &mut self, root_file_id: FileId, edition: Edition, display_name: Option, version: Option, - cfg_options: Arc, - potential_cfg_options: Option>, + mut cfg_options: CfgOptions, + mut potential_cfg_options: Option, mut env: Env, origin: CrateOrigin, is_proc_macro: bool, - proc_macro_cwd: Option, - ) -> CrateId { + proc_macro_cwd: Arc, + ws_data: Arc, + ) -> CrateBuilderId { env.entries.shrink_to_fit(); - let data = CrateData { - root_file_id, - edition, - version, - display_name, + cfg_options.shrink_to_fit(); + if let Some(potential_cfg_options) = &mut potential_cfg_options { + potential_cfg_options.shrink_to_fit(); + } + self.arena.alloc(CrateBuilder { + basic: CrateData { + root_file_id, + edition, + dependencies: Vec::new(), + origin, + is_proc_macro, + proc_macro_cwd, + }, + extra: ExtraCrateData { version, display_name, potential_cfg_options }, cfg_options, - potential_cfg_options, env, - dependencies: Vec::new(), - origin, - is_proc_macro, - proc_macro_cwd, - }; - self.arena.alloc(data) + ws_data, + }) } pub fn add_dep( &mut self, - from: CrateId, - dep: Dependency, + from: CrateBuilderId, + dep: DependencyBuilder, ) -> Result<(), CyclicDependenciesError> { let _p = tracing::info_span!("add_dep").entered(); @@ -395,37 +462,154 @@ impl CrateGraph { // that out, look for a path in the *opposite* direction, from `to` to // `from`. if let Some(path) = self.find_path(&mut FxHashSet::default(), dep.crate_id, from) { - let path = path.into_iter().map(|it| (it, self[it].display_name.clone())).collect(); + let path = + path.into_iter().map(|it| (it, self[it].extra.display_name.clone())).collect(); let err = CyclicDependenciesError { path }; assert!(err.from().0 == from && err.to().0 == dep.crate_id); return Err(err); } - self.arena[from].add_dep(dep); + self.arena[from].basic.dependencies.push(dep); Ok(()) } - pub fn is_empty(&self) -> bool { - self.arena.is_empty() - } + pub fn set_in_db(self, db: &mut dyn RootQueryDb) -> CratesIdMap { + let mut all_crates = Vec::with_capacity(self.arena.len()); + let mut visited = FxHashMap::default(); + let mut visited_root_files = FxHashSet::default(); - pub fn len(&self) -> usize { - self.arena.len() - } + let old_all_crates = db.all_crates(); - pub fn iter(&self) -> impl Iterator + '_ { - self.arena.iter().map(|(idx, _)| idx) + let crates_map = db.crates_map(); + // salsa doesn't compare new input to old input to see if they are the same, so here we are doing all the work ourselves. + for krate in self.iter() { + go( + &self, + db, + &crates_map, + &mut visited, + &mut visited_root_files, + &mut all_crates, + krate, + ); + } + + if **old_all_crates != *all_crates { + db.set_all_crates_with_durability( + Arc::new(all_crates.into_boxed_slice()), + Durability::MEDIUM, + ); + } + + return visited; + + fn go( + graph: &CrateGraphBuilder, + db: &mut dyn RootQueryDb, + crates_map: &CratesMap, + visited: &mut FxHashMap, + visited_root_files: &mut FxHashSet, + all_crates: &mut Vec, + source: CrateBuilderId, + ) -> Crate { + if let Some(&crate_id) = visited.get(&source) { + return crate_id; + } + let krate = &graph[source]; + let dependencies = krate + .basic + .dependencies + .iter() + .map(|dep| BuiltDependency { + crate_id: go( + graph, + db, + crates_map, + visited, + visited_root_files, + all_crates, + dep.crate_id, + ), + name: dep.name.clone(), + prelude: dep.prelude, + sysroot: dep.sysroot, + }) + .collect::>(); + let crate_data = BuiltCrateData { + dependencies, + edition: krate.basic.edition, + is_proc_macro: krate.basic.is_proc_macro, + origin: krate.basic.origin.clone(), + root_file_id: krate.basic.root_file_id, + proc_macro_cwd: krate.basic.proc_macro_cwd.clone(), + }; + let disambiguator = if visited_root_files.insert(krate.basic.root_file_id) { + None + } else { + Some(Box::new((crate_data.clone(), krate.cfg_options.to_hashable()))) + }; + + let unique_crate_data = + UniqueCrateData { root_file_id: krate.basic.root_file_id, disambiguator }; + let crate_input = match crates_map.0.entry(unique_crate_data) { + Entry::Occupied(entry) => { + let old_crate = *entry.get(); + if crate_data != *old_crate.data(db) { + old_crate.set_data(db).with_durability(Durability::MEDIUM).to(crate_data); + } + if krate.extra != *old_crate.extra_data(db) { + old_crate + .set_extra_data(db) + .with_durability(Durability::MEDIUM) + .to(krate.extra.clone()); + } + if krate.cfg_options != *old_crate.cfg_options(db) { + old_crate + .set_cfg_options(db) + .with_durability(Durability::MEDIUM) + .to(krate.cfg_options.clone()); + } + if krate.env != *old_crate.env(db) { + old_crate + .set_env(db) + .with_durability(Durability::MEDIUM) + .to(krate.env.clone()); + } + if krate.ws_data != *old_crate.workspace_data(db) { + old_crate + .set_workspace_data(db) + .with_durability(Durability::MEDIUM) + .to(krate.ws_data.clone()); + } + old_crate + } + Entry::Vacant(entry) => { + let input = Crate::builder( + crate_data, + krate.extra.clone(), + krate.ws_data.clone(), + krate.cfg_options.clone(), + krate.env.clone(), + ) + .durability(Durability::MEDIUM) + .new(db); + entry.insert(input); + input + } + }; + all_crates.push(crate_input); + visited.insert(source, crate_input); + crate_input + } } - // FIXME: used for fixing up the toolchain sysroot, should be removed and done differently - #[doc(hidden)] - pub fn iter_mut(&mut self) -> impl Iterator + '_ { - self.arena.iter_mut() + pub fn iter(&self) -> impl Iterator + '_ { + self.arena.iter().map(|(idx, _)| idx) } /// Returns an iterator over all transitive dependencies of the given crate, /// including the crate itself. - pub fn transitive_deps(&self, of: CrateId) -> impl Iterator { + pub fn transitive_deps(&self, of: CrateBuilderId) -> impl Iterator { let mut worklist = vec![of]; let mut deps = FxHashSet::default(); @@ -434,42 +618,15 @@ impl CrateGraph { continue; } - worklist.extend(self[krate].dependencies.iter().map(|dep| dep.crate_id)); + worklist.extend(self[krate].basic.dependencies.iter().map(|dep| dep.crate_id)); } deps.into_iter() } - /// Returns all transitive reverse dependencies of the given crate, - /// including the crate itself. - pub fn transitive_rev_deps(&self, of: CrateId) -> impl Iterator { - let mut worklist = vec![of]; - let mut rev_deps = FxHashSet::default(); - rev_deps.insert(of); - - let mut inverted_graph = FxHashMap::<_, Vec<_>>::default(); - self.arena.iter().for_each(|(krate, data)| { - data.dependencies - .iter() - .for_each(|dep| inverted_graph.entry(dep.crate_id).or_default().push(krate)) - }); - - while let Some(krate) = worklist.pop() { - if let Some(krate_rev_deps) = inverted_graph.get(&krate) { - krate_rev_deps - .iter() - .copied() - .filter(|&rev_dep| rev_deps.insert(rev_dep)) - .for_each(|rev_dep| worklist.push(rev_dep)); - } - } - - rev_deps.into_iter() - } - /// Returns all crates in the graph, sorted in topological order (ie. dependencies of a crate /// come before the crate itself). - pub fn crates_in_topological_order(&self) -> Vec { + fn crates_in_topological_order(&self) -> Vec { let mut res = Vec::new(); let mut visited = FxHashSet::default(); @@ -480,15 +637,15 @@ impl CrateGraph { return res; fn go( - graph: &CrateGraph, - visited: &mut FxHashSet, - res: &mut Vec, - source: CrateId, + graph: &CrateGraphBuilder, + visited: &mut FxHashSet, + res: &mut Vec, + source: CrateBuilderId, ) { if !visited.insert(source) { return; } - for dep in graph[source].dependencies.iter() { + for dep in graph[source].basic.dependencies.iter() { go(graph, visited, res, dep.crate_id) } res.push(source) @@ -504,23 +661,27 @@ impl CrateGraph { /// Returns a map mapping `other`'s IDs to the new IDs in `self`. pub fn extend( &mut self, - mut other: CrateGraph, + mut other: CrateGraphBuilder, proc_macros: &mut ProcMacroPaths, - ) -> FxHashMap { + ) -> FxHashMap { // Sorting here is a bit pointless because the input is likely already sorted. // However, the overhead is small and it makes the `extend` method harder to misuse. self.arena .iter_mut() - .for_each(|(_, data)| data.dependencies.sort_by_key(|dep| dep.crate_id)); + .for_each(|(_, data)| data.basic.dependencies.sort_by_key(|dep| dep.crate_id)); - let m = self.len(); + let m = self.arena.len(); let topo = other.crates_in_topological_order(); - let mut id_map: FxHashMap = FxHashMap::default(); + let mut id_map: FxHashMap = FxHashMap::default(); for topo in topo { let crate_data = &mut other.arena[topo]; - crate_data.dependencies.iter_mut().for_each(|dep| dep.crate_id = id_map[&dep.crate_id]); - crate_data.dependencies.sort_by_key(|dep| dep.crate_id); + crate_data + .basic + .dependencies + .iter_mut() + .for_each(|dep| dep.crate_id = id_map[&dep.crate_id]); + crate_data.basic.dependencies.sort_by_key(|dep| dep.crate_id); let find = self.arena.iter().take(m).find_map(|(k, v)| (v == crate_data).then_some(k)); let new_id = find.unwrap_or_else(|| self.arena.alloc(crate_data.clone())); @@ -534,10 +695,10 @@ impl CrateGraph { fn find_path( &self, - visited: &mut FxHashSet, - from: CrateId, - to: CrateId, - ) -> Option> { + visited: &mut FxHashSet, + from: CrateBuilderId, + to: CrateBuilderId, + ) -> Option> { if !visited.insert(from) { return None; } @@ -546,7 +707,7 @@ impl CrateGraph { return Some(vec![to]); } - for dep in &self[from].dependencies { + for dep in &self[from].basic.dependencies { let crate_id = dep.crate_id; if let Some(mut path) = self.find_path(visited, crate_id, to) { path.push(from); @@ -559,7 +720,10 @@ impl CrateGraph { /// Removes all crates from this crate graph except for the ones in `to_keep` and fixes up the dependencies. /// Returns a mapping from old crate ids to new crate ids. - pub fn remove_crates_except(&mut self, to_keep: &[CrateId]) -> Vec> { + pub fn remove_crates_except( + &mut self, + to_keep: &[CrateBuilderId], + ) -> Vec> { let mut id_map = vec![None; self.arena.len()]; self.arena = std::mem::take(&mut self.arena) .into_iter() @@ -567,12 +731,12 @@ impl CrateGraph { .enumerate() .map(|(new_id, (id, data))| { id_map[id.into_raw().into_u32() as usize] = - Some(CrateId::from_raw(RawIdx::from_u32(new_id as u32))); + Some(CrateBuilderId::from_raw(RawIdx::from_u32(new_id as u32))); data }) .collect(); for (_, data) in self.arena.iter_mut() { - data.dependencies.iter_mut().for_each(|dep| { + data.basic.dependencies.iter_mut().for_each(|dep| { dep.crate_id = id_map[dep.crate_id.into_raw().into_u32() as usize].expect("crate was filtered") }); @@ -585,22 +749,36 @@ impl CrateGraph { } } -impl ops::Index for CrateGraph { - type Output = CrateData; - fn index(&self, crate_id: CrateId) -> &CrateData { - &self.arena[crate_id] +pub(crate) fn transitive_rev_deps(db: &dyn RootQueryDb, of: Crate) -> FxHashSet { + let mut worklist = vec![of]; + let mut rev_deps = FxHashSet::default(); + rev_deps.insert(of); + + let mut inverted_graph = FxHashMap::<_, Vec<_>>::default(); + db.all_crates().iter().for_each(|&krate| { + krate + .data(db) + .dependencies + .iter() + .for_each(|dep| inverted_graph.entry(dep.crate_id).or_default().push(krate)) + }); + + while let Some(krate) = worklist.pop() { + if let Some(crate_rev_deps) = inverted_graph.get(&krate) { + crate_rev_deps + .iter() + .copied() + .filter(|&rev_dep| rev_deps.insert(rev_dep)) + .for_each(|rev_dep| worklist.push(rev_dep)); + } } -} -impl CrateData { - /// Add a dependency to `self` without checking if the dependency - // is existent among `self.dependencies`. - fn add_dep(&mut self, dep: Dependency) { - self.dependencies.push(dep) - } + rev_deps +} - pub fn root_file_id(&self) -> EditionedFileId { - EditionedFileId::new(self.root_file_id, self.edition) +impl BuiltCrateData { + pub fn root_file_id(&self, db: &dyn salsa::Database) -> EditionedFileId { + EditionedFileId::new(db, self.root_file_id, self.edition) } } @@ -657,21 +835,21 @@ impl<'a> IntoIterator for &'a Env { #[derive(Debug)] pub struct CyclicDependenciesError { - path: Vec<(CrateId, Option)>, + path: Vec<(CrateBuilderId, Option)>, } impl CyclicDependenciesError { - fn from(&self) -> &(CrateId, Option) { + fn from(&self) -> &(CrateBuilderId, Option) { self.path.first().unwrap() } - fn to(&self) -> &(CrateId, Option) { + fn to(&self) -> &(CrateBuilderId, Option) { self.path.last().unwrap() } } impl fmt::Display for CyclicDependenciesError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let render = |(id, name): &(CrateId, Option)| match name { + let render = |(id, name): &(CrateBuilderId, Option)| match name { Some(it) => format!("{it}({id:?})"), None => format!("{id:?}"), }; @@ -688,13 +866,20 @@ impl fmt::Display for CyclicDependenciesError { #[cfg(test)] mod tests { - use crate::CrateOrigin; + use triomphe::Arc; + use vfs::AbsPathBuf; + + use crate::{CrateWorkspaceData, DependencyBuilder}; - use super::{CrateGraph, CrateName, Dependency, Edition::Edition2018, Env, FileId}; + use super::{CrateGraphBuilder, CrateName, CrateOrigin, Edition::Edition2018, Env, FileId}; + + fn empty_ws_data() -> Arc { + Arc::new(CrateWorkspaceData { data_layout: Err("".into()), toolchain: None }) + } #[test] fn detect_cyclic_dependency_indirect() { - let mut graph = CrateGraph::default(); + let mut graph = CrateGraphBuilder::default(); let crate1 = graph.add_crate_root( FileId::from_raw(1u32), Edition2018, @@ -705,7 +890,8 @@ mod tests { Env::default(), CrateOrigin::Local { repo: None, name: None }, false, - None, + Arc::new(AbsPathBuf::assert_utf8(std::env::current_dir().unwrap())), + empty_ws_data(), ); let crate2 = graph.add_crate_root( FileId::from_raw(2u32), @@ -717,7 +903,8 @@ mod tests { Env::default(), CrateOrigin::Local { repo: None, name: None }, false, - None, + Arc::new(AbsPathBuf::assert_utf8(std::env::current_dir().unwrap())), + empty_ws_data(), ); let crate3 = graph.add_crate_root( FileId::from_raw(3u32), @@ -729,22 +916,29 @@ mod tests { Env::default(), CrateOrigin::Local { repo: None, name: None }, false, - None, + Arc::new(AbsPathBuf::assert_utf8(std::env::current_dir().unwrap())), + empty_ws_data(), + ); + assert!( + graph + .add_dep(crate1, DependencyBuilder::new(CrateName::new("crate2").unwrap(), crate2,)) + .is_ok() + ); + assert!( + graph + .add_dep(crate2, DependencyBuilder::new(CrateName::new("crate3").unwrap(), crate3,)) + .is_ok() + ); + assert!( + graph + .add_dep(crate3, DependencyBuilder::new(CrateName::new("crate1").unwrap(), crate1,)) + .is_err() ); - assert!(graph - .add_dep(crate1, Dependency::new(CrateName::new("crate2").unwrap(), crate2,)) - .is_ok()); - assert!(graph - .add_dep(crate2, Dependency::new(CrateName::new("crate3").unwrap(), crate3,)) - .is_ok()); - assert!(graph - .add_dep(crate3, Dependency::new(CrateName::new("crate1").unwrap(), crate1,)) - .is_err()); } #[test] fn detect_cyclic_dependency_direct() { - let mut graph = CrateGraph::default(); + let mut graph = CrateGraphBuilder::default(); let crate1 = graph.add_crate_root( FileId::from_raw(1u32), Edition2018, @@ -755,7 +949,8 @@ mod tests { Env::default(), CrateOrigin::Local { repo: None, name: None }, false, - None, + Arc::new(AbsPathBuf::assert_utf8(std::env::current_dir().unwrap())), + empty_ws_data(), ); let crate2 = graph.add_crate_root( FileId::from_raw(2u32), @@ -767,19 +962,24 @@ mod tests { Env::default(), CrateOrigin::Local { repo: None, name: None }, false, - None, + Arc::new(AbsPathBuf::assert_utf8(std::env::current_dir().unwrap())), + empty_ws_data(), + ); + assert!( + graph + .add_dep(crate1, DependencyBuilder::new(CrateName::new("crate2").unwrap(), crate2,)) + .is_ok() + ); + assert!( + graph + .add_dep(crate2, DependencyBuilder::new(CrateName::new("crate2").unwrap(), crate2,)) + .is_err() ); - assert!(graph - .add_dep(crate1, Dependency::new(CrateName::new("crate2").unwrap(), crate2,)) - .is_ok()); - assert!(graph - .add_dep(crate2, Dependency::new(CrateName::new("crate2").unwrap(), crate2,)) - .is_err()); } #[test] fn it_works() { - let mut graph = CrateGraph::default(); + let mut graph = CrateGraphBuilder::default(); let crate1 = graph.add_crate_root( FileId::from_raw(1u32), Edition2018, @@ -790,7 +990,8 @@ mod tests { Env::default(), CrateOrigin::Local { repo: None, name: None }, false, - None, + Arc::new(AbsPathBuf::assert_utf8(std::env::current_dir().unwrap())), + empty_ws_data(), ); let crate2 = graph.add_crate_root( FileId::from_raw(2u32), @@ -802,7 +1003,8 @@ mod tests { Env::default(), CrateOrigin::Local { repo: None, name: None }, false, - None, + Arc::new(AbsPathBuf::assert_utf8(std::env::current_dir().unwrap())), + empty_ws_data(), ); let crate3 = graph.add_crate_root( FileId::from_raw(3u32), @@ -814,19 +1016,24 @@ mod tests { Env::default(), CrateOrigin::Local { repo: None, name: None }, false, - None, + Arc::new(AbsPathBuf::assert_utf8(std::env::current_dir().unwrap())), + empty_ws_data(), + ); + assert!( + graph + .add_dep(crate1, DependencyBuilder::new(CrateName::new("crate2").unwrap(), crate2,)) + .is_ok() + ); + assert!( + graph + .add_dep(crate2, DependencyBuilder::new(CrateName::new("crate3").unwrap(), crate3,)) + .is_ok() ); - assert!(graph - .add_dep(crate1, Dependency::new(CrateName::new("crate2").unwrap(), crate2,)) - .is_ok()); - assert!(graph - .add_dep(crate2, Dependency::new(CrateName::new("crate3").unwrap(), crate3,)) - .is_ok()); } #[test] fn dashes_are_normalized() { - let mut graph = CrateGraph::default(); + let mut graph = CrateGraphBuilder::default(); let crate1 = graph.add_crate_root( FileId::from_raw(1u32), Edition2018, @@ -837,7 +1044,8 @@ mod tests { Env::default(), CrateOrigin::Local { repo: None, name: None }, false, - None, + Arc::new(AbsPathBuf::assert_utf8(std::env::current_dir().unwrap())), + empty_ws_data(), ); let crate2 = graph.add_crate_root( FileId::from_raw(2u32), @@ -849,17 +1057,25 @@ mod tests { Env::default(), CrateOrigin::Local { repo: None, name: None }, false, - None, + Arc::new(AbsPathBuf::assert_utf8(std::env::current_dir().unwrap())), + empty_ws_data(), + ); + assert!( + graph + .add_dep( + crate1, + DependencyBuilder::new( + CrateName::normalize_dashes("crate-name-with-dashes"), + crate2, + ) + ) + .is_ok() ); - assert!(graph - .add_dep( - crate1, - Dependency::new(CrateName::normalize_dashes("crate-name-with-dashes"), crate2,) - ) - .is_ok()); assert_eq!( - graph[crate1].dependencies, - vec![Dependency::new(CrateName::new("crate_name_with_dashes").unwrap(), crate2,)] + graph.arena[crate1].basic.dependencies, + vec![ + DependencyBuilder::new(CrateName::new("crate_name_with_dashes").unwrap(), crate2,) + ] ); } } diff --git a/src/tools/rust-analyzer/crates/base-db/src/lib.rs b/src/tools/rust-analyzer/crates/base-db/src/lib.rs index eed8c88683951..7f7a712577e41 100644 --- a/src/tools/rust-analyzer/crates/base-db/src/lib.rs +++ b/src/tools/rust-analyzer/crates/base-db/src/lib.rs @@ -3,201 +3,373 @@ mod change; mod input; -use std::panic; - -use ra_salsa::Durability; -use rustc_hash::FxHashMap; -use span::EditionedFileId; -use syntax::{ast, Parse, SourceFile, SyntaxError}; -use triomphe::Arc; -use vfs::FileId; +use std::hash::BuildHasherDefault; pub use crate::{ change::FileChange, input::{ - CrateData, CrateDisplayName, CrateGraph, CrateId, CrateName, CrateOrigin, Dependency, Env, - LangCrateOrigin, ProcMacroPaths, ReleaseChannel, SourceRoot, SourceRootId, - TargetLayoutLoadResult, + BuiltCrateData, BuiltDependency, Crate, CrateBuilder, CrateBuilderId, CrateDataBuilder, + CrateDisplayName, CrateGraphBuilder, CrateName, CrateOrigin, CratesIdMap, CratesMap, + DependencyBuilder, Env, ExtraCrateData, LangCrateOrigin, ProcMacroPaths, ReleaseChannel, + SourceRoot, SourceRootId, TargetLayoutLoadResult, UniqueCrateData, }, }; -pub use ra_salsa::{self, Cancelled}; -pub use vfs::{file_set::FileSet, AnchoredPath, AnchoredPathBuf, VfsPath}; - +use dashmap::{DashMap, mapref::entry::Entry}; +pub use query_group::{self}; +use rustc_hash::{FxHashSet, FxHasher}; +pub use salsa::{self}; +use salsa::{Durability, Setter}; pub use semver::{BuildMetadata, Prerelease, Version, VersionReq}; +use span::Edition; +use syntax::{Parse, SyntaxError, ast}; +use triomphe::Arc; +pub use vfs::{AnchoredPath, AnchoredPathBuf, FileId, VfsPath, file_set::FileSet}; #[macro_export] macro_rules! impl_intern_key { - ($name:ident) => { - impl $crate::ra_salsa::InternKey for $name { - fn from_intern_id(v: $crate::ra_salsa::InternId) -> Self { - $name(v) - } - fn as_intern_id(&self) -> $crate::ra_salsa::InternId { - self.0 + ($id:ident, $loc:ident) => { + #[salsa::interned(no_lifetime)] + pub struct $id { + pub loc: $loc, + } + + // If we derive this salsa prints the values recursively, and this causes us to blow. + impl ::std::fmt::Debug for $id { + fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result { + f.debug_tuple(stringify!($id)) + .field(&format_args!("{:04x}", self.0.as_u32())) + .finish() } } }; } -pub trait Upcast { - fn upcast(&self) -> &T; -} - pub const DEFAULT_FILE_TEXT_LRU_CAP: u16 = 16; pub const DEFAULT_PARSE_LRU_CAP: u16 = 128; pub const DEFAULT_BORROWCK_LRU_CAP: u16 = 2024; -pub trait FileLoader { - fn resolve_path(&self, path: AnchoredPath<'_>) -> Option; - /// Crates whose root's source root is the same as the source root of `file_id` - fn relevant_crates(&self, file_id: FileId) -> Arc<[CrateId]>; +#[derive(Debug, Default)] +pub struct Files { + files: Arc>>, + source_roots: Arc>>, + file_source_roots: Arc>>, } -/// Database which stores all significant input facts: source code and project -/// model. Everything else in rust-analyzer is derived from these queries. -#[ra_salsa::query_group(SourceDatabaseStorage)] -pub trait SourceDatabase: FileLoader + std::fmt::Debug { - #[ra_salsa::input] - fn compressed_file_text(&self, file_id: FileId) -> Arc<[u8]>; +impl Files { + pub fn file_text(&self, file_id: vfs::FileId) -> FileText { + *self.files.get(&file_id).expect("Unable to fetch file; this is a bug") + } - /// Text of the file. - #[ra_salsa::lru] - fn file_text(&self, file_id: FileId) -> Arc; + pub fn set_file_text(&self, db: &mut dyn SourceDatabase, file_id: vfs::FileId, text: &str) { + match self.files.entry(file_id) { + Entry::Occupied(mut occupied) => { + occupied.get_mut().set_text(db).to(Arc::from(text)); + } + Entry::Vacant(vacant) => { + let text = FileText::new(db, Arc::from(text), file_id); + vacant.insert(text); + } + }; + } - /// Parses the file into the syntax tree. - #[ra_salsa::lru] - fn parse(&self, file_id: EditionedFileId) -> Parse; + pub fn set_file_text_with_durability( + &self, + db: &mut dyn SourceDatabase, + file_id: vfs::FileId, + text: &str, + durability: Durability, + ) { + match self.files.entry(file_id) { + Entry::Occupied(mut occupied) => { + occupied.get_mut().set_text(db).with_durability(durability).to(Arc::from(text)); + } + Entry::Vacant(vacant) => { + let text = + FileText::builder(Arc::from(text), file_id).durability(durability).new(db); + vacant.insert(text); + } + }; + } - /// Returns the set of errors obtained from parsing the file including validation errors. - fn parse_errors(&self, file_id: EditionedFileId) -> Option>; + /// Source root of the file. + pub fn source_root(&self, source_root_id: SourceRootId) -> SourceRootInput { + let source_root = self + .source_roots + .get(&source_root_id) + .expect("Unable to fetch source root id; this is a bug"); - /// The crate graph. - #[ra_salsa::input] - fn crate_graph(&self) -> Arc; + *source_root + } - #[ra_salsa::input] - fn crate_workspace_data(&self) -> Arc>>; + pub fn set_source_root_with_durability( + &self, + db: &mut dyn SourceDatabase, + source_root_id: SourceRootId, + source_root: Arc, + durability: Durability, + ) { + match self.source_roots.entry(source_root_id) { + Entry::Occupied(mut occupied) => { + occupied.get_mut().set_source_root(db).with_durability(durability).to(source_root); + } + Entry::Vacant(vacant) => { + let source_root = + SourceRootInput::builder(source_root).durability(durability).new(db); + vacant.insert(source_root); + } + }; + } + + pub fn file_source_root(&self, id: vfs::FileId) -> FileSourceRootInput { + let file_source_root = self + .file_source_roots + .get(&id) + .expect("Unable to fetch FileSourceRootInput; this is a bug"); + *file_source_root + } - #[ra_salsa::transparent] - fn toolchain_channel(&self, krate: CrateId) -> Option; + pub fn set_file_source_root_with_durability( + &self, + db: &mut dyn SourceDatabase, + id: vfs::FileId, + source_root_id: SourceRootId, + durability: Durability, + ) { + match self.file_source_roots.entry(id) { + Entry::Occupied(mut occupied) => { + occupied + .get_mut() + .set_source_root_id(db) + .with_durability(durability) + .to(source_root_id); + } + Entry::Vacant(vacant) => { + let file_source_root = + FileSourceRootInput::builder(source_root_id).durability(durability).new(db); + vacant.insert(file_source_root); + } + }; + } } -/// Crate related data shared by the whole workspace. -#[derive(Debug, PartialEq, Eq, Hash, Clone)] -pub struct CrateWorkspaceData { - // FIXME: Consider removing this, making HirDatabase::target_data_layout an input query - pub data_layout: TargetLayoutLoadResult, - /// Toolchain version used to compile the crate. - pub toolchain: Option, +#[salsa::interned(no_lifetime, debug, constructor=from_span)] +pub struct EditionedFileId { + pub editioned_file_id: span::EditionedFileId, } -fn toolchain_channel(db: &dyn SourceDatabase, krate: CrateId) -> Option { - db.crate_workspace_data() - .get(&krate)? - .toolchain - .as_ref() - .and_then(|v| ReleaseChannel::from_str(&v.pre)) +impl EditionedFileId { + // Salsa already uses the name `new`... + #[inline] + pub fn new(db: &dyn salsa::Database, file_id: FileId, edition: Edition) -> Self { + EditionedFileId::from_span(db, span::EditionedFileId::new(file_id, edition)) + } + + #[inline] + pub fn current_edition(db: &dyn salsa::Database, file_id: FileId) -> Self { + EditionedFileId::new(db, file_id, Edition::CURRENT) + } + + #[inline] + pub fn file_id(self, db: &dyn salsa::Database) -> vfs::FileId { + let id = self.editioned_file_id(db); + id.file_id() + } + + #[inline] + pub fn unpack(self, db: &dyn salsa::Database) -> (vfs::FileId, span::Edition) { + let id = self.editioned_file_id(db); + (id.file_id(), id.edition()) + } + + #[inline] + pub fn edition(self, db: &dyn SourceDatabase) -> Edition { + self.editioned_file_id(db).edition() + } } -fn parse(db: &dyn SourceDatabase, file_id: EditionedFileId) -> Parse { - let _p = tracing::info_span!("parse", ?file_id).entered(); - let (file_id, edition) = file_id.unpack(); - let text = db.file_text(file_id); - SourceFile::parse(&text, edition) +#[salsa::input(debug)] +pub struct FileText { + pub text: Arc, + pub file_id: vfs::FileId, } -fn parse_errors(db: &dyn SourceDatabase, file_id: EditionedFileId) -> Option> { - let errors = db.parse(file_id).errors(); - match &*errors { - [] => None, - [..] => Some(errors.into()), - } +#[salsa::input(debug)] +pub struct FileSourceRootInput { + pub source_root_id: SourceRootId, } -fn file_text(db: &dyn SourceDatabase, file_id: FileId) -> Arc { - let bytes = db.compressed_file_text(file_id); - let bytes = - lz4_flex::decompress_size_prepended(&bytes).expect("lz4 decompression should not fail"); - let text = std::str::from_utf8(&bytes).expect("file contents should be valid UTF-8"); - Arc::from(text) +#[salsa::input(debug)] +pub struct SourceRootInput { + pub source_root: Arc, } -/// We don't want to give HIR knowledge of source roots, hence we extract these -/// methods into a separate DB. -#[ra_salsa::query_group(SourceRootDatabaseStorage)] -pub trait SourceRootDatabase: SourceDatabase { - /// Path to a file, relative to the root of its source root. - /// Source root of the file. - #[ra_salsa::input] - fn file_source_root(&self, file_id: FileId) -> SourceRootId; - /// Contents of the source root. - #[ra_salsa::input] - fn source_root(&self, id: SourceRootId) -> Arc; +/// Database which stores all significant input facts: source code and project +/// model. Everything else in rust-analyzer is derived from these queries. +#[query_group::query_group] +pub trait RootQueryDb: SourceDatabase + salsa::Database { + /// Parses the file into the syntax tree. + #[salsa::invoke(parse)] + #[salsa::lru(128)] + fn parse(&self, file_id: EditionedFileId) -> Parse; + + /// Returns the set of errors obtained from parsing the file including validation errors. + #[salsa::transparent] + fn parse_errors(&self, file_id: EditionedFileId) -> Option<&[SyntaxError]>; + + #[salsa::transparent] + fn toolchain_channel(&self, krate: Crate) -> Option; /// Crates whose root file is in `id`. - fn source_root_crates(&self, id: SourceRootId) -> Arc<[CrateId]>; + #[salsa::invoke_interned(source_root_crates)] + fn source_root_crates(&self, id: SourceRootId) -> Arc<[Crate]>; + + #[salsa::transparent] + fn relevant_crates(&self, file_id: FileId) -> Arc<[Crate]>; + + /// Returns the crates in topological order. + /// + /// **Warning**: do not use this query in `hir-*` crates! It kills incrementality across crate metadata modifications. + #[salsa::input] + fn all_crates(&self) -> Arc>; + + /// Returns an iterator over all transitive dependencies of the given crate, + /// including the crate itself. + /// + /// **Warning**: do not use this query in `hir-*` crates! It kills incrementality across crate metadata modifications. + #[salsa::transparent] + fn transitive_deps(&self, crate_id: Crate) -> FxHashSet; + + /// Returns all transitive reverse dependencies of the given crate, + /// including the crate itself. + /// + /// **Warning**: do not use this query in `hir-*` crates! It kills incrementality across crate metadata modifications. + #[salsa::invoke(input::transitive_rev_deps)] + #[salsa::transparent] + fn transitive_rev_deps(&self, of: Crate) -> FxHashSet; } -pub trait SourceDatabaseFileInputExt { - fn set_file_text(&mut self, file_id: FileId, text: &str) { - self.set_file_text_with_durability(file_id, text, Durability::LOW); +pub fn transitive_deps(db: &dyn SourceDatabase, crate_id: Crate) -> FxHashSet { + // There is a bit of duplication here and in `CrateGraphBuilder` in the same method, but it's not terrible + // and removing that is a bit difficult. + let mut worklist = vec![crate_id]; + let mut deps = FxHashSet::default(); + + while let Some(krate) = worklist.pop() { + if !deps.insert(krate) { + continue; + } + + worklist.extend(krate.data(db).dependencies.iter().map(|dep| dep.crate_id)); } + deps +} + +#[salsa::db] +pub trait SourceDatabase: salsa::Database { + /// Text of the file. + fn file_text(&self, file_id: vfs::FileId) -> FileText; + + fn set_file_text(&mut self, file_id: vfs::FileId, text: &str); + fn set_file_text_with_durability( &mut self, - file_id: FileId, + file_id: vfs::FileId, text: &str, durability: Durability, ); -} -impl SourceDatabaseFileInputExt for Db { - fn set_file_text_with_durability( + /// Contents of the source root. + fn source_root(&self, id: SourceRootId) -> SourceRootInput; + + fn file_source_root(&self, id: vfs::FileId) -> FileSourceRootInput; + + fn set_file_source_root_with_durability( &mut self, - file_id: FileId, - text: &str, + id: vfs::FileId, + source_root_id: SourceRootId, durability: Durability, - ) { - let bytes = text.as_bytes(); - let compressed = lz4_flex::compress_prepend_size(bytes); - self.set_compressed_file_text_with_durability( - file_id, - Arc::from(compressed.as_slice()), - durability, - ) + ); + + /// Source root of the file. + fn set_source_root_with_durability( + &mut self, + source_root_id: SourceRootId, + source_root: Arc, + durability: Durability, + ); + + fn resolve_path(&self, path: AnchoredPath<'_>) -> Option { + // FIXME: this *somehow* should be platform agnostic... + let source_root = self.file_source_root(path.anchor); + let source_root = self.source_root(source_root.source_root_id(self)); + source_root.source_root(self).resolve_path(path) + } + + #[doc(hidden)] + fn crates_map(&self) -> Arc; +} + +/// Crate related data shared by the whole workspace. +#[derive(Debug, PartialEq, Eq, Hash, Clone)] +pub struct CrateWorkspaceData { + // FIXME: Consider removing this, making HirDatabase::target_data_layout an input query + pub data_layout: TargetLayoutLoadResult, + /// Toolchain version used to compile the crate. + pub toolchain: Option, +} + +impl CrateWorkspaceData { + pub fn is_atleast_187(&self) -> bool { + const VERSION_187: Version = Version { + major: 1, + minor: 87, + patch: 0, + pre: Prerelease::EMPTY, + build: BuildMetadata::EMPTY, + }; + self.toolchain.as_ref().map_or(false, |v| *v >= VERSION_187) } } -fn source_root_crates(db: &dyn SourceRootDatabase, id: SourceRootId) -> Arc<[CrateId]> { - let graph = db.crate_graph(); - let mut crates = graph +fn toolchain_channel(db: &dyn RootQueryDb, krate: Crate) -> Option { + krate.workspace_data(db).toolchain.as_ref().and_then(|v| ReleaseChannel::from_str(&v.pre)) +} + +fn parse(db: &dyn RootQueryDb, file_id: EditionedFileId) -> Parse { + let _p = tracing::info_span!("parse", ?file_id).entered(); + let (file_id, edition) = file_id.unpack(db.as_dyn_database()); + let text = db.file_text(file_id).text(db); + ast::SourceFile::parse(&text, edition) +} + +fn parse_errors(db: &dyn RootQueryDb, file_id: EditionedFileId) -> Option<&[SyntaxError]> { + #[salsa::tracked(return_ref)] + fn parse_errors(db: &dyn RootQueryDb, file_id: EditionedFileId) -> Option> { + let errors = db.parse(file_id).errors(); + match &*errors { + [] => None, + [..] => Some(errors.into()), + } + } + parse_errors(db, file_id).as_ref().map(|it| &**it) +} + +fn source_root_crates(db: &dyn RootQueryDb, id: SourceRootId) -> Arc<[Crate]> { + let crates = db.all_crates(); + crates .iter() + .copied() .filter(|&krate| { - let root_file = graph[krate].root_file_id; - db.file_source_root(root_file) == id + let root_file = krate.data(db).root_file_id; + db.file_source_root(root_file).source_root_id(db) == id }) - .collect::>(); - crates.sort(); - crates.dedup(); - crates.into_iter().collect() + .collect() } -// FIXME: Would be nice to get rid of this somehow -/// Silly workaround for cyclic deps due to the SourceRootDatabase and SourceDatabase split -/// regarding FileLoader -pub struct FileLoaderDelegate(pub T); +fn relevant_crates(db: &dyn RootQueryDb, file_id: FileId) -> Arc<[Crate]> { + let _p = tracing::info_span!("relevant_crates").entered(); -impl FileLoader for FileLoaderDelegate<&'_ T> { - fn resolve_path(&self, path: AnchoredPath<'_>) -> Option { - // FIXME: this *somehow* should be platform agnostic... - let source_root = self.0.file_source_root(path.anchor); - let source_root = self.0.source_root(source_root); - source_root.resolve_path(path) - } - - fn relevant_crates(&self, file_id: FileId) -> Arc<[CrateId]> { - let _p = tracing::info_span!("relevant_crates").entered(); - let source_root = self.0.file_source_root(file_id); - self.0.source_root_crates(source_root) - } + let source_root = db.file_source_root(file_id); + db.source_root_crates(source_root.source_root_id(db)) } diff --git a/src/tools/rust-analyzer/crates/cfg/Cargo.toml b/src/tools/rust-analyzer/crates/cfg/Cargo.toml index e887368ef28f8..d7764a16c044c 100644 --- a/src/tools/rust-analyzer/crates/cfg/Cargo.toml +++ b/src/tools/rust-analyzer/crates/cfg/Cargo.toml @@ -20,13 +20,13 @@ tt = { workspace = true, optional = true } intern.workspace = true [dev-dependencies] -expect-test = "1.4.1" -oorandom = "11.1.3" +expect-test = "1.5.1" +oorandom = "11.1.5" # We depend on both individually instead of using `features = ["derive"]` to microoptimize the # build graph: if the feature was enabled, syn would be built early on in the graph if `smolstr` # supports `arbitrary`. This way, we avoid feature unification. -arbitrary = "1.3.2" -derive_arbitrary = "1.3.2" +arbitrary = "1.4.1" +derive_arbitrary = "1.4.1" # local deps syntax-bridge.workspace = true diff --git a/src/tools/rust-analyzer/crates/cfg/src/lib.rs b/src/tools/rust-analyzer/crates/cfg/src/lib.rs index 08545b685119d..906106ca5db0b 100644 --- a/src/tools/rust-analyzer/crates/cfg/src/lib.rs +++ b/src/tools/rust-analyzer/crates/cfg/src/lib.rs @@ -9,7 +9,7 @@ use std::fmt; use rustc_hash::FxHashSet; -use intern::{sym, Symbol}; +use intern::{Symbol, sym}; pub use cfg_expr::{CfgAtom, CfgExpr}; pub use dnf::DnfExpr; @@ -31,7 +31,7 @@ pub struct CfgOptions { impl Default for CfgOptions { fn default() -> Self { - Self { enabled: FxHashSet::from_iter([CfgAtom::Flag(sym::true_.clone())]) } + Self { enabled: FxHashSet::from_iter([CfgAtom::Flag(sym::true_)]) } } } @@ -104,6 +104,17 @@ impl CfgOptions { _ => None, }) } + + pub fn to_hashable(&self) -> HashableCfgOptions { + let mut enabled = self.enabled.iter().cloned().collect::>(); + enabled.sort_unstable(); + HashableCfgOptions { _enabled: enabled } + } + + #[inline] + pub fn shrink_to_fit(&mut self) { + self.enabled.shrink_to_fit(); + } } impl Extend for CfgOptions { @@ -256,3 +267,9 @@ impl fmt::Display for InactiveReason { Ok(()) } } + +/// A `CfgOptions` that implements `Hash`, for the sake of hashing only. +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct HashableCfgOptions { + _enabled: Box<[CfgAtom]>, +} diff --git a/src/tools/rust-analyzer/crates/cfg/src/tests.rs b/src/tools/rust-analyzer/crates/cfg/src/tests.rs index 6d87d83ad9300..6766748097f00 100644 --- a/src/tools/rust-analyzer/crates/cfg/src/tests.rs +++ b/src/tools/rust-analyzer/crates/cfg/src/tests.rs @@ -1,10 +1,11 @@ use arbitrary::{Arbitrary, Unstructured}; -use expect_test::{expect, Expect}; +use expect_test::{Expect, expect}; use intern::Symbol; -use syntax::{ast, AstNode, Edition}; +use syntax::{AstNode, Edition, ast}; use syntax_bridge::{ - dummy_test_span_utils::{DummyTestSpanMap, DUMMY}, - syntax_node_to_token_tree, DocCommentDesugarMode, + DocCommentDesugarMode, + dummy_test_span_utils::{DUMMY, DummyTestSpanMap}, + syntax_node_to_token_tree, }; use crate::{CfgAtom, CfgExpr, CfgOptions, DnfExpr}; diff --git a/src/tools/rust-analyzer/crates/edition/src/lib.rs b/src/tools/rust-analyzer/crates/edition/src/lib.rs index 7e9c94af408c1..f1a1fe596493b 100644 --- a/src/tools/rust-analyzer/crates/edition/src/lib.rs +++ b/src/tools/rust-analyzer/crates/edition/src/lib.rs @@ -15,9 +15,19 @@ pub enum Edition { impl Edition { pub const DEFAULT: Edition = Edition::Edition2015; pub const LATEST: Edition = Edition::Edition2024; - pub const CURRENT: Edition = Edition::Edition2021; + pub const CURRENT: Edition = Edition::Edition2024; /// The current latest stable edition, note this is usually not the right choice in code. - pub const CURRENT_FIXME: Edition = Edition::Edition2021; + pub const CURRENT_FIXME: Edition = Edition::Edition2024; + + pub fn from_u32(u32: u32) -> Edition { + match u32 { + 0 => Edition::Edition2015, + 1 => Edition::Edition2018, + 2 => Edition::Edition2021, + 3 => Edition::Edition2024, + _ => panic!("invalid edition"), + } + } pub fn at_least_2024(self) -> bool { self >= Edition::Edition2024 @@ -31,6 +41,15 @@ impl Edition { self >= Edition::Edition2018 } + pub fn number(&self) -> usize { + match self { + Edition::Edition2015 => 2015, + Edition::Edition2018 => 2018, + Edition::Edition2021 => 2021, + Edition::Edition2024 => 2024, + } + } + pub fn iter() -> impl Iterator { [Edition::Edition2015, Edition::Edition2018, Edition::Edition2021, Edition::Edition2024] .iter() diff --git a/src/tools/rust-analyzer/crates/hir-def/Cargo.toml b/src/tools/rust-analyzer/crates/hir-def/Cargo.toml index a22961c26c84c..f97597ffe5a6b 100644 --- a/src/tools/rust-analyzer/crates/hir-def/Cargo.toml +++ b/src/tools/rust-analyzer/crates/hir-def/Cargo.toml @@ -14,8 +14,7 @@ rust-version.workspace = true [dependencies] arrayvec.workspace = true bitflags.workspace = true -cov-mark = "2.0.0-pre.1" -dashmap.workspace = true +cov-mark = "2.0.0" drop_bomb = "0.1.5" either.workspace = true fst = { version = "0.4.7", default-features = false } @@ -25,12 +24,12 @@ la-arena.workspace = true rustc-hash.workspace = true tracing.workspace = true smallvec.workspace = true -hashbrown.workspace = true triomphe.workspace = true -rustc_apfloat = "0.2.0" +rustc_apfloat = "0.2.2" text-size.workspace = true +salsa.workspace = true +query-group.workspace = true -ra-ap-rustc_hashes.workspace = true ra-ap-rustc_parse_format.workspace = true ra-ap-rustc_abi.workspace = true @@ -44,7 +43,7 @@ mbe.workspace = true cfg.workspace = true tt.workspace = true span.workspace = true - +thin-vec = "0.2.14" [dev-dependencies] expect-test.workspace = true @@ -53,6 +52,7 @@ expect-test.workspace = true test-utils.workspace = true test-fixture.workspace = true syntax-bridge.workspace = true + [features] in-rust-tree = ["hir-expand/in-rust-tree"] diff --git a/src/tools/rust-analyzer/crates/hir-def/src/attr.rs b/src/tools/rust-analyzer/crates/hir-def/src/attr.rs index 710bffcefe900..a80313aba3e49 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/attr.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/attr.rs @@ -2,31 +2,32 @@ use std::{borrow::Cow, hash::Hash, ops}; -use base_db::CrateId; +use base_db::Crate; use cfg::{CfgExpr, CfgOptions}; use either::Either; use hir_expand::{ - attrs::{collect_attrs, Attr, AttrId, RawAttrs}, HirFileId, InFile, + attrs::{Attr, AttrId, RawAttrs, collect_attrs}, }; -use intern::{sym, Symbol}; +use intern::{Symbol, sym}; use la_arena::{ArenaMap, Idx, RawIdx}; use mbe::DelimiterKind; +use rustc_abi::ReprOptions; use syntax::{ - ast::{self, HasAttrs}, AstPtr, + ast::{self, HasAttrs}, }; use triomphe::Arc; use tt::iter::{TtElement, TtIter}; use crate::{ + AdtId, AttrDefId, GenericParamId, HasModule, ItemTreeLoc, LocalFieldId, Lookup, MacroId, + VariantId, db::DefDatabase, item_tree::{AttrOwner, FieldParent, ItemTreeNode}, lang_item::LangItem, nameres::{ModuleOrigin, ModuleSource}, src::{HasChildSource, HasSource}, - AdtId, AttrDefId, GenericParamId, HasModule, ItemTreeLoc, LocalFieldId, Lookup, MacroId, - VariantId, }; /// Desugared attributes of an item post `cfg_attr` expansion. @@ -44,8 +45,8 @@ impl Attrs { (**self).iter().find(|attr| attr.id == id) } - pub(crate) fn filter(db: &dyn DefDatabase, krate: CrateId, raw_attrs: RawAttrs) -> Attrs { - Attrs(raw_attrs.filter(db.upcast(), krate)) + pub(crate) fn filter(db: &dyn DefDatabase, krate: Crate, raw_attrs: RawAttrs) -> Attrs { + Attrs(raw_attrs.filter(db, krate)) } } @@ -75,8 +76,6 @@ impl Attrs { let _p = tracing::info_span!("fields_attrs_query").entered(); // FIXME: There should be some proper form of mapping between item tree field ids and hir field ids let mut res = ArenaMap::default(); - - let crate_graph = db.crate_graph(); let item_tree; let (parent, fields, krate) = match v { VariantId::EnumVariantId(it) => { @@ -84,7 +83,7 @@ impl Attrs { let krate = loc.parent.lookup(db).container.krate; item_tree = loc.id.item_tree(db); let variant = &item_tree[loc.id.value]; - (FieldParent::Variant(loc.id.value), &variant.fields, krate) + (FieldParent::EnumVariant(loc.id.value), &variant.fields, krate) } VariantId::StructId(it) => { let loc = it.lookup(db); @@ -102,7 +101,7 @@ impl Attrs { } }; - let cfg_options = &crate_graph[krate].cfg_options; + let cfg_options = krate.cfg_options(db); let mut idx = 0; for (id, _field) in fields.iter().enumerate() { @@ -118,17 +117,20 @@ impl Attrs { } impl Attrs { - pub fn by_key<'attrs>(&'attrs self, key: &'attrs Symbol) -> AttrQuery<'attrs> { + #[inline] + pub fn by_key(&self, key: Symbol) -> AttrQuery<'_> { AttrQuery { attrs: self, key } } + #[inline] pub fn rust_analyzer_tool(&self) -> impl Iterator { self.iter() .filter(|&attr| attr.path.segments().first().is_some_and(|s| *s == sym::rust_analyzer)) } + #[inline] pub fn cfg(&self) -> Option { - let mut cfgs = self.by_key(&sym::cfg).tt_values().map(CfgExpr::parse); + let mut cfgs = self.by_key(sym::cfg).tt_values().map(CfgExpr::parse); let first = cfgs.next()?; match cfgs.next() { Some(second) => { @@ -139,10 +141,12 @@ impl Attrs { } } + #[inline] pub fn cfgs(&self) -> impl Iterator + '_ { - self.by_key(&sym::cfg).tt_values().map(CfgExpr::parse) + self.by_key(sym::cfg).tt_values().map(CfgExpr::parse) } + #[inline] pub(crate) fn is_cfg_enabled(&self, cfg_options: &CfgOptions) -> bool { match self.cfg() { None => true, @@ -150,78 +154,225 @@ impl Attrs { } } + #[inline] pub fn lang(&self) -> Option<&Symbol> { - self.by_key(&sym::lang).string_value() + self.by_key(sym::lang).string_value() } + #[inline] pub fn lang_item(&self) -> Option { - self.by_key(&sym::lang).string_value().and_then(LangItem::from_symbol) + self.by_key(sym::lang).string_value().and_then(LangItem::from_symbol) } + #[inline] pub fn has_doc_hidden(&self) -> bool { - self.by_key(&sym::doc).tt_values().any(|tt| { + self.by_key(sym::doc).tt_values().any(|tt| { tt.top_subtree().delimiter.kind == DelimiterKind::Parenthesis && matches!(tt.token_trees().flat_tokens(), [tt::TokenTree::Leaf(tt::Leaf::Ident(ident))] if ident.sym == sym::hidden) }) } + #[inline] pub fn has_doc_notable_trait(&self) -> bool { - self.by_key(&sym::doc).tt_values().any(|tt| { + self.by_key(sym::doc).tt_values().any(|tt| { tt.top_subtree().delimiter.kind == DelimiterKind::Parenthesis && matches!(tt.token_trees().flat_tokens(), [tt::TokenTree::Leaf(tt::Leaf::Ident(ident))] if ident.sym == sym::notable_trait) }) } + #[inline] pub fn doc_exprs(&self) -> impl Iterator + '_ { - self.by_key(&sym::doc).tt_values().map(DocExpr::parse) + self.by_key(sym::doc).tt_values().map(DocExpr::parse) } + #[inline] pub fn doc_aliases(&self) -> impl Iterator + '_ { self.doc_exprs().flat_map(|doc_expr| doc_expr.aliases().to_vec()) } + #[inline] pub fn export_name(&self) -> Option<&Symbol> { - self.by_key(&sym::export_name).string_value() + self.by_key(sym::export_name).string_value() } + #[inline] pub fn is_proc_macro(&self) -> bool { - self.by_key(&sym::proc_macro).exists() + self.by_key(sym::proc_macro).exists() } + #[inline] pub fn is_proc_macro_attribute(&self) -> bool { - self.by_key(&sym::proc_macro_attribute).exists() + self.by_key(sym::proc_macro_attribute).exists() } + #[inline] pub fn is_proc_macro_derive(&self) -> bool { - self.by_key(&sym::proc_macro_derive).exists() + self.by_key(sym::proc_macro_derive).exists() } + #[inline] pub fn is_test(&self) -> bool { self.iter().any(|it| { it.path() .segments() .iter() .rev() - .zip( - [sym::core.clone(), sym::prelude.clone(), sym::v1.clone(), sym::test.clone()] - .iter() - .rev(), - ) + .zip([sym::core, sym::prelude, sym::v1, sym::test].iter().rev()) .all(|it| it.0 == it.1) }) } + #[inline] pub fn is_ignore(&self) -> bool { - self.by_key(&sym::ignore).exists() + self.by_key(sym::ignore).exists() } + #[inline] pub fn is_bench(&self) -> bool { - self.by_key(&sym::bench).exists() + self.by_key(sym::bench).exists() } + #[inline] pub fn is_unstable(&self) -> bool { - self.by_key(&sym::unstable).exists() + self.by_key(sym::unstable).exists() + } + + #[inline] + pub fn rustc_legacy_const_generics(&self) -> Option>> { + self.by_key(sym::rustc_legacy_const_generics) + .tt_values() + .next() + .map(parse_rustc_legacy_const_generics) + .filter(|it| !it.is_empty()) + .map(Box::new) + } + + #[inline] + pub fn repr(&self) -> Option { + self.by_key(sym::repr).tt_values().filter_map(parse_repr_tt).fold(None, |acc, repr| { + acc.map_or(Some(repr), |mut acc| { + merge_repr(&mut acc, repr); + Some(acc) + }) + }) + } +} + +fn parse_rustc_legacy_const_generics(tt: &crate::tt::TopSubtree) -> Box<[u32]> { + let mut indices = Vec::new(); + let mut iter = tt.iter(); + while let (Some(first), second) = (iter.next(), iter.next()) { + match first { + TtElement::Leaf(tt::Leaf::Literal(lit)) => match lit.symbol.as_str().parse() { + Ok(index) => indices.push(index), + Err(_) => break, + }, + _ => break, + } + + if let Some(comma) = second { + match comma { + TtElement::Leaf(tt::Leaf::Punct(punct)) if punct.char == ',' => {} + _ => break, + } + } } + + indices.into_boxed_slice() +} + +fn merge_repr(this: &mut ReprOptions, other: ReprOptions) { + let ReprOptions { int, align, pack, flags, field_shuffle_seed: _ } = this; + flags.insert(other.flags); + *align = (*align).max(other.align); + *pack = match (*pack, other.pack) { + (Some(pack), None) | (None, Some(pack)) => Some(pack), + _ => (*pack).min(other.pack), + }; + if other.int.is_some() { + *int = other.int; + } +} + +fn parse_repr_tt(tt: &crate::tt::TopSubtree) -> Option { + use crate::builtin_type::{BuiltinInt, BuiltinUint}; + use rustc_abi::{Align, Integer, IntegerType, ReprFlags, ReprOptions}; + + match tt.top_subtree().delimiter { + tt::Delimiter { kind: DelimiterKind::Parenthesis, .. } => {} + _ => return None, + } + + let mut acc = ReprOptions::default(); + let mut tts = tt.iter(); + while let Some(tt) = tts.next() { + let TtElement::Leaf(tt::Leaf::Ident(ident)) = tt else { + continue; + }; + let repr = match &ident.sym { + s if *s == sym::packed => { + let pack = if let Some(TtElement::Subtree(_, mut tt_iter)) = tts.peek() { + tts.next(); + if let Some(TtElement::Leaf(tt::Leaf::Literal(lit))) = tt_iter.next() { + lit.symbol.as_str().parse().unwrap_or_default() + } else { + 0 + } + } else { + 0 + }; + let pack = Some(Align::from_bytes(pack).unwrap_or(Align::ONE)); + ReprOptions { pack, ..Default::default() } + } + s if *s == sym::align => { + let mut align = None; + if let Some(TtElement::Subtree(_, mut tt_iter)) = tts.peek() { + tts.next(); + if let Some(TtElement::Leaf(tt::Leaf::Literal(lit))) = tt_iter.next() { + if let Ok(a) = lit.symbol.as_str().parse() { + align = Align::from_bytes(a).ok(); + } + } + } + ReprOptions { align, ..Default::default() } + } + s if *s == sym::C => ReprOptions { flags: ReprFlags::IS_C, ..Default::default() }, + s if *s == sym::transparent => { + ReprOptions { flags: ReprFlags::IS_TRANSPARENT, ..Default::default() } + } + s if *s == sym::simd => ReprOptions { flags: ReprFlags::IS_SIMD, ..Default::default() }, + repr => { + let mut int = None; + if let Some(builtin) = BuiltinInt::from_suffix_sym(repr) + .map(Either::Left) + .or_else(|| BuiltinUint::from_suffix_sym(repr).map(Either::Right)) + { + int = Some(match builtin { + Either::Left(bi) => match bi { + BuiltinInt::Isize => IntegerType::Pointer(true), + BuiltinInt::I8 => IntegerType::Fixed(Integer::I8, true), + BuiltinInt::I16 => IntegerType::Fixed(Integer::I16, true), + BuiltinInt::I32 => IntegerType::Fixed(Integer::I32, true), + BuiltinInt::I64 => IntegerType::Fixed(Integer::I64, true), + BuiltinInt::I128 => IntegerType::Fixed(Integer::I128, true), + }, + Either::Right(bu) => match bu { + BuiltinUint::Usize => IntegerType::Pointer(false), + BuiltinUint::U8 => IntegerType::Fixed(Integer::I8, false), + BuiltinUint::U16 => IntegerType::Fixed(Integer::I16, false), + BuiltinUint::U32 => IntegerType::Fixed(Integer::I32, false), + BuiltinUint::U64 => IntegerType::Fixed(Integer::I64, false), + BuiltinUint::U128 => IntegerType::Fixed(Integer::I128, false), + }, + }); + } + ReprOptions { int, ..Default::default() } + } + }; + merge_repr(&mut acc, repr); + } + + Some(acc) } #[derive(Debug, Clone, PartialEq, Eq, Hash)] @@ -373,7 +524,7 @@ impl AttrsWithOwner { // FIXME: We should be never getting `None` here. match src.value.get(it.local_id()) { Some(val) => RawAttrs::from_attrs_owner( - db.upcast(), + db, src.with_value(val), db.span_map(src.file_id).as_ref(), ), @@ -385,7 +536,7 @@ impl AttrsWithOwner { // FIXME: We should be never getting `None` here. match src.value.get(it.local_id()) { Some(val) => RawAttrs::from_attrs_owner( - db.upcast(), + db, src.with_value(val), db.span_map(src.file_id).as_ref(), ), @@ -397,7 +548,7 @@ impl AttrsWithOwner { // FIXME: We should be never getting `None` here. match src.value.get(it.local_id) { Some(val) => RawAttrs::from_attrs_owner( - db.upcast(), + db, src.with_value(val), db.span_map(src.file_id).as_ref(), ), @@ -410,7 +561,7 @@ impl AttrsWithOwner { AttrDefId::UseId(it) => attrs_from_item_tree_loc(db, it), }; - let attrs = raw_attrs.filter(db.upcast(), def.krate(db)); + let attrs = raw_attrs.filter(db, def.krate(db)); Attrs(attrs) } @@ -547,36 +698,42 @@ impl AttrSourceMap { } } -#[derive(Debug, Clone, Copy)] +#[derive(Debug, Clone)] pub struct AttrQuery<'attr> { attrs: &'attr Attrs, - key: &'attr Symbol, + key: Symbol, } impl<'attr> AttrQuery<'attr> { + #[inline] pub fn tt_values(self) -> impl Iterator { self.attrs().filter_map(|attr| attr.token_tree_value()) } + #[inline] pub fn string_value(self) -> Option<&'attr Symbol> { self.attrs().find_map(|attr| attr.string_value()) } + #[inline] pub fn string_value_with_span(self) -> Option<(&'attr Symbol, span::Span)> { self.attrs().find_map(|attr| attr.string_value_with_span()) } + #[inline] pub fn string_value_unescape(self) -> Option> { self.attrs().find_map(|attr| attr.string_value_unescape()) } + #[inline] pub fn exists(self) -> bool { self.attrs().next().is_some() } + #[inline] pub fn attrs(self) -> impl Iterator + Clone { let key = self.key; - self.attrs.iter().filter(move |attr| attr.path.as_ident().is_some_and(|s| *s == *key)) + self.attrs.iter().filter(move |attr| attr.path.as_ident().is_some_and(|s| *s == key)) } /// Find string value for a specific key inside token tree @@ -585,10 +742,11 @@ impl<'attr> AttrQuery<'attr> { /// #[doc(html_root_url = "url")] /// ^^^^^^^^^^^^^ key /// ``` - pub fn find_string_value_in_tt(self, key: &'attr Symbol) -> Option<&'attr str> { + #[inline] + pub fn find_string_value_in_tt(self, key: Symbol) -> Option<&'attr str> { self.tt_values().find_map(|tt| { let name = tt.iter() - .skip_while(|tt| !matches!(tt, TtElement::Leaf(tt::Leaf::Ident(tt::Ident { sym, ..} )) if *sym == *key)) + .skip_while(|tt| !matches!(tt, TtElement::Leaf(tt::Leaf::Ident(tt::Ident { sym, ..} )) if *sym == key)) .nth(2); match name { @@ -601,17 +759,14 @@ impl<'attr> AttrQuery<'attr> { fn any_has_attrs<'db>( db: &(dyn DefDatabase + 'db), - id: impl Lookup< - Database<'db> = dyn DefDatabase + 'db, - Data = impl HasSource, - >, + id: impl Lookup>, ) -> InFile { id.lookup(db).source(db).map(ast::AnyHasAttrs::new) } fn attrs_from_item_tree_loc<'db, N: ItemTreeNode>( db: &(dyn DefDatabase + 'db), - lookup: impl Lookup = dyn DefDatabase + 'db, Data = impl ItemTreeLoc>, + lookup: impl Lookup>, ) -> RawAttrs { let id = lookup.lookup(db).item_tree_id(); let tree = id.item_tree(db); @@ -649,8 +804,8 @@ mod tests { use hir_expand::span_map::{RealSpanMap, SpanMap}; use span::FileId; - use syntax::{ast, AstNode, TextRange}; - use syntax_bridge::{syntax_node_to_token_tree, DocCommentDesugarMode}; + use syntax::{AstNode, TextRange, ast}; + use syntax_bridge::{DocCommentDesugarMode, syntax_node_to_token_tree}; use crate::attr::{DocAtom, DocExpr}; diff --git a/src/tools/rust-analyzer/crates/hir-def/src/builtin_type.rs b/src/tools/rust-analyzer/crates/hir-def/src/builtin_type.rs index 14b9af84e6ffb..8b61c6a9f0349 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/builtin_type.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/builtin_type.rs @@ -6,7 +6,7 @@ use std::fmt; use hir_expand::name::{AsName, Name}; -use intern::{sym, Symbol}; +use intern::{Symbol, sym}; /// Different signed int types. #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] pub enum BuiltinInt { @@ -51,28 +51,28 @@ impl BuiltinType { #[rustfmt::skip] pub fn all_builtin_types() -> [(Name, BuiltinType); 19] { [ - (Name::new_symbol_root(sym::char.clone()), BuiltinType::Char), - (Name::new_symbol_root(sym::bool.clone()), BuiltinType::Bool), - (Name::new_symbol_root(sym::str.clone()), BuiltinType::Str), - - (Name::new_symbol_root(sym::isize.clone()), BuiltinType::Int(BuiltinInt::Isize)), - (Name::new_symbol_root(sym::i8.clone()), BuiltinType::Int(BuiltinInt::I8)), - (Name::new_symbol_root(sym::i16.clone()), BuiltinType::Int(BuiltinInt::I16)), - (Name::new_symbol_root(sym::i32.clone()), BuiltinType::Int(BuiltinInt::I32)), - (Name::new_symbol_root(sym::i64.clone()), BuiltinType::Int(BuiltinInt::I64)), - (Name::new_symbol_root(sym::i128.clone()), BuiltinType::Int(BuiltinInt::I128)), - - (Name::new_symbol_root(sym::usize.clone()), BuiltinType::Uint(BuiltinUint::Usize)), - (Name::new_symbol_root(sym::u8.clone()), BuiltinType::Uint(BuiltinUint::U8)), - (Name::new_symbol_root(sym::u16.clone()), BuiltinType::Uint(BuiltinUint::U16)), - (Name::new_symbol_root(sym::u32.clone()), BuiltinType::Uint(BuiltinUint::U32)), - (Name::new_symbol_root(sym::u64.clone()), BuiltinType::Uint(BuiltinUint::U64)), - (Name::new_symbol_root(sym::u128.clone()), BuiltinType::Uint(BuiltinUint::U128)), - - (Name::new_symbol_root(sym::f16.clone()), BuiltinType::Float(BuiltinFloat::F16)), - (Name::new_symbol_root(sym::f32.clone()), BuiltinType::Float(BuiltinFloat::F32)), - (Name::new_symbol_root(sym::f64.clone()), BuiltinType::Float(BuiltinFloat::F64)), - (Name::new_symbol_root(sym::f128.clone()), BuiltinType::Float(BuiltinFloat::F128)), + (Name::new_symbol_root(sym::char), BuiltinType::Char), + (Name::new_symbol_root(sym::bool), BuiltinType::Bool), + (Name::new_symbol_root(sym::str), BuiltinType::Str), + + (Name::new_symbol_root(sym::isize), BuiltinType::Int(BuiltinInt::Isize)), + (Name::new_symbol_root(sym::i8), BuiltinType::Int(BuiltinInt::I8)), + (Name::new_symbol_root(sym::i16), BuiltinType::Int(BuiltinInt::I16)), + (Name::new_symbol_root(sym::i32), BuiltinType::Int(BuiltinInt::I32)), + (Name::new_symbol_root(sym::i64), BuiltinType::Int(BuiltinInt::I64)), + (Name::new_symbol_root(sym::i128), BuiltinType::Int(BuiltinInt::I128)), + + (Name::new_symbol_root(sym::usize), BuiltinType::Uint(BuiltinUint::Usize)), + (Name::new_symbol_root(sym::u8), BuiltinType::Uint(BuiltinUint::U8)), + (Name::new_symbol_root(sym::u16), BuiltinType::Uint(BuiltinUint::U16)), + (Name::new_symbol_root(sym::u32), BuiltinType::Uint(BuiltinUint::U32)), + (Name::new_symbol_root(sym::u64), BuiltinType::Uint(BuiltinUint::U64)), + (Name::new_symbol_root(sym::u128), BuiltinType::Uint(BuiltinUint::U128)), + + (Name::new_symbol_root(sym::f16), BuiltinType::Float(BuiltinFloat::F16)), + (Name::new_symbol_root(sym::f32), BuiltinType::Float(BuiltinFloat::F32)), + (Name::new_symbol_root(sym::f64), BuiltinType::Float(BuiltinFloat::F64)), + (Name::new_symbol_root(sym::f128), BuiltinType::Float(BuiltinFloat::F128)), ] } @@ -86,30 +86,30 @@ impl BuiltinType { impl AsName for BuiltinType { fn as_name(&self) -> Name { match self { - BuiltinType::Char => Name::new_symbol_root(sym::char.clone()), - BuiltinType::Bool => Name::new_symbol_root(sym::bool.clone()), - BuiltinType::Str => Name::new_symbol_root(sym::str.clone()), + BuiltinType::Char => Name::new_symbol_root(sym::char), + BuiltinType::Bool => Name::new_symbol_root(sym::bool), + BuiltinType::Str => Name::new_symbol_root(sym::str), BuiltinType::Int(it) => match it { - BuiltinInt::Isize => Name::new_symbol_root(sym::isize.clone()), - BuiltinInt::I8 => Name::new_symbol_root(sym::i8.clone()), - BuiltinInt::I16 => Name::new_symbol_root(sym::i16.clone()), - BuiltinInt::I32 => Name::new_symbol_root(sym::i32.clone()), - BuiltinInt::I64 => Name::new_symbol_root(sym::i64.clone()), - BuiltinInt::I128 => Name::new_symbol_root(sym::i128.clone()), + BuiltinInt::Isize => Name::new_symbol_root(sym::isize), + BuiltinInt::I8 => Name::new_symbol_root(sym::i8), + BuiltinInt::I16 => Name::new_symbol_root(sym::i16), + BuiltinInt::I32 => Name::new_symbol_root(sym::i32), + BuiltinInt::I64 => Name::new_symbol_root(sym::i64), + BuiltinInt::I128 => Name::new_symbol_root(sym::i128), }, BuiltinType::Uint(it) => match it { - BuiltinUint::Usize => Name::new_symbol_root(sym::usize.clone()), - BuiltinUint::U8 => Name::new_symbol_root(sym::u8.clone()), - BuiltinUint::U16 => Name::new_symbol_root(sym::u16.clone()), - BuiltinUint::U32 => Name::new_symbol_root(sym::u32.clone()), - BuiltinUint::U64 => Name::new_symbol_root(sym::u64.clone()), - BuiltinUint::U128 => Name::new_symbol_root(sym::u128.clone()), + BuiltinUint::Usize => Name::new_symbol_root(sym::usize), + BuiltinUint::U8 => Name::new_symbol_root(sym::u8), + BuiltinUint::U16 => Name::new_symbol_root(sym::u16), + BuiltinUint::U32 => Name::new_symbol_root(sym::u32), + BuiltinUint::U64 => Name::new_symbol_root(sym::u64), + BuiltinUint::U128 => Name::new_symbol_root(sym::u128), }, BuiltinType::Float(it) => match it { - BuiltinFloat::F16 => Name::new_symbol_root(sym::f16.clone()), - BuiltinFloat::F32 => Name::new_symbol_root(sym::f32.clone()), - BuiltinFloat::F64 => Name::new_symbol_root(sym::f64.clone()), - BuiltinFloat::F128 => Name::new_symbol_root(sym::f128.clone()), + BuiltinFloat::F16 => Name::new_symbol_root(sym::f16), + BuiltinFloat::F32 => Name::new_symbol_root(sym::f32), + BuiltinFloat::F64 => Name::new_symbol_root(sym::f64), + BuiltinFloat::F128 => Name::new_symbol_root(sym::f128), }, } } diff --git a/src/tools/rust-analyzer/crates/hir-def/src/data.rs b/src/tools/rust-analyzer/crates/hir-def/src/data.rs deleted file mode 100644 index bec662787728c..0000000000000 --- a/src/tools/rust-analyzer/crates/hir-def/src/data.rs +++ /dev/null @@ -1,843 +0,0 @@ -//! Contains basic data about various HIR declarations. - -pub mod adt; - -use base_db::CrateId; -use hir_expand::{ - name::Name, AstId, ExpandResult, HirFileId, InFile, MacroCallId, MacroCallKind, MacroDefKind, -}; -use intern::{sym, Symbol}; -use la_arena::{Idx, RawIdx}; -use smallvec::SmallVec; -use syntax::{ast, Parse}; -use triomphe::Arc; -use tt::iter::TtElement; - -use crate::{ - db::DefDatabase, - expander::{Expander, Mark}, - item_tree::{self, AssocItem, FnFlags, ItemTree, ItemTreeId, MacroCall, ModItem, TreeId}, - macro_call_as_call_id, - nameres::{ - attr_resolution::ResolvedAttr, - diagnostics::{DefDiagnostic, DefDiagnostics}, - proc_macro::{parse_macro_name_and_helper_attrs, ProcMacroKind}, - DefMap, MacroSubNs, - }, - path::ImportAlias, - type_ref::{TraitRef, TypeBound, TypeRefId, TypesMap}, - visibility::RawVisibility, - AssocItemId, AstIdWithPath, ConstId, ConstLoc, ExternCrateId, FunctionId, FunctionLoc, - HasModule, ImplId, Intern, ItemContainerId, ItemLoc, Lookup, Macro2Id, MacroRulesId, ModuleId, - ProcMacroId, StaticId, TraitAliasId, TraitId, TypeAliasId, TypeAliasLoc, -}; - -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct FunctionData { - pub name: Name, - pub params: Box<[TypeRefId]>, - pub ret_type: TypeRefId, - pub visibility: RawVisibility, - pub abi: Option, - pub legacy_const_generics_indices: Option>>, - pub rustc_allow_incoherent_impl: bool, - pub types_map: Arc, - flags: FnFlags, -} - -impl FunctionData { - pub(crate) fn fn_data_query(db: &dyn DefDatabase, func: FunctionId) -> Arc { - let loc = func.lookup(db); - let krate = loc.container.module(db).krate; - let item_tree = loc.id.item_tree(db); - let func = &item_tree[loc.id.value]; - let visibility = if let ItemContainerId::TraitId(trait_id) = loc.container { - trait_vis(db, trait_id) - } else { - item_tree[func.visibility].clone() - }; - - let crate_graph = db.crate_graph(); - let cfg_options = &crate_graph[krate].cfg_options; - let attr_owner = |idx| { - item_tree::AttrOwner::Param(loc.id.value, Idx::from_raw(RawIdx::from(idx as u32))) - }; - - let mut flags = func.flags; - if flags.contains(FnFlags::HAS_SELF_PARAM) { - // If there's a self param in the syntax, but it is cfg'd out, remove the flag. - let is_cfgd_out = - !item_tree.attrs(db, krate, attr_owner(0usize)).is_cfg_enabled(cfg_options); - if is_cfgd_out { - cov_mark::hit!(cfgd_out_self_param); - flags.remove(FnFlags::HAS_SELF_PARAM); - } - } - if flags.contains(FnFlags::IS_VARARGS) { - if let Some((_, param)) = func.params.iter().enumerate().rev().find(|&(idx, _)| { - item_tree.attrs(db, krate, attr_owner(idx)).is_cfg_enabled(cfg_options) - }) { - if param.type_ref.is_some() { - flags.remove(FnFlags::IS_VARARGS); - } - } else { - flags.remove(FnFlags::IS_VARARGS); - } - } - - let attrs = item_tree.attrs(db, krate, ModItem::from(loc.id.value).into()); - let legacy_const_generics_indices = attrs - .by_key(&sym::rustc_legacy_const_generics) - .tt_values() - .next() - .map(parse_rustc_legacy_const_generics) - .filter(|it| !it.is_empty()) - .map(Box::new); - let rustc_allow_incoherent_impl = attrs.by_key(&sym::rustc_allow_incoherent_impl).exists(); - if flags.contains(FnFlags::HAS_UNSAFE_KW) - && attrs.by_key(&sym::rustc_deprecated_safe_2024).exists() - { - flags.remove(FnFlags::HAS_UNSAFE_KW); - flags.insert(FnFlags::DEPRECATED_SAFE_2024); - } - - if attrs.by_key(&sym::target_feature).exists() { - flags.insert(FnFlags::HAS_TARGET_FEATURE); - } - - Arc::new(FunctionData { - name: func.name.clone(), - params: func - .params - .iter() - .enumerate() - .filter(|&(idx, _)| { - item_tree.attrs(db, krate, attr_owner(idx)).is_cfg_enabled(cfg_options) - }) - .filter_map(|(_, param)| param.type_ref) - .collect(), - ret_type: func.ret_type, - visibility, - abi: func.abi.clone(), - legacy_const_generics_indices, - types_map: func.types_map.clone(), - flags, - rustc_allow_incoherent_impl, - }) - } - - pub fn has_body(&self) -> bool { - self.flags.contains(FnFlags::HAS_BODY) - } - - /// True if the first param is `self`. This is relevant to decide whether this - /// can be called as a method. - pub fn has_self_param(&self) -> bool { - self.flags.contains(FnFlags::HAS_SELF_PARAM) - } - - pub fn is_default(&self) -> bool { - self.flags.contains(FnFlags::HAS_DEFAULT_KW) - } - - pub fn is_const(&self) -> bool { - self.flags.contains(FnFlags::HAS_CONST_KW) - } - - pub fn is_async(&self) -> bool { - self.flags.contains(FnFlags::HAS_ASYNC_KW) - } - - pub fn is_unsafe(&self) -> bool { - self.flags.contains(FnFlags::HAS_UNSAFE_KW) - } - - pub fn is_deprecated_safe_2024(&self) -> bool { - self.flags.contains(FnFlags::DEPRECATED_SAFE_2024) - } - - pub fn is_safe(&self) -> bool { - self.flags.contains(FnFlags::HAS_SAFE_KW) - } - - pub fn is_varargs(&self) -> bool { - self.flags.contains(FnFlags::IS_VARARGS) - } - - pub fn has_target_feature(&self) -> bool { - self.flags.contains(FnFlags::HAS_TARGET_FEATURE) - } -} - -fn parse_rustc_legacy_const_generics(tt: &crate::tt::TopSubtree) -> Box<[u32]> { - let mut indices = Vec::new(); - let mut iter = tt.iter(); - while let (Some(first), second) = (iter.next(), iter.next()) { - match first { - TtElement::Leaf(tt::Leaf::Literal(lit)) => match lit.symbol.as_str().parse() { - Ok(index) => indices.push(index), - Err(_) => break, - }, - _ => break, - } - - if let Some(comma) = second { - match comma { - TtElement::Leaf(tt::Leaf::Punct(punct)) if punct.char == ',' => {} - _ => break, - } - } - } - - indices.into_boxed_slice() -} - -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct TypeAliasData { - pub name: Name, - pub type_ref: Option, - pub visibility: RawVisibility, - pub is_extern: bool, - pub rustc_has_incoherent_inherent_impls: bool, - pub rustc_allow_incoherent_impl: bool, - /// Bounds restricting the type alias itself (eg. `type Ty: Bound;` in a trait or impl). - pub bounds: Box<[TypeBound]>, - pub types_map: Arc, -} - -impl TypeAliasData { - pub(crate) fn type_alias_data_query( - db: &dyn DefDatabase, - typ: TypeAliasId, - ) -> Arc { - let loc = typ.lookup(db); - let item_tree = loc.id.item_tree(db); - let typ = &item_tree[loc.id.value]; - let visibility = if let ItemContainerId::TraitId(trait_id) = loc.container { - trait_vis(db, trait_id) - } else { - item_tree[typ.visibility].clone() - }; - - let attrs = item_tree.attrs( - db, - loc.container.module(db).krate(), - ModItem::from(loc.id.value).into(), - ); - let rustc_has_incoherent_inherent_impls = - attrs.by_key(&sym::rustc_has_incoherent_inherent_impls).exists(); - let rustc_allow_incoherent_impl = attrs.by_key(&sym::rustc_allow_incoherent_impl).exists(); - - Arc::new(TypeAliasData { - name: typ.name.clone(), - type_ref: typ.type_ref, - visibility, - is_extern: matches!(loc.container, ItemContainerId::ExternBlockId(_)), - rustc_has_incoherent_inherent_impls, - rustc_allow_incoherent_impl, - bounds: typ.bounds.clone(), - types_map: typ.types_map.clone(), - }) - } -} - -bitflags::bitflags! { - #[derive(Debug, Clone, Copy, Eq, PartialEq, Default)] - pub struct TraitFlags: u8 { - const IS_AUTO = 1 << 0; - const IS_UNSAFE = 1 << 1; - const IS_FUNDAMENTAL = 1 << 2; - const RUSTC_HAS_INCOHERENT_INHERENT_IMPLS = 1 << 3; - const SKIP_ARRAY_DURING_METHOD_DISPATCH = 1 << 4; - const SKIP_BOXED_SLICE_DURING_METHOD_DISPATCH = 1 << 5; - const RUSTC_PAREN_SUGAR = 1 << 6; - } -} - -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct TraitData { - pub name: Name, - pub items: Box<[(Name, AssocItemId)]>, - pub flags: TraitFlags, - pub visibility: RawVisibility, - // box it as the vec is usually empty anyways - pub macro_calls: Option, MacroCallId)>>>, -} - -impl TraitData { - #[inline] - pub(crate) fn trait_data_query(db: &dyn DefDatabase, tr: TraitId) -> Arc { - db.trait_data_with_diagnostics(tr).0 - } - - pub(crate) fn trait_data_with_diagnostics_query( - db: &dyn DefDatabase, - tr: TraitId, - ) -> (Arc, DefDiagnostics) { - let ItemLoc { container: module_id, id: tree_id } = tr.lookup(db); - let item_tree = tree_id.item_tree(db); - let tr_def = &item_tree[tree_id.value]; - let name = tr_def.name.clone(); - let visibility = item_tree[tr_def.visibility].clone(); - let attrs = item_tree.attrs(db, module_id.krate(), ModItem::from(tree_id.value).into()); - - let mut flags = TraitFlags::empty(); - - if tr_def.is_auto { - flags |= TraitFlags::IS_AUTO; - } - if tr_def.is_unsafe { - flags |= TraitFlags::IS_UNSAFE; - } - if attrs.by_key(&sym::fundamental).exists() { - flags |= TraitFlags::IS_FUNDAMENTAL; - } - if attrs.by_key(&sym::rustc_has_incoherent_inherent_impls).exists() { - flags |= TraitFlags::RUSTC_HAS_INCOHERENT_INHERENT_IMPLS; - } - if attrs.by_key(&sym::rustc_paren_sugar).exists() { - flags |= TraitFlags::RUSTC_PAREN_SUGAR; - } - - let mut skip_array_during_method_dispatch = - attrs.by_key(&sym::rustc_skip_array_during_method_dispatch).exists(); - let mut skip_boxed_slice_during_method_dispatch = false; - for tt in attrs.by_key(&sym::rustc_skip_during_method_dispatch).tt_values() { - for tt in tt.iter() { - if let tt::iter::TtElement::Leaf(tt::Leaf::Ident(ident)) = tt { - skip_array_during_method_dispatch |= ident.sym == sym::array; - skip_boxed_slice_during_method_dispatch |= ident.sym == sym::boxed_slice; - } - } - } - - if skip_array_during_method_dispatch { - flags |= TraitFlags::SKIP_ARRAY_DURING_METHOD_DISPATCH; - } - if skip_boxed_slice_during_method_dispatch { - flags |= TraitFlags::SKIP_BOXED_SLICE_DURING_METHOD_DISPATCH; - } - - let mut collector = - AssocItemCollector::new(db, module_id, tree_id.file_id(), ItemContainerId::TraitId(tr)); - collector.collect(&item_tree, tree_id.tree_id(), &tr_def.items); - let (items, macro_calls, diagnostics) = collector.finish(); - - ( - Arc::new(TraitData { name, macro_calls, items, visibility, flags }), - DefDiagnostics::new(diagnostics), - ) - } - - pub fn associated_types(&self) -> impl Iterator + '_ { - self.items.iter().filter_map(|(_name, item)| match item { - AssocItemId::TypeAliasId(t) => Some(*t), - _ => None, - }) - } - - pub fn associated_type_by_name(&self, name: &Name) -> Option { - self.items.iter().find_map(|(item_name, item)| match item { - AssocItemId::TypeAliasId(t) if item_name == name => Some(*t), - _ => None, - }) - } - - pub fn method_by_name(&self, name: &Name) -> Option { - self.items.iter().find_map(|(item_name, item)| match item { - AssocItemId::FunctionId(t) if item_name == name => Some(*t), - _ => None, - }) - } - - pub fn attribute_calls(&self) -> impl Iterator, MacroCallId)> + '_ { - self.macro_calls.iter().flat_map(|it| it.iter()).copied() - } -} - -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct TraitAliasData { - pub name: Name, - pub visibility: RawVisibility, -} - -impl TraitAliasData { - pub(crate) fn trait_alias_query(db: &dyn DefDatabase, id: TraitAliasId) -> Arc { - let loc = id.lookup(db); - let item_tree = loc.id.item_tree(db); - let alias = &item_tree[loc.id.value]; - let visibility = item_tree[alias.visibility].clone(); - - Arc::new(TraitAliasData { name: alias.name.clone(), visibility }) - } -} - -#[derive(Debug, PartialEq, Eq)] -pub struct ImplData { - pub target_trait: Option, - pub self_ty: TypeRefId, - pub items: Box<[(Name, AssocItemId)]>, - pub is_negative: bool, - pub is_unsafe: bool, - // box it as the vec is usually empty anyways - pub macro_calls: Option, MacroCallId)>>>, - pub types_map: Arc, -} - -impl ImplData { - #[inline] - pub(crate) fn impl_data_query(db: &dyn DefDatabase, id: ImplId) -> Arc { - db.impl_data_with_diagnostics(id).0 - } - - pub(crate) fn impl_data_with_diagnostics_query( - db: &dyn DefDatabase, - id: ImplId, - ) -> (Arc, DefDiagnostics) { - let _p = tracing::info_span!("impl_data_with_diagnostics_query").entered(); - let ItemLoc { container: module_id, id: tree_id } = id.lookup(db); - - let item_tree = tree_id.item_tree(db); - let impl_def = &item_tree[tree_id.value]; - let target_trait = impl_def.target_trait; - let self_ty = impl_def.self_ty; - let is_negative = impl_def.is_negative; - let is_unsafe = impl_def.is_unsafe; - - let mut collector = - AssocItemCollector::new(db, module_id, tree_id.file_id(), ItemContainerId::ImplId(id)); - collector.collect(&item_tree, tree_id.tree_id(), &impl_def.items); - - let (items, macro_calls, diagnostics) = collector.finish(); - - ( - Arc::new(ImplData { - target_trait, - self_ty, - items, - is_negative, - is_unsafe, - macro_calls, - types_map: impl_def.types_map.clone(), - }), - DefDiagnostics::new(diagnostics), - ) - } - - pub fn attribute_calls(&self) -> impl Iterator, MacroCallId)> + '_ { - self.macro_calls.iter().flat_map(|it| it.iter()).copied() - } -} - -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct Macro2Data { - pub name: Name, - pub visibility: RawVisibility, - // It's a bit wasteful as currently this is only for builtin `Default` derive macro, but macro2 - // are rarely used in practice so I think it's okay for now. - /// Derive helpers, if this is a derive rustc_builtin_macro - pub helpers: Option>, -} - -impl Macro2Data { - pub(crate) fn macro2_data_query(db: &dyn DefDatabase, makro: Macro2Id) -> Arc { - let loc = makro.lookup(db); - let item_tree = loc.id.item_tree(db); - let makro = &item_tree[loc.id.value]; - - let helpers = item_tree - .attrs(db, loc.container.krate(), ModItem::from(loc.id.value).into()) - .by_key(&sym::rustc_builtin_macro) - .tt_values() - .next() - .and_then(parse_macro_name_and_helper_attrs) - .map(|(_, helpers)| helpers); - - Arc::new(Macro2Data { - name: makro.name.clone(), - visibility: item_tree[makro.visibility].clone(), - helpers, - }) - } -} -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct MacroRulesData { - pub name: Name, - pub macro_export: bool, -} - -impl MacroRulesData { - pub(crate) fn macro_rules_data_query( - db: &dyn DefDatabase, - makro: MacroRulesId, - ) -> Arc { - let loc = makro.lookup(db); - let item_tree = loc.id.item_tree(db); - let makro = &item_tree[loc.id.value]; - - let macro_export = item_tree - .attrs(db, loc.container.krate(), ModItem::from(loc.id.value).into()) - .by_key(&sym::macro_export) - .exists(); - - Arc::new(MacroRulesData { name: makro.name.clone(), macro_export }) - } -} - -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct ProcMacroData { - pub name: Name, - /// Derive helpers, if this is a derive - pub helpers: Option>, -} - -impl ProcMacroData { - pub(crate) fn proc_macro_data_query( - db: &dyn DefDatabase, - makro: ProcMacroId, - ) -> Arc { - let loc = makro.lookup(db); - let item_tree = loc.id.item_tree(db); - let makro = &item_tree[loc.id.value]; - - let (name, helpers) = if let Some(def) = item_tree - .attrs(db, loc.container.krate(), ModItem::from(loc.id.value).into()) - .parse_proc_macro_decl(&makro.name) - { - ( - def.name, - match def.kind { - ProcMacroKind::Derive { helpers } => Some(helpers), - ProcMacroKind::Bang | ProcMacroKind::Attr => None, - }, - ) - } else { - // eeeh... - stdx::never!("proc macro declaration is not a proc macro"); - (makro.name.clone(), None) - }; - Arc::new(ProcMacroData { name, helpers }) - } -} - -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct ExternCrateDeclData { - pub name: Name, - pub alias: Option, - pub visibility: RawVisibility, - pub crate_id: Option, -} - -impl ExternCrateDeclData { - pub(crate) fn extern_crate_decl_data_query( - db: &dyn DefDatabase, - extern_crate: ExternCrateId, - ) -> Arc { - let loc = extern_crate.lookup(db); - let item_tree = loc.id.item_tree(db); - let extern_crate = &item_tree[loc.id.value]; - - let name = extern_crate.name.clone(); - let krate = loc.container.krate(); - let crate_id = if name == sym::self_.clone() { - Some(krate) - } else { - db.crate_graph()[krate].dependencies.iter().find_map(|dep| { - if dep.name.symbol() == name.symbol() { - Some(dep.crate_id) - } else { - None - } - }) - }; - - Arc::new(Self { - name, - visibility: item_tree[extern_crate.visibility].clone(), - alias: extern_crate.alias.clone(), - crate_id, - }) - } -} - -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct ConstData { - /// `None` for `const _: () = ();` - pub name: Option, - pub type_ref: TypeRefId, - pub visibility: RawVisibility, - pub rustc_allow_incoherent_impl: bool, - pub has_body: bool, - pub types_map: Arc, -} - -impl ConstData { - pub(crate) fn const_data_query(db: &dyn DefDatabase, konst: ConstId) -> Arc { - let loc = konst.lookup(db); - let item_tree = loc.id.item_tree(db); - let konst = &item_tree[loc.id.value]; - let visibility = if let ItemContainerId::TraitId(trait_id) = loc.container { - trait_vis(db, trait_id) - } else { - item_tree[konst.visibility].clone() - }; - - let rustc_allow_incoherent_impl = item_tree - .attrs(db, loc.container.module(db).krate(), ModItem::from(loc.id.value).into()) - .by_key(&sym::rustc_allow_incoherent_impl) - .exists(); - - Arc::new(ConstData { - name: konst.name.clone(), - type_ref: konst.type_ref, - visibility, - rustc_allow_incoherent_impl, - has_body: konst.has_body, - types_map: konst.types_map.clone(), - }) - } -} - -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct StaticData { - pub name: Name, - pub type_ref: TypeRefId, - pub visibility: RawVisibility, - pub mutable: bool, - pub is_extern: bool, - pub has_safe_kw: bool, - pub has_unsafe_kw: bool, - pub types_map: Arc, -} - -impl StaticData { - pub(crate) fn static_data_query(db: &dyn DefDatabase, konst: StaticId) -> Arc { - let loc = konst.lookup(db); - let item_tree = loc.id.item_tree(db); - let statik = &item_tree[loc.id.value]; - - Arc::new(StaticData { - name: statik.name.clone(), - type_ref: statik.type_ref, - visibility: item_tree[statik.visibility].clone(), - mutable: statik.mutable, - is_extern: matches!(loc.container, ItemContainerId::ExternBlockId(_)), - has_safe_kw: statik.has_safe_kw, - has_unsafe_kw: statik.has_unsafe_kw, - types_map: statik.types_map.clone(), - }) - } -} - -struct AssocItemCollector<'a> { - db: &'a dyn DefDatabase, - module_id: ModuleId, - def_map: Arc, - diagnostics: Vec, - container: ItemContainerId, - expander: Expander, - - items: Vec<(Name, AssocItemId)>, - macro_calls: Vec<(AstId, MacroCallId)>, -} - -impl<'a> AssocItemCollector<'a> { - fn new( - db: &'a dyn DefDatabase, - module_id: ModuleId, - file_id: HirFileId, - container: ItemContainerId, - ) -> Self { - Self { - db, - module_id, - def_map: module_id.def_map(db), - container, - expander: Expander::new(db, file_id, module_id), - items: Vec::new(), - macro_calls: Vec::new(), - diagnostics: Vec::new(), - } - } - - fn finish( - self, - ) -> ( - Box<[(Name, AssocItemId)]>, - Option, MacroCallId)>>>, - Vec, - ) { - ( - self.items.into_boxed_slice(), - if self.macro_calls.is_empty() { None } else { Some(Box::new(self.macro_calls)) }, - self.diagnostics, - ) - } - - fn collect(&mut self, item_tree: &ItemTree, tree_id: TreeId, assoc_items: &[AssocItem]) { - let container = self.container; - self.items.reserve(assoc_items.len()); - - 'items: for &item in assoc_items { - let attrs = item_tree.attrs(self.db, self.module_id.krate, ModItem::from(item).into()); - if !attrs.is_cfg_enabled(self.expander.cfg_options()) { - self.diagnostics.push(DefDiagnostic::unconfigured_code( - self.module_id.local_id, - tree_id, - ModItem::from(item).into(), - attrs.cfg().unwrap(), - self.expander.cfg_options().clone(), - )); - continue; - } - - 'attrs: for attr in &*attrs { - let ast_id = - AstId::new(self.expander.current_file_id(), item.ast_id(item_tree).upcast()); - let ast_id_with_path = AstIdWithPath { path: attr.path.clone(), ast_id }; - - match self.def_map.resolve_attr_macro( - self.db, - self.module_id.local_id, - ast_id_with_path, - attr, - ) { - Ok(ResolvedAttr::Macro(call_id)) => { - let loc = self.db.lookup_intern_macro_call(call_id); - if let MacroDefKind::ProcMacro(_, exp, _) = loc.def.kind { - // If there's no expander for the proc macro (e.g. the - // proc macro is ignored, or building the proc macro - // crate failed), skip expansion like we would if it was - // disabled. This is analogous to the handling in - // `DefCollector::collect_macros`. - if let Some(err) = exp.as_expand_error(self.module_id.krate) { - self.diagnostics.push(DefDiagnostic::macro_error( - self.module_id.local_id, - ast_id, - (*attr.path).clone(), - err, - )); - continue 'attrs; - } - } - - self.macro_calls.push((ast_id, call_id)); - let res = - self.expander.enter_expand_id::(self.db, call_id); - self.collect_macro_items(res); - continue 'items; - } - Ok(_) => (), - Err(_) => { - self.diagnostics.push(DefDiagnostic::unresolved_macro_call( - self.module_id.local_id, - MacroCallKind::Attr { - ast_id, - attr_args: None, - invoc_attr_index: attr.id, - }, - attr.path().clone(), - )); - } - } - } - - self.collect_item(item_tree, tree_id, container, item); - } - } - - fn collect_item( - &mut self, - item_tree: &ItemTree, - tree_id: TreeId, - container: ItemContainerId, - item: AssocItem, - ) { - match item { - AssocItem::Function(id) => { - let item = &item_tree[id]; - let def = - FunctionLoc { container, id: ItemTreeId::new(tree_id, id) }.intern(self.db); - self.items.push((item.name.clone(), def.into())); - } - AssocItem::TypeAlias(id) => { - let item = &item_tree[id]; - let def = - TypeAliasLoc { container, id: ItemTreeId::new(tree_id, id) }.intern(self.db); - self.items.push((item.name.clone(), def.into())); - } - AssocItem::Const(id) => { - let item = &item_tree[id]; - let Some(name) = item.name.clone() else { return }; - let def = ConstLoc { container, id: ItemTreeId::new(tree_id, id) }.intern(self.db); - self.items.push((name, def.into())); - } - AssocItem::MacroCall(call) => { - let file_id = self.expander.current_file_id(); - let MacroCall { ast_id, expand_to, ctxt, ref path } = item_tree[call]; - let module = self.expander.module.local_id; - - let resolver = |path: &_| { - self.def_map - .resolve_path( - self.db, - module, - path, - crate::item_scope::BuiltinShadowMode::Other, - Some(MacroSubNs::Bang), - ) - .0 - .take_macros() - .map(|it| self.db.macro_def(it)) - }; - match macro_call_as_call_id( - self.db.upcast(), - &AstIdWithPath::new(file_id, ast_id, Clone::clone(path)), - ctxt, - expand_to, - self.expander.krate(), - resolver, - ) { - Ok(Some(call_id)) => { - let res = - self.expander.enter_expand_id::(self.db, call_id); - self.macro_calls.push((InFile::new(file_id, ast_id.upcast()), call_id)); - self.collect_macro_items(res); - } - Ok(None) => (), - Err(_) => { - self.diagnostics.push(DefDiagnostic::unresolved_macro_call( - self.module_id.local_id, - MacroCallKind::FnLike { - ast_id: InFile::new(file_id, ast_id), - expand_to, - eager: None, - }, - Clone::clone(path), - )); - } - } - } - } - } - - fn collect_macro_items(&mut self, res: ExpandResult)>>) { - let Some((mark, _parse)) = res.value else { return }; - - let tree_id = item_tree::TreeId::new(self.expander.current_file_id(), None); - let item_tree = tree_id.item_tree(self.db); - let iter: SmallVec<[_; 2]> = - item_tree.top_level_items().iter().filter_map(ModItem::as_assoc_item).collect(); - - self.collect(&item_tree, tree_id, &iter); - - self.expander.exit(mark); - } -} - -fn trait_vis(db: &dyn DefDatabase, trait_id: TraitId) -> RawVisibility { - let ItemLoc { id: tree_id, .. } = trait_id.lookup(db); - let item_tree = tree_id.item_tree(db); - let tr_def = &item_tree[tree_id.value]; - item_tree[tr_def.visibility].clone() -} diff --git a/src/tools/rust-analyzer/crates/hir-def/src/data/adt.rs b/src/tools/rust-analyzer/crates/hir-def/src/data/adt.rs deleted file mode 100644 index c94622016d355..0000000000000 --- a/src/tools/rust-analyzer/crates/hir-def/src/data/adt.rs +++ /dev/null @@ -1,489 +0,0 @@ -//! Defines hir-level representation of structs, enums and unions - -use base_db::CrateId; -use bitflags::bitflags; -use cfg::CfgOptions; -use either::Either; - -use hir_expand::name::Name; -use intern::sym; -use la_arena::Arena; -use rustc_abi::{Align, Integer, IntegerType, ReprFlags, ReprOptions}; -use rustc_hashes::Hash64; -use triomphe::Arc; -use tt::iter::TtElement; - -use crate::{ - builtin_type::{BuiltinInt, BuiltinUint}, - db::DefDatabase, - hir::Expr, - item_tree::{ - AttrOwner, Field, FieldParent, FieldsShape, ItemTree, ModItem, RawVisibilityId, TreeId, - }, - lang_item::LangItem, - nameres::diagnostics::{DefDiagnostic, DefDiagnostics}, - tt::{Delimiter, DelimiterKind, Leaf, TopSubtree}, - type_ref::{TypeRefId, TypesMap}, - visibility::RawVisibility, - EnumId, EnumVariantId, LocalFieldId, LocalModuleId, Lookup, StructId, UnionId, VariantId, -}; - -/// Note that we use `StructData` for unions as well! -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct StructData { - pub name: Name, - pub variant_data: Arc, - pub repr: Option, - pub visibility: RawVisibility, - pub flags: StructFlags, -} - -bitflags! { - #[derive(Debug, Copy, Clone, PartialEq, Eq)] - pub struct StructFlags: u8 { - const NO_FLAGS = 0; - /// Indicates whether the struct is `PhantomData`. - const IS_PHANTOM_DATA = 1 << 2; - /// Indicates whether the struct has a `#[fundamental]` attribute. - const IS_FUNDAMENTAL = 1 << 3; - // FIXME: should this be a flag? - /// Indicates whether the struct has a `#[rustc_has_incoherent_inherent_impls]` attribute. - const IS_RUSTC_HAS_INCOHERENT_INHERENT_IMPL = 1 << 4; - /// Indicates whether this struct is `Box`. - const IS_BOX = 1 << 5; - /// Indicates whether this struct is `ManuallyDrop`. - const IS_MANUALLY_DROP = 1 << 6; - /// Indicates whether this struct is `UnsafeCell`. - const IS_UNSAFE_CELL = 1 << 7; - } -} - -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct EnumData { - pub name: Name, - pub variants: Box<[(EnumVariantId, Name)]>, - pub repr: Option, - pub visibility: RawVisibility, - pub rustc_has_incoherent_inherent_impls: bool, -} - -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct EnumVariantData { - pub name: Name, - pub variant_data: Arc, -} - -#[derive(Debug, Clone, PartialEq, Eq)] -pub enum VariantData { - Record { fields: Arena, types_map: Arc }, - Tuple { fields: Arena, types_map: Arc }, - Unit, -} - -/// A single field of an enum variant or struct -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct FieldData { - pub name: Name, - pub type_ref: TypeRefId, - pub visibility: RawVisibility, -} - -fn repr_from_value( - db: &dyn DefDatabase, - krate: CrateId, - item_tree: &ItemTree, - of: AttrOwner, -) -> Option { - item_tree.attrs(db, krate, of).by_key(&sym::repr).tt_values().find_map(parse_repr_tt) -} - -fn parse_repr_tt(tt: &TopSubtree) -> Option { - match tt.top_subtree().delimiter { - Delimiter { kind: DelimiterKind::Parenthesis, .. } => {} - _ => return None, - } - - let mut flags = ReprFlags::empty(); - let mut int = None; - let mut max_align: Option = None; - let mut min_pack: Option = None; - - let mut tts = tt.iter(); - while let Some(tt) = tts.next() { - if let TtElement::Leaf(Leaf::Ident(ident)) = tt { - flags.insert(match &ident.sym { - s if *s == sym::packed => { - let pack = if let Some(TtElement::Subtree(_, mut tt_iter)) = tts.peek() { - tts.next(); - if let Some(TtElement::Leaf(Leaf::Literal(lit))) = tt_iter.next() { - lit.symbol.as_str().parse().unwrap_or_default() - } else { - 0 - } - } else { - 0 - }; - let pack = Align::from_bytes(pack).unwrap_or(Align::ONE); - min_pack = - Some(if let Some(min_pack) = min_pack { min_pack.min(pack) } else { pack }); - ReprFlags::empty() - } - s if *s == sym::align => { - if let Some(TtElement::Subtree(_, mut tt_iter)) = tts.peek() { - tts.next(); - if let Some(TtElement::Leaf(Leaf::Literal(lit))) = tt_iter.next() { - if let Ok(align) = lit.symbol.as_str().parse() { - let align = Align::from_bytes(align).ok(); - max_align = max_align.max(align); - } - } - } - ReprFlags::empty() - } - s if *s == sym::C => ReprFlags::IS_C, - s if *s == sym::transparent => ReprFlags::IS_TRANSPARENT, - s if *s == sym::simd => ReprFlags::IS_SIMD, - repr => { - if let Some(builtin) = BuiltinInt::from_suffix_sym(repr) - .map(Either::Left) - .or_else(|| BuiltinUint::from_suffix_sym(repr).map(Either::Right)) - { - int = Some(match builtin { - Either::Left(bi) => match bi { - BuiltinInt::Isize => IntegerType::Pointer(true), - BuiltinInt::I8 => IntegerType::Fixed(Integer::I8, true), - BuiltinInt::I16 => IntegerType::Fixed(Integer::I16, true), - BuiltinInt::I32 => IntegerType::Fixed(Integer::I32, true), - BuiltinInt::I64 => IntegerType::Fixed(Integer::I64, true), - BuiltinInt::I128 => IntegerType::Fixed(Integer::I128, true), - }, - Either::Right(bu) => match bu { - BuiltinUint::Usize => IntegerType::Pointer(false), - BuiltinUint::U8 => IntegerType::Fixed(Integer::I8, false), - BuiltinUint::U16 => IntegerType::Fixed(Integer::I16, false), - BuiltinUint::U32 => IntegerType::Fixed(Integer::I32, false), - BuiltinUint::U64 => IntegerType::Fixed(Integer::I64, false), - BuiltinUint::U128 => IntegerType::Fixed(Integer::I128, false), - }, - }); - } - ReprFlags::empty() - } - }) - } - } - - Some(ReprOptions { - int, - align: max_align, - pack: min_pack, - flags, - field_shuffle_seed: Hash64::ZERO, - }) -} - -impl StructData { - #[inline] - pub(crate) fn struct_data_query(db: &dyn DefDatabase, id: StructId) -> Arc { - db.struct_data_with_diagnostics(id).0 - } - - pub(crate) fn struct_data_with_diagnostics_query( - db: &dyn DefDatabase, - id: StructId, - ) -> (Arc, DefDiagnostics) { - let loc = id.lookup(db); - let krate = loc.container.krate; - let item_tree = loc.id.item_tree(db); - let repr = repr_from_value(db, krate, &item_tree, ModItem::from(loc.id.value).into()); - let attrs = item_tree.attrs(db, krate, ModItem::from(loc.id.value).into()); - - let mut flags = StructFlags::NO_FLAGS; - if attrs.by_key(&sym::rustc_has_incoherent_inherent_impls).exists() { - flags |= StructFlags::IS_RUSTC_HAS_INCOHERENT_INHERENT_IMPL; - } - if attrs.by_key(&sym::fundamental).exists() { - flags |= StructFlags::IS_FUNDAMENTAL; - } - if let Some(lang) = attrs.lang_item() { - match lang { - LangItem::PhantomData => flags |= StructFlags::IS_PHANTOM_DATA, - LangItem::OwnedBox => flags |= StructFlags::IS_BOX, - LangItem::ManuallyDrop => flags |= StructFlags::IS_MANUALLY_DROP, - LangItem::UnsafeCell => flags |= StructFlags::IS_UNSAFE_CELL, - _ => (), - } - } - - let strukt = &item_tree[loc.id.value]; - let (fields, diagnostics) = lower_fields( - db, - krate, - loc.container.local_id, - loc.id.tree_id(), - &item_tree, - &db.crate_graph()[krate].cfg_options, - FieldParent::Struct(loc.id.value), - &strukt.fields, - None, - ); - let types_map = strukt.types_map.clone(); - ( - Arc::new(StructData { - name: strukt.name.clone(), - variant_data: Arc::new(match strukt.shape { - FieldsShape::Record => VariantData::Record { fields, types_map }, - FieldsShape::Tuple => VariantData::Tuple { fields, types_map }, - FieldsShape::Unit => VariantData::Unit, - }), - repr, - visibility: item_tree[strukt.visibility].clone(), - flags, - }), - DefDiagnostics::new(diagnostics), - ) - } - - #[inline] - pub(crate) fn union_data_query(db: &dyn DefDatabase, id: UnionId) -> Arc { - db.union_data_with_diagnostics(id).0 - } - - pub(crate) fn union_data_with_diagnostics_query( - db: &dyn DefDatabase, - id: UnionId, - ) -> (Arc, DefDiagnostics) { - let loc = id.lookup(db); - let krate = loc.container.krate; - let item_tree = loc.id.item_tree(db); - let repr = repr_from_value(db, krate, &item_tree, ModItem::from(loc.id.value).into()); - let attrs = item_tree.attrs(db, krate, ModItem::from(loc.id.value).into()); - let mut flags = StructFlags::NO_FLAGS; - if attrs.by_key(&sym::rustc_has_incoherent_inherent_impls).exists() { - flags |= StructFlags::IS_RUSTC_HAS_INCOHERENT_INHERENT_IMPL; - } - if attrs.by_key(&sym::fundamental).exists() { - flags |= StructFlags::IS_FUNDAMENTAL; - } - - let union = &item_tree[loc.id.value]; - let (fields, diagnostics) = lower_fields( - db, - krate, - loc.container.local_id, - loc.id.tree_id(), - &item_tree, - &db.crate_graph()[krate].cfg_options, - FieldParent::Union(loc.id.value), - &union.fields, - None, - ); - let types_map = union.types_map.clone(); - ( - Arc::new(StructData { - name: union.name.clone(), - variant_data: Arc::new(VariantData::Record { fields, types_map }), - repr, - visibility: item_tree[union.visibility].clone(), - flags, - }), - DefDiagnostics::new(diagnostics), - ) - } -} - -impl EnumData { - pub(crate) fn enum_data_query(db: &dyn DefDatabase, e: EnumId) -> Arc { - let loc = e.lookup(db); - let krate = loc.container.krate; - let item_tree = loc.id.item_tree(db); - let repr = repr_from_value(db, krate, &item_tree, ModItem::from(loc.id.value).into()); - let rustc_has_incoherent_inherent_impls = item_tree - .attrs(db, loc.container.krate, ModItem::from(loc.id.value).into()) - .by_key(&sym::rustc_has_incoherent_inherent_impls) - .exists(); - - let enum_ = &item_tree[loc.id.value]; - - Arc::new(EnumData { - name: enum_.name.clone(), - variants: loc.container.def_map(db).enum_definitions[&e] - .iter() - .map(|&id| (id, item_tree[id.lookup(db).id.value].name.clone())) - .collect(), - repr, - visibility: item_tree[enum_.visibility].clone(), - rustc_has_incoherent_inherent_impls, - }) - } - - pub fn variant(&self, name: &Name) -> Option { - let &(id, _) = self.variants.iter().find(|(_id, n)| n == name)?; - Some(id) - } - - pub fn variant_body_type(&self) -> IntegerType { - match self.repr { - Some(ReprOptions { int: Some(builtin), .. }) => builtin, - _ => IntegerType::Pointer(true), - } - } - - // [Adopted from rustc](https://github.com/rust-lang/rust/blob/bd53aa3bf7a24a70d763182303bd75e5fc51a9af/compiler/rustc_middle/src/ty/adt.rs#L446-L448) - pub fn is_payload_free(&self, db: &dyn DefDatabase) -> bool { - self.variants.iter().all(|(v, _)| { - // The condition check order is slightly modified from rustc - // to improve performance by early returning with relatively fast checks - let variant = &db.enum_variant_data(*v).variant_data; - if !variant.fields().is_empty() { - return false; - } - // The outer if condition is whether this variant has const ctor or not - if !matches!(variant.kind(), StructKind::Unit) { - let body = db.body((*v).into()); - // A variant with explicit discriminant - if body.exprs[body.body_expr] != Expr::Missing { - return false; - } - } - true - }) - } -} - -impl EnumVariantData { - #[inline] - pub(crate) fn enum_variant_data_query( - db: &dyn DefDatabase, - e: EnumVariantId, - ) -> Arc { - db.enum_variant_data_with_diagnostics(e).0 - } - - pub(crate) fn enum_variant_data_with_diagnostics_query( - db: &dyn DefDatabase, - e: EnumVariantId, - ) -> (Arc, DefDiagnostics) { - let loc = e.lookup(db); - let container = loc.parent.lookup(db).container; - let krate = container.krate; - let item_tree = loc.id.item_tree(db); - let variant = &item_tree[loc.id.value]; - - let (fields, diagnostics) = lower_fields( - db, - krate, - container.local_id, - loc.id.tree_id(), - &item_tree, - &db.crate_graph()[krate].cfg_options, - FieldParent::Variant(loc.id.value), - &variant.fields, - Some(item_tree[loc.parent.lookup(db).id.value].visibility), - ); - let types_map = variant.types_map.clone(); - - ( - Arc::new(EnumVariantData { - name: variant.name.clone(), - variant_data: Arc::new(match variant.shape { - FieldsShape::Record => VariantData::Record { fields, types_map }, - FieldsShape::Tuple => VariantData::Tuple { fields, types_map }, - FieldsShape::Unit => VariantData::Unit, - }), - }), - DefDiagnostics::new(diagnostics), - ) - } -} - -impl VariantData { - pub fn fields(&self) -> &Arena { - const EMPTY: &Arena = &Arena::new(); - match &self { - VariantData::Record { fields, .. } | VariantData::Tuple { fields, .. } => fields, - _ => EMPTY, - } - } - - pub fn types_map(&self) -> &TypesMap { - match &self { - VariantData::Record { types_map, .. } | VariantData::Tuple { types_map, .. } => { - types_map - } - VariantData::Unit => TypesMap::EMPTY, - } - } - - // FIXME: Linear lookup - pub fn field(&self, name: &Name) -> Option { - self.fields().iter().find_map(|(id, data)| if &data.name == name { Some(id) } else { None }) - } - - pub fn kind(&self) -> StructKind { - match self { - VariantData::Record { .. } => StructKind::Record, - VariantData::Tuple { .. } => StructKind::Tuple, - VariantData::Unit => StructKind::Unit, - } - } - - #[allow(clippy::self_named_constructors)] - pub(crate) fn variant_data(db: &dyn DefDatabase, id: VariantId) -> Arc { - match id { - VariantId::StructId(it) => db.struct_data(it).variant_data.clone(), - VariantId::EnumVariantId(it) => db.enum_variant_data(it).variant_data.clone(), - VariantId::UnionId(it) => db.union_data(it).variant_data.clone(), - } - } -} - -#[derive(Debug, Copy, Clone, PartialEq, Eq)] -pub enum StructKind { - Tuple, - Record, - Unit, -} - -fn lower_fields( - db: &dyn DefDatabase, - krate: CrateId, - container: LocalModuleId, - tree_id: TreeId, - item_tree: &ItemTree, - cfg_options: &CfgOptions, - parent: FieldParent, - fields: &[Field], - override_visibility: Option, -) -> (Arena, Vec) { - let mut diagnostics = Vec::new(); - let mut arena = Arena::new(); - for (idx, field) in fields.iter().enumerate() { - let attr_owner = AttrOwner::make_field_indexed(parent, idx); - let attrs = item_tree.attrs(db, krate, attr_owner); - if attrs.is_cfg_enabled(cfg_options) { - arena.alloc(lower_field(item_tree, field, override_visibility)); - } else { - diagnostics.push(DefDiagnostic::unconfigured_code( - container, - tree_id, - attr_owner, - attrs.cfg().unwrap(), - cfg_options.clone(), - )) - } - } - (arena, diagnostics) -} - -fn lower_field( - item_tree: &ItemTree, - field: &Field, - override_visibility: Option, -) -> FieldData { - FieldData { - name: field.name.clone(), - type_ref: field.type_ref, - visibility: item_tree[override_visibility.unwrap_or(field.visibility)].clone(), - } -} diff --git a/src/tools/rust-analyzer/crates/hir-def/src/db.rs b/src/tools/rust-analyzer/crates/hir-def/src/db.rs index 598a850898bb6..34cf42d02bdb0 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/db.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/db.rs @@ -1,273 +1,373 @@ //! Defines database & queries for name resolution. -use base_db::{ra_salsa, CrateId, SourceDatabase, Upcast}; +use base_db::{Crate, RootQueryDb, SourceDatabase}; use either::Either; -use hir_expand::{db::ExpandDatabase, HirFileId, MacroDefId}; +use hir_expand::{EditionedFileId, HirFileId, MacroCallId, MacroDefId, db::ExpandDatabase}; use intern::sym; use la_arena::ArenaMap; -use span::{EditionedFileId, MacroCallId}; -use syntax::{ast, AstPtr}; +use syntax::{AstPtr, ast}; +use thin_vec::ThinVec; use triomphe::Arc; use crate::{ + AttrDefId, BlockId, BlockLoc, ConstId, ConstLoc, DefWithBodyId, EnumId, EnumLoc, EnumVariantId, + EnumVariantLoc, ExternBlockId, ExternBlockLoc, ExternCrateId, ExternCrateLoc, FunctionId, + FunctionLoc, GenericDefId, ImplId, ImplLoc, LocalFieldId, Macro2Id, Macro2Loc, MacroId, + MacroRulesId, MacroRulesLoc, MacroRulesLocFlags, ProcMacroId, ProcMacroLoc, StaticId, + StaticLoc, StructId, StructLoc, TraitAliasId, TraitAliasLoc, TraitId, TraitLoc, TypeAliasId, + TypeAliasLoc, UnionId, UnionLoc, UseId, UseLoc, VariantId, attr::{Attrs, AttrsWithOwner}, - data::{ - adt::{EnumData, EnumVariantData, StructData, VariantData}, - ConstData, ExternCrateDeclData, FunctionData, ImplData, Macro2Data, MacroRulesData, - ProcMacroData, StaticData, TraitAliasData, TraitData, TypeAliasData, + expr_store::{ + Body, BodySourceMap, ExpressionStore, ExpressionStoreSourceMap, scope::ExprScopes, }, - expr_store::{scope::ExprScopes, Body, BodySourceMap}, - generics::GenericParams, + hir::generics::GenericParams, import_map::ImportMap, - item_tree::{AttrOwner, ItemTree, ItemTreeSourceMaps}, + item_tree::{AttrOwner, ItemTree}, lang_item::{self, LangItem, LangItemTarget, LangItems}, - nameres::{diagnostics::DefDiagnostics, DefMap}, + nameres::{ + DefMap, LocalDefMap, + assoc::{ImplItems, TraitItems}, + diagnostics::DefDiagnostics, + }, + signatures::{ + ConstSignature, EnumSignature, EnumVariants, FunctionSignature, ImplSignature, + InactiveEnumVariantCode, StaticSignature, StructSignature, TraitAliasSignature, + TraitSignature, TypeAliasSignature, UnionSignature, VariantFields, + }, tt, - type_ref::TypesSourceMap, visibility::{self, Visibility}, - AttrDefId, BlockId, BlockLoc, ConstBlockId, ConstBlockLoc, ConstId, ConstLoc, DefWithBodyId, - EnumId, EnumLoc, EnumVariantId, EnumVariantLoc, ExternBlockId, ExternBlockLoc, ExternCrateId, - ExternCrateLoc, FunctionId, FunctionLoc, GenericDefId, ImplId, ImplLoc, InTypeConstId, - InTypeConstLoc, LocalFieldId, Macro2Id, Macro2Loc, MacroId, MacroRulesId, MacroRulesLoc, - MacroRulesLocFlags, ProcMacroId, ProcMacroLoc, StaticId, StaticLoc, StructId, StructLoc, - TraitAliasId, TraitAliasLoc, TraitId, TraitLoc, TypeAliasId, TypeAliasLoc, UnionId, UnionLoc, - UseId, UseLoc, VariantId, }; -#[ra_salsa::query_group(InternDatabaseStorage)] -pub trait InternDatabase: SourceDatabase { +use salsa::plumbing::AsId; + +#[query_group::query_group(InternDatabaseStorage)] +pub trait InternDatabase: RootQueryDb { // region: items - #[ra_salsa::interned] + #[salsa::interned] fn intern_use(&self, loc: UseLoc) -> UseId; - #[ra_salsa::interned] + + #[salsa::interned] fn intern_extern_crate(&self, loc: ExternCrateLoc) -> ExternCrateId; - #[ra_salsa::interned] + + #[salsa::interned] fn intern_function(&self, loc: FunctionLoc) -> FunctionId; - #[ra_salsa::interned] + + #[salsa::interned] fn intern_struct(&self, loc: StructLoc) -> StructId; - #[ra_salsa::interned] + + #[salsa::interned] fn intern_union(&self, loc: UnionLoc) -> UnionId; - #[ra_salsa::interned] + + #[salsa::interned] fn intern_enum(&self, loc: EnumLoc) -> EnumId; - #[ra_salsa::interned] + + #[salsa::interned] fn intern_enum_variant(&self, loc: EnumVariantLoc) -> EnumVariantId; - #[ra_salsa::interned] + + #[salsa::interned] fn intern_const(&self, loc: ConstLoc) -> ConstId; - #[ra_salsa::interned] + + #[salsa::interned] fn intern_static(&self, loc: StaticLoc) -> StaticId; - #[ra_salsa::interned] + + #[salsa::interned] fn intern_trait(&self, loc: TraitLoc) -> TraitId; - #[ra_salsa::interned] + + #[salsa::interned] fn intern_trait_alias(&self, loc: TraitAliasLoc) -> TraitAliasId; - #[ra_salsa::interned] + + #[salsa::interned] fn intern_type_alias(&self, loc: TypeAliasLoc) -> TypeAliasId; - #[ra_salsa::interned] + + #[salsa::interned] fn intern_impl(&self, loc: ImplLoc) -> ImplId; - #[ra_salsa::interned] + + #[salsa::interned] fn intern_extern_block(&self, loc: ExternBlockLoc) -> ExternBlockId; - #[ra_salsa::interned] + + #[salsa::interned] fn intern_macro2(&self, loc: Macro2Loc) -> Macro2Id; - #[ra_salsa::interned] + + #[salsa::interned] fn intern_proc_macro(&self, loc: ProcMacroLoc) -> ProcMacroId; - #[ra_salsa::interned] + + #[salsa::interned] fn intern_macro_rules(&self, loc: MacroRulesLoc) -> MacroRulesId; - // endregion: items + // // endregion: items - #[ra_salsa::interned] + #[salsa::interned] fn intern_block(&self, loc: BlockLoc) -> BlockId; - #[ra_salsa::interned] - fn intern_anonymous_const(&self, id: ConstBlockLoc) -> ConstBlockId; - #[ra_salsa::interned] - fn intern_in_type_const(&self, id: InTypeConstLoc) -> InTypeConstId; } -#[ra_salsa::query_group(DefDatabaseStorage)] -pub trait DefDatabase: InternDatabase + ExpandDatabase + Upcast { +#[query_group::query_group] +pub trait DefDatabase: InternDatabase + ExpandDatabase + SourceDatabase { /// Whether to expand procedural macros during name resolution. - #[ra_salsa::input] + #[salsa::input] fn expand_proc_attr_macros(&self) -> bool; /// Computes an [`ItemTree`] for the given file or macro expansion. - #[ra_salsa::invoke(ItemTree::file_item_tree_query)] + #[salsa::invoke(ItemTree::file_item_tree_query)] fn file_item_tree(&self, file_id: HirFileId) -> Arc; - #[ra_salsa::invoke(ItemTree::block_item_tree_query)] + #[salsa::invoke(ItemTree::block_item_tree_query)] fn block_item_tree(&self, block_id: BlockId) -> Arc; - #[ra_salsa::invoke(ItemTree::file_item_tree_with_source_map_query)] - fn file_item_tree_with_source_map( - &self, - file_id: HirFileId, - ) -> (Arc, Arc); - - #[ra_salsa::invoke(ItemTree::block_item_tree_with_source_map_query)] - fn block_item_tree_with_source_map( - &self, - block_id: BlockId, - ) -> (Arc, Arc); + #[salsa::invoke(DefMap::crate_local_def_map_query)] + fn crate_local_def_map(&self, krate: Crate) -> (Arc, Arc); - #[ra_salsa::invoke(DefMap::crate_def_map_query)] - fn crate_def_map(&self, krate: CrateId) -> Arc; + #[salsa::invoke(DefMap::crate_def_map_query)] + fn crate_def_map(&self, krate: Crate) -> Arc; /// Computes the block-level `DefMap`. - #[ra_salsa::invoke(DefMap::block_def_map_query)] + #[salsa::invoke(DefMap::block_def_map_query)] fn block_def_map(&self, block: BlockId) -> Arc; /// Turns a MacroId into a MacroDefId, describing the macro's definition post name resolution. + #[salsa::invoke(macro_def)] fn macro_def(&self, m: MacroId) -> MacroDefId; // region:data - #[ra_salsa::transparent] - #[ra_salsa::invoke(StructData::struct_data_query)] - fn struct_data(&self, id: StructId) -> Arc; + #[salsa::invoke(VariantFields::query)] + fn variant_fields_with_source_map( + &self, + id: VariantId, + ) -> (Arc, Arc); - #[ra_salsa::invoke(StructData::struct_data_with_diagnostics_query)] - fn struct_data_with_diagnostics(&self, id: StructId) -> (Arc, DefDiagnostics); + #[salsa::tracked] + fn enum_variants(&self, id: EnumId) -> Arc { + self.enum_variants_with_diagnostics(id).0 + } + + #[salsa::invoke(EnumVariants::enum_variants_query)] + fn enum_variants_with_diagnostics( + &self, + id: EnumId, + ) -> (Arc, Option>>); - #[ra_salsa::transparent] - #[ra_salsa::invoke(StructData::union_data_query)] - fn union_data(&self, id: UnionId) -> Arc; + #[salsa::transparent] + #[salsa::invoke(ImplItems::impl_items_query)] + fn impl_items(&self, e: ImplId) -> Arc; - #[ra_salsa::invoke(StructData::union_data_with_diagnostics_query)] - fn union_data_with_diagnostics(&self, id: UnionId) -> (Arc, DefDiagnostics); + #[salsa::invoke(ImplItems::impl_items_with_diagnostics_query)] + fn impl_items_with_diagnostics(&self, e: ImplId) -> (Arc, DefDiagnostics); - #[ra_salsa::invoke(EnumData::enum_data_query)] - fn enum_data(&self, e: EnumId) -> Arc; + #[salsa::transparent] + #[salsa::invoke(TraitItems::trait_items_query)] + fn trait_items(&self, e: TraitId) -> Arc; - #[ra_salsa::transparent] - #[ra_salsa::invoke(EnumVariantData::enum_variant_data_query)] - fn enum_variant_data(&self, id: EnumVariantId) -> Arc; + #[salsa::invoke(TraitItems::trait_items_with_diagnostics_query)] + fn trait_items_with_diagnostics(&self, tr: TraitId) -> (Arc, DefDiagnostics); - #[ra_salsa::invoke(EnumVariantData::enum_variant_data_with_diagnostics_query)] - fn enum_variant_data_with_diagnostics( - &self, - id: EnumVariantId, - ) -> (Arc, DefDiagnostics); + #[salsa::tracked] + fn variant_fields(&self, id: VariantId) -> Arc { + self.variant_fields_with_source_map(id).0 + } + + #[salsa::tracked] + fn trait_signature(&self, trait_: TraitId) -> Arc { + self.trait_signature_with_source_map(trait_).0 + } - #[ra_salsa::transparent] - #[ra_salsa::invoke(VariantData::variant_data)] - fn variant_data(&self, id: VariantId) -> Arc; - #[ra_salsa::transparent] - #[ra_salsa::invoke(ImplData::impl_data_query)] - fn impl_data(&self, e: ImplId) -> Arc; + #[salsa::tracked] + fn impl_signature(&self, impl_: ImplId) -> Arc { + self.impl_signature_with_source_map(impl_).0 + } + + #[salsa::tracked] + fn struct_signature(&self, struct_: StructId) -> Arc { + self.struct_signature_with_source_map(struct_).0 + } + + #[salsa::tracked] + fn union_signature(&self, union_: UnionId) -> Arc { + self.union_signature_with_source_map(union_).0 + } + + #[salsa::tracked] + fn enum_signature(&self, e: EnumId) -> Arc { + self.enum_signature_with_source_map(e).0 + } - #[ra_salsa::invoke(ImplData::impl_data_with_diagnostics_query)] - fn impl_data_with_diagnostics(&self, e: ImplId) -> (Arc, DefDiagnostics); + #[salsa::tracked] + fn const_signature(&self, e: ConstId) -> Arc { + self.const_signature_with_source_map(e).0 + } - #[ra_salsa::transparent] - #[ra_salsa::invoke(TraitData::trait_data_query)] - fn trait_data(&self, e: TraitId) -> Arc; + #[salsa::tracked] + fn static_signature(&self, e: StaticId) -> Arc { + self.static_signature_with_source_map(e).0 + } + + #[salsa::tracked] + fn function_signature(&self, e: FunctionId) -> Arc { + self.function_signature_with_source_map(e).0 + } + + #[salsa::tracked] + fn trait_alias_signature(&self, e: TraitAliasId) -> Arc { + self.trait_alias_signature_with_source_map(e).0 + } + + #[salsa::tracked] + fn type_alias_signature(&self, e: TypeAliasId) -> Arc { + self.type_alias_signature_with_source_map(e).0 + } - #[ra_salsa::invoke(TraitData::trait_data_with_diagnostics_query)] - fn trait_data_with_diagnostics(&self, tr: TraitId) -> (Arc, DefDiagnostics); + #[salsa::invoke(TraitSignature::query)] + fn trait_signature_with_source_map( + &self, + trait_: TraitId, + ) -> (Arc, Arc); - #[ra_salsa::invoke(TraitAliasData::trait_alias_query)] - fn trait_alias_data(&self, e: TraitAliasId) -> Arc; + #[salsa::invoke(ImplSignature::query)] + fn impl_signature_with_source_map( + &self, + impl_: ImplId, + ) -> (Arc, Arc); - #[ra_salsa::invoke(TypeAliasData::type_alias_data_query)] - fn type_alias_data(&self, e: TypeAliasId) -> Arc; + #[salsa::invoke(StructSignature::query)] + fn struct_signature_with_source_map( + &self, + struct_: StructId, + ) -> (Arc, Arc); - #[ra_salsa::invoke(FunctionData::fn_data_query)] - fn function_data(&self, func: FunctionId) -> Arc; + #[salsa::invoke(UnionSignature::query)] + fn union_signature_with_source_map( + &self, + union_: UnionId, + ) -> (Arc, Arc); - #[ra_salsa::invoke(ConstData::const_data_query)] - fn const_data(&self, konst: ConstId) -> Arc; + #[salsa::invoke(EnumSignature::query)] + fn enum_signature_with_source_map( + &self, + e: EnumId, + ) -> (Arc, Arc); - #[ra_salsa::invoke(StaticData::static_data_query)] - fn static_data(&self, statik: StaticId) -> Arc; + #[salsa::invoke(ConstSignature::query)] + fn const_signature_with_source_map( + &self, + e: ConstId, + ) -> (Arc, Arc); - #[ra_salsa::invoke(Macro2Data::macro2_data_query)] - fn macro2_data(&self, makro: Macro2Id) -> Arc; + #[salsa::invoke(StaticSignature::query)] + fn static_signature_with_source_map( + &self, + e: StaticId, + ) -> (Arc, Arc); - #[ra_salsa::invoke(MacroRulesData::macro_rules_data_query)] - fn macro_rules_data(&self, makro: MacroRulesId) -> Arc; + #[salsa::invoke(FunctionSignature::query)] + fn function_signature_with_source_map( + &self, + e: FunctionId, + ) -> (Arc, Arc); - #[ra_salsa::invoke(ProcMacroData::proc_macro_data_query)] - fn proc_macro_data(&self, makro: ProcMacroId) -> Arc; + #[salsa::invoke(TraitAliasSignature::query)] + fn trait_alias_signature_with_source_map( + &self, + e: TraitAliasId, + ) -> (Arc, Arc); - #[ra_salsa::invoke(ExternCrateDeclData::extern_crate_decl_data_query)] - fn extern_crate_decl_data(&self, extern_crate: ExternCrateId) -> Arc; + #[salsa::invoke(TypeAliasSignature::query)] + fn type_alias_signature_with_source_map( + &self, + e: TypeAliasId, + ) -> (Arc, Arc); // endregion:data - #[ra_salsa::invoke(Body::body_with_source_map_query)] - #[ra_salsa::lru] + #[salsa::invoke(Body::body_with_source_map_query)] + #[salsa::lru(512)] fn body_with_source_map(&self, def: DefWithBodyId) -> (Arc, Arc); - #[ra_salsa::invoke(Body::body_query)] + #[salsa::invoke(Body::body_query)] fn body(&self, def: DefWithBodyId) -> Arc; - #[ra_salsa::invoke(ExprScopes::expr_scopes_query)] + #[salsa::invoke(ExprScopes::expr_scopes_query)] fn expr_scopes(&self, def: DefWithBodyId) -> Arc; - #[ra_salsa::invoke(GenericParams::generic_params_query)] + #[salsa::transparent] + #[salsa::invoke(GenericParams::new)] fn generic_params(&self, def: GenericDefId) -> Arc; - /// If this returns `None` for the source map, that means it is the same as with the item tree. - #[ra_salsa::invoke(GenericParams::generic_params_with_source_map_query)] - fn generic_params_with_source_map( + #[salsa::transparent] + #[salsa::invoke(GenericParams::generic_params_and_store)] + fn generic_params_and_store( &self, def: GenericDefId, - ) -> (Arc, Option>); + ) -> (Arc, Arc); + + #[salsa::transparent] + #[salsa::invoke(GenericParams::generic_params_and_store_and_source_map)] + fn generic_params_and_store_and_source_map( + &self, + def: GenericDefId, + ) -> (Arc, Arc, Arc); // region:attrs - #[ra_salsa::invoke(Attrs::fields_attrs_query)] + #[salsa::invoke(Attrs::fields_attrs_query)] fn fields_attrs(&self, def: VariantId) -> Arc>; // should this really be a query? - #[ra_salsa::invoke(crate::attr::fields_attrs_source_map)] + #[salsa::invoke(crate::attr::fields_attrs_source_map)] fn fields_attrs_source_map( &self, def: VariantId, ) -> Arc>>>; - #[ra_salsa::invoke(AttrsWithOwner::attrs_query)] + // FIXME: Make this a non-interned query. + #[salsa::invoke_interned(AttrsWithOwner::attrs_query)] fn attrs(&self, def: AttrDefId) -> Attrs; - #[ra_salsa::transparent] - #[ra_salsa::invoke(lang_item::lang_attr)] + #[salsa::transparent] + #[salsa::invoke(lang_item::lang_attr)] fn lang_attr(&self, def: AttrDefId) -> Option; // endregion:attrs - #[ra_salsa::invoke(LangItems::lang_item_query)] - fn lang_item(&self, start_crate: CrateId, item: LangItem) -> Option; + #[salsa::invoke(LangItems::lang_item_query)] + fn lang_item(&self, start_crate: Crate, item: LangItem) -> Option; - #[ra_salsa::invoke(ImportMap::import_map_query)] - fn import_map(&self, krate: CrateId) -> Arc; + #[salsa::invoke(ImportMap::import_map_query)] + fn import_map(&self, krate: Crate) -> Arc; // region:visibilities - #[ra_salsa::invoke(visibility::field_visibilities_query)] + #[salsa::invoke(visibility::field_visibilities_query)] fn field_visibilities(&self, var: VariantId) -> Arc>; // FIXME: unify function_visibility and const_visibility? - #[ra_salsa::invoke(visibility::function_visibility_query)] + + #[salsa::invoke(visibility::function_visibility_query)] fn function_visibility(&self, def: FunctionId) -> Visibility; - #[ra_salsa::invoke(visibility::const_visibility_query)] + #[salsa::invoke(visibility::const_visibility_query)] fn const_visibility(&self, def: ConstId) -> Visibility; + #[salsa::invoke(visibility::type_alias_visibility_query)] + fn type_alias_visibility(&self, def: TypeAliasId) -> Visibility; + // endregion:visibilities - #[ra_salsa::invoke(LangItems::crate_lang_items_query)] - fn crate_lang_items(&self, krate: CrateId) -> Option>; + #[salsa::invoke(LangItems::crate_lang_items_query)] + fn crate_lang_items(&self, krate: Crate) -> Option>; - #[ra_salsa::invoke(crate::lang_item::notable_traits_in_deps)] - fn notable_traits_in_deps(&self, krate: CrateId) -> Arc<[Arc<[TraitId]>]>; - #[ra_salsa::invoke(crate::lang_item::crate_notable_traits)] - fn crate_notable_traits(&self, krate: CrateId) -> Option>; + #[salsa::invoke(crate::lang_item::notable_traits_in_deps)] + fn notable_traits_in_deps(&self, krate: Crate) -> Arc<[Arc<[TraitId]>]>; + #[salsa::invoke(crate::lang_item::crate_notable_traits)] + fn crate_notable_traits(&self, krate: Crate) -> Option>; - fn crate_supports_no_std(&self, crate_id: CrateId) -> bool; + #[salsa::invoke(crate_supports_no_std)] + fn crate_supports_no_std(&self, crate_id: Crate) -> bool; - fn include_macro_invoc(&self, crate_id: CrateId) -> Arc<[(MacroCallId, EditionedFileId)]>; + #[salsa::invoke(include_macro_invoc)] + fn include_macro_invoc(&self, crate_id: Crate) -> Arc<[(MacroCallId, EditionedFileId)]>; } // return: macro call id and include file id fn include_macro_invoc( db: &dyn DefDatabase, - krate: CrateId, + krate: Crate, ) -> Arc<[(MacroCallId, EditionedFileId)]> { db.crate_def_map(krate) .modules @@ -275,20 +375,20 @@ fn include_macro_invoc( .flat_map(|m| m.scope.iter_macro_invoc()) .filter_map(|invoc| { db.lookup_intern_macro_call(*invoc.1) - .include_file_id(db.upcast(), *invoc.1) + .include_file_id(db, *invoc.1) .map(|x| (*invoc.1, x)) }) .collect() } -fn crate_supports_no_std(db: &dyn DefDatabase, crate_id: CrateId) -> bool { - let file = db.crate_graph()[crate_id].root_file_id(); +fn crate_supports_no_std(db: &dyn DefDatabase, crate_id: Crate) -> bool { + let file = crate_id.data(db).root_file_id(db); let item_tree = db.file_item_tree(file.into()); let attrs = item_tree.raw_attrs(AttrOwner::TopLevel); for attr in &**attrs { match attr.path().as_ident() { - Some(ident) if *ident == sym::no_std.clone() => return true, - Some(ident) if *ident == sym::cfg_attr.clone() => {} + Some(ident) if *ident == sym::no_std => return true, + Some(ident) if *ident == sym::cfg_attr => {} _ => continue, } @@ -304,7 +404,7 @@ fn crate_supports_no_std(db: &dyn DefDatabase, crate_id: CrateId) -> bool { for output in segments.skip(1) { match output.flat_tokens() { [tt::TokenTree::Leaf(tt::Leaf::Ident(ident))] if ident.sym == sym::no_std => { - return true + return true; } _ => {} } diff --git a/src/tools/rust-analyzer/crates/hir-def/src/dyn_map.rs b/src/tools/rust-analyzer/crates/hir-def/src/dyn_map.rs index 8868bc0cd95bd..eed1490a7af62 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/dyn_map.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/dyn_map.rs @@ -27,15 +27,15 @@ pub mod keys { use std::marker::PhantomData; - use hir_expand::{attrs::AttrId, MacroCallId}; + use hir_expand::{MacroCallId, attrs::AttrId}; use rustc_hash::FxHashMap; - use syntax::{ast, AstNode, AstPtr}; + use syntax::{AstNode, AstPtr, ast}; use crate::{ - dyn_map::{DynMap, Policy}, BlockId, ConstId, EnumId, EnumVariantId, ExternBlockId, ExternCrateId, FieldId, FunctionId, ImplId, LifetimeParamId, Macro2Id, MacroRulesId, ProcMacroId, StaticId, StructId, TraitAliasId, TraitId, TypeAliasId, TypeOrConstParamId, UnionId, UseId, + dyn_map::{DynMap, Policy}, }; pub type Key = crate::dyn_map::Key, V, AstPtrPolicy>; @@ -112,6 +112,10 @@ pub struct Key { } impl Key { + #[allow( + clippy::new_without_default, + reason = "this a const fn, so it can't be default yet. See " + )] pub(crate) const fn new() -> Key { Key { _phantom: PhantomData } } @@ -148,16 +152,11 @@ impl Policy for (K, V) { } } +#[derive(Default)] pub struct DynMap { pub(crate) map: Map, } -impl Default for DynMap { - fn default() -> Self { - DynMap { map: Map::new() } - } -} - #[repr(transparent)] pub struct KeyMap { map: DynMap, diff --git a/src/tools/rust-analyzer/crates/hir-def/src/expander.rs b/src/tools/rust-analyzer/crates/hir-def/src/expander.rs deleted file mode 100644 index a1b3123c9914e..0000000000000 --- a/src/tools/rust-analyzer/crates/hir-def/src/expander.rs +++ /dev/null @@ -1,243 +0,0 @@ -//! Macro expansion utilities. - -use std::cell::OnceCell; - -use base_db::CrateId; -use cfg::CfgOptions; -use drop_bomb::DropBomb; -use hir_expand::{ - attrs::RawAttrs, mod_path::ModPath, span_map::SpanMap, ExpandError, ExpandErrorKind, - ExpandResult, HirFileId, InFile, Lookup, MacroCallId, -}; -use span::{Edition, SyntaxContextId}; -use syntax::{ast, Parse}; -use triomphe::Arc; - -use crate::type_ref::{TypesMap, TypesSourceMap}; -use crate::{ - attr::Attrs, db::DefDatabase, lower::LowerCtx, path::Path, AsMacroCall, MacroId, ModuleId, - UnresolvedMacro, -}; - -#[derive(Debug)] -pub struct Expander { - cfg_options: Arc, - span_map: OnceCell, - current_file_id: HirFileId, - pub(crate) module: ModuleId, - /// `recursion_depth == usize::MAX` indicates that the recursion limit has been reached. - recursion_depth: u32, - recursion_limit: usize, -} - -impl Expander { - pub fn new(db: &dyn DefDatabase, current_file_id: HirFileId, module: ModuleId) -> Expander { - let recursion_limit = module.def_map(db).recursion_limit() as usize; - let recursion_limit = if cfg!(test) { - // Without this, `body::tests::your_stack_belongs_to_me` stack-overflows in debug - std::cmp::min(32, recursion_limit) - } else { - recursion_limit - }; - Expander { - current_file_id, - module, - recursion_depth: 0, - recursion_limit, - cfg_options: db.crate_graph()[module.krate].cfg_options.clone(), - span_map: OnceCell::new(), - } - } - - pub(crate) fn span_map(&self, db: &dyn DefDatabase) -> &SpanMap { - self.span_map.get_or_init(|| db.span_map(self.current_file_id)) - } - - pub fn krate(&self) -> CrateId { - self.module.krate - } - - pub fn syntax_context(&self) -> SyntaxContextId { - // FIXME: - SyntaxContextId::root(Edition::CURRENT) - } - - pub fn enter_expand( - &mut self, - db: &dyn DefDatabase, - macro_call: ast::MacroCall, - resolver: impl Fn(&ModPath) -> Option, - ) -> Result)>>, UnresolvedMacro> { - // FIXME: within_limit should support this, instead of us having to extract the error - let mut unresolved_macro_err = None; - - let result = self.within_limit(db, |this| { - let macro_call = this.in_file(¯o_call); - match macro_call.as_call_id_with_errors(db.upcast(), this.module.krate(), |path| { - resolver(path).map(|it| db.macro_def(it)) - }) { - Ok(call_id) => call_id, - Err(resolve_err) => { - unresolved_macro_err = Some(resolve_err); - ExpandResult { value: None, err: None } - } - } - }); - - if let Some(err) = unresolved_macro_err { - Err(err) - } else { - Ok(result) - } - } - - pub fn enter_expand_id( - &mut self, - db: &dyn DefDatabase, - call_id: MacroCallId, - ) -> ExpandResult)>> { - self.within_limit(db, |_this| ExpandResult::ok(Some(call_id))) - } - - pub fn exit(&mut self, mut mark: Mark) { - self.span_map = mark.span_map; - self.current_file_id = mark.file_id; - if self.recursion_depth == u32::MAX { - // Recursion limit has been reached somewhere in the macro expansion tree. Reset the - // depth only when we get out of the tree. - if !self.current_file_id.is_macro() { - self.recursion_depth = 0; - } - } else { - self.recursion_depth -= 1; - } - mark.bomb.defuse(); - } - - pub fn ctx<'a>( - &self, - db: &'a dyn DefDatabase, - types_map: &'a mut TypesMap, - types_source_map: &'a mut TypesSourceMap, - ) -> LowerCtx<'a> { - LowerCtx::with_span_map_cell( - db, - self.current_file_id, - self.span_map.clone(), - types_map, - types_source_map, - ) - } - - pub(crate) fn in_file(&self, value: T) -> InFile { - InFile { file_id: self.current_file_id, value } - } - - pub(crate) fn parse_attrs(&self, db: &dyn DefDatabase, owner: &dyn ast::HasAttrs) -> Attrs { - Attrs::filter( - db, - self.krate(), - RawAttrs::new( - db.upcast(), - owner, - self.span_map.get_or_init(|| db.span_map(self.current_file_id)).as_ref(), - ), - ) - } - - pub(crate) fn cfg_options(&self) -> &CfgOptions { - &self.cfg_options - } - - pub fn current_file_id(&self) -> HirFileId { - self.current_file_id - } - - pub(crate) fn parse_path( - &mut self, - db: &dyn DefDatabase, - path: ast::Path, - types_map: &mut TypesMap, - types_source_map: &mut TypesSourceMap, - ) -> Option { - let mut ctx = LowerCtx::with_span_map_cell( - db, - self.current_file_id, - self.span_map.clone(), - types_map, - types_source_map, - ); - Path::from_src(&mut ctx, path) - } - - fn within_limit( - &mut self, - db: &dyn DefDatabase, - op: F, - ) -> ExpandResult)>> - where - F: FnOnce(&mut Self) -> ExpandResult>, - { - if self.recursion_depth == u32::MAX { - // Recursion limit has been reached somewhere in the macro expansion tree. We should - // stop expanding other macro calls in this tree, or else this may result in - // exponential number of macro expansions, leading to a hang. - // - // The overflow error should have been reported when it occurred (see the next branch), - // so don't return overflow error here to avoid diagnostics duplication. - cov_mark::hit!(overflow_but_not_me); - return ExpandResult::ok(None); - } - - let ExpandResult { value, err } = op(self); - let Some(call_id) = value else { - return ExpandResult { value: None, err }; - }; - if self.recursion_depth as usize > self.recursion_limit { - self.recursion_depth = u32::MAX; - cov_mark::hit!(your_stack_belongs_to_me); - return ExpandResult::only_err(ExpandError::new( - db.macro_arg_considering_derives(call_id, &call_id.lookup(db.upcast()).kind).2, - ExpandErrorKind::RecursionOverflow, - )); - } - - let macro_file = call_id.as_macro_file(); - let res = db.parse_macro_expansion(macro_file); - - let err = err.or(res.err); - ExpandResult { - value: match &err { - // If proc-macro is disabled or unresolved, we want to expand to a missing expression - // instead of an empty tree which might end up in an empty block. - Some(e) if matches!(e.kind(), ExpandErrorKind::MissingProcMacroExpander(_)) => None, - _ => (|| { - let parse = res.value.0.cast::()?; - - self.recursion_depth += 1; - let old_span_map = OnceCell::new(); - if let Some(prev) = self.span_map.take() { - _ = old_span_map.set(prev); - }; - _ = self.span_map.set(SpanMap::ExpansionSpanMap(res.value.1)); - let old_file_id = - std::mem::replace(&mut self.current_file_id, macro_file.into()); - let mark = Mark { - file_id: old_file_id, - span_map: old_span_map, - bomb: DropBomb::new("expansion mark dropped"), - }; - Some((mark, parse)) - })(), - }, - err, - } - } -} - -#[derive(Debug)] -pub struct Mark { - file_id: HirFileId, - span_map: OnceCell, - bomb: DropBomb, -} diff --git a/src/tools/rust-analyzer/crates/hir-def/src/expr_store.rs b/src/tools/rust-analyzer/crates/hir-def/src/expr_store.rs index 5ff6a7ffe5669..e3775c4931ae8 100644 --- a/src/tools/rust-analyzer/crates/hir-def/src/expr_store.rs +++ b/src/tools/rust-analyzer/crates/hir-def/src/expr_store.rs @@ -1,10 +1,11 @@ //! Defines `ExpressionStore`: a lowered representation of functions, statics and //! consts. -mod body; -mod lower; -mod pretty; +pub mod body; +mod expander; +pub mod lower; +pub mod path; +pub mod pretty; pub mod scope; - #[cfg(test)] mod tests; @@ -12,45 +13,49 @@ use std::ops::{Deref, Index}; use cfg::{CfgExpr, CfgOptions}; use either::Either; -use hir_expand::{name::Name, ExpandError, InFile}; +use hir_expand::{ExpandError, InFile, MacroCallId, mod_path::ModPath, name::Name}; use la_arena::{Arena, ArenaMap}; use rustc_hash::FxHashMap; use smallvec::SmallVec; -use span::{Edition, MacroFileId, SyntaxContextData}; -use syntax::{ast, AstPtr, SyntaxNodePtr}; +use span::{Edition, SyntaxContext}; +use syntax::{AstPtr, SyntaxNodePtr, ast}; use triomphe::Arc; use tt::TextRange; use crate::{ + BlockId, SyntheticSyntax, db::DefDatabase, + expr_store::path::Path, hir::{ Array, AsmOperand, Binding, BindingId, Expr, ExprId, ExprOrPatId, Label, LabelId, Pat, PatId, RecordFieldPat, Statement, }, nameres::DefMap, - path::{ModPath, Path}, - type_ref::{TypeRef, TypeRefId, TypesMap, TypesSourceMap}, - BlockId, DefWithBodyId, Lookup, SyntheticSyntax, + type_ref::{LifetimeRef, LifetimeRefId, PathId, TypeRef, TypeRefId}, }; pub use self::body::{Body, BodySourceMap}; +pub use self::lower::{ + hir_assoc_type_binding_to_ast, hir_generic_arg_to_ast, hir_segment_to_ast_segment, +}; /// A wrapper around [`span::SyntaxContextId`] that is intended only for comparisons. #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub struct HygieneId(span::SyntaxContextId); +pub struct HygieneId(span::SyntaxContext); impl HygieneId { // The edition doesn't matter here, we only use this for comparisons and to lookup the macro. - pub const ROOT: Self = Self(span::SyntaxContextId::root(Edition::Edition2015)); + pub const ROOT: Self = Self(span::SyntaxContext::root(Edition::Edition2015)); - pub fn new(mut ctx: span::SyntaxContextId) -> Self { + pub fn new(mut ctx: span::SyntaxContext) -> Self { // See `Name` for why we're doing that. ctx.remove_root_edition(); Self(ctx) } - pub(crate) fn lookup(self, db: &dyn DefDatabase) -> SyntaxContextData { - db.lookup_intern_syntax_context(self.0) + // FIXME: Inline this + pub(crate) fn lookup(self) -> SyntaxContext { + self.0 } pub(crate) fn is_root(self) -> bool { @@ -79,27 +84,26 @@ pub type ExprOrPatSource = InFile; pub type SelfParamPtr = AstPtr; pub type MacroCallPtr = AstPtr; +pub type TypePtr = AstPtr; +pub type TypeSource = InFile; + +pub type LifetimePtr = AstPtr; +pub type LifetimeSource = InFile; + #[derive(Debug, Eq, PartialEq)] pub struct ExpressionStore { pub exprs: Arena, pub pats: Arena, pub bindings: Arena, pub labels: Arena