mirror of
https://github.com/rust-lang/rust.git
synced 2026-04-27 18:57:42 +03:00
Auto merge of #154572 - lnicola:sync-from-ra, r=lnicola
`rust-analyzer` subtree update Subtree update of `rust-analyzer` to https://github.com/rust-lang/rust-analyzer/commit/f1297b21119565c626320c1ffc248965fffb2527. Created using https://github.com/rust-lang/josh-sync. r? @ghost
This commit is contained in:
@@ -16,7 +16,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
|
||||
+13
-18
@@ -30,8 +30,8 @@ jobs:
|
||||
outputs:
|
||||
typescript: ${{ steps.filter.outputs.typescript }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: dorny/paths-filter@1441771bbfdd59dcd748680ee64ebd8faab1a242
|
||||
- uses: actions/checkout@v6
|
||||
- uses: dorny/paths-filter@fbd0ab8f3e69293af611ebaee6363fc25e6d187d # v4.0.1
|
||||
id: filter
|
||||
with:
|
||||
filters: |
|
||||
@@ -45,7 +45,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
ref: ${{ github.event.pull_request.head.sha }}
|
||||
|
||||
@@ -88,7 +88,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
ref: ${{ github.event.pull_request.head.sha }}
|
||||
|
||||
@@ -136,7 +136,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Install Rust toolchain
|
||||
run: |
|
||||
@@ -164,7 +164,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Install Rust toolchain
|
||||
run: |
|
||||
@@ -180,7 +180,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
|
||||
# Note that clippy output is currently dependent on whether rust-src is installed,
|
||||
# https://github.com/rust-lang/rust-clippy/issues/14625
|
||||
@@ -202,7 +202,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Install Rust toolchain
|
||||
run: |
|
||||
@@ -226,12 +226,7 @@ jobs:
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
target:
|
||||
[
|
||||
powerpc-unknown-linux-gnu,
|
||||
x86_64-unknown-linux-musl,
|
||||
wasm32-unknown-unknown,
|
||||
]
|
||||
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
|
||||
@@ -240,7 +235,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Install Rust toolchain
|
||||
run: |
|
||||
@@ -268,10 +263,10 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Install Nodejs
|
||||
uses: actions/setup-node@v4
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: 22
|
||||
|
||||
@@ -327,7 +322,7 @@ jobs:
|
||||
run: curl -LsSf https://github.com/crate-ci/typos/releases/download/$TYPOS_VERSION/typos-$TYPOS_VERSION-x86_64-unknown-linux-musl.tar.gz | tar zxf - -C ${CARGO_HOME:-~/.cargo}/bin
|
||||
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
ref: ${{ github.event.pull_request.head.sha }}
|
||||
|
||||
|
||||
+3
-3
@@ -13,7 +13,7 @@ jobs:
|
||||
coverage:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v6
|
||||
|
||||
- name: Install Rust toolchain
|
||||
run: |
|
||||
@@ -34,9 +34,9 @@ jobs:
|
||||
|
||||
- name: Generate code coverage
|
||||
run: cargo llvm-cov --workspace --lcov --output-path lcov.info
|
||||
|
||||
|
||||
- name: Upload coverage to Codecov
|
||||
uses: codecov/codecov-action@v5
|
||||
uses: codecov/codecov-action@57e3a136b779b570ffcdbf80b3bdc90e7fab3de2 # v6.0.0
|
||||
with:
|
||||
files: lcov.info
|
||||
fail_ci_if_error: false
|
||||
|
||||
+3
-3
@@ -2,10 +2,10 @@ name: Fuzz
|
||||
on:
|
||||
schedule:
|
||||
# Once a week
|
||||
- cron: '0 0 * * 0'
|
||||
- cron: "0 0 * * 0"
|
||||
push:
|
||||
paths:
|
||||
- '.github/workflows/fuzz.yml'
|
||||
- ".github/workflows/fuzz.yml"
|
||||
# Allow manual trigger
|
||||
workflow_dispatch:
|
||||
|
||||
@@ -27,7 +27,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
ref: ${{ github.event.pull_request.head.sha }}
|
||||
fetch-depth: 1
|
||||
|
||||
+11
-11
@@ -23,7 +23,7 @@ jobs:
|
||||
rustup component add --toolchain beta rust-src
|
||||
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Cache cargo
|
||||
uses: actions/cache@v4
|
||||
@@ -45,7 +45,7 @@ jobs:
|
||||
key: ${{ runner.os }}-target-${{ github.sha }}
|
||||
|
||||
- name: Upload build metrics
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: build-${{ github.sha }}
|
||||
path: target/build.json
|
||||
@@ -66,7 +66,7 @@ jobs:
|
||||
rustup component add --toolchain beta rust-src
|
||||
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Restore target cache
|
||||
uses: actions/cache@v4
|
||||
@@ -78,7 +78,7 @@ jobs:
|
||||
run: cargo xtask metrics "${{ matrix.names }}"
|
||||
|
||||
- name: Upload metrics
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: ${{ matrix.names }}-${{ github.sha }}
|
||||
path: target/${{ matrix.names }}.json
|
||||
@@ -89,35 +89,35 @@ jobs:
|
||||
needs: [build_metrics, other_metrics]
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Download build metrics
|
||||
uses: actions/download-artifact@v4
|
||||
uses: actions/download-artifact@v8
|
||||
with:
|
||||
name: build-${{ github.sha }}
|
||||
|
||||
- name: Download self metrics
|
||||
uses: actions/download-artifact@v4
|
||||
uses: actions/download-artifact@v8
|
||||
with:
|
||||
name: self-${{ github.sha }}
|
||||
|
||||
- name: Download ripgrep-13.0.0 metrics
|
||||
uses: actions/download-artifact@v4
|
||||
uses: actions/download-artifact@v8
|
||||
with:
|
||||
name: ripgrep-13.0.0-${{ github.sha }}
|
||||
|
||||
- name: Download webrender-2022 metrics
|
||||
uses: actions/download-artifact@v4
|
||||
uses: actions/download-artifact@v8
|
||||
with:
|
||||
name: webrender-2022-${{ github.sha }}
|
||||
|
||||
- name: Download diesel-1.4.8 metrics
|
||||
uses: actions/download-artifact@v4
|
||||
uses: actions/download-artifact@v8
|
||||
with:
|
||||
name: diesel-1.4.8-${{ github.sha }}
|
||||
|
||||
- name: Download hyper-0.14.18 metrics
|
||||
uses: actions/download-artifact@v4
|
||||
uses: actions/download-artifact@v8
|
||||
with:
|
||||
name: hyper-0.14.18-${{ github.sha }}
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
|
||||
+16
-16
@@ -70,12 +70,12 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: ${{ env.FETCH_DEPTH }}
|
||||
|
||||
- name: Install Node.js toolchain
|
||||
uses: actions/setup-node@v4
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: 22
|
||||
|
||||
@@ -143,7 +143,7 @@ jobs:
|
||||
run: target/${{ matrix.target }}/release/rust-analyzer analysis-stats --with-deps --no-sysroot --no-test $(rustc --print sysroot)/lib/rustlib/src/rust/library/std -q
|
||||
|
||||
- name: Upload artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: dist-${{ matrix.target }}
|
||||
path: ./dist
|
||||
@@ -166,7 +166,7 @@ jobs:
|
||||
run: apk add --no-cache git clang lld musl-dev nodejs npm
|
||||
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: ${{ env.FETCH_DEPTH }}
|
||||
|
||||
@@ -189,7 +189,7 @@ jobs:
|
||||
- run: rm -rf editors/code/server
|
||||
|
||||
- name: Upload artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: dist-x86_64-unknown-linux-musl
|
||||
path: ./dist
|
||||
@@ -201,7 +201,7 @@ jobs:
|
||||
needs: ["dist", "dist-x86_64-unknown-linux-musl"]
|
||||
steps:
|
||||
- name: Install Nodejs
|
||||
uses: actions/setup-node@v4
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: 22
|
||||
|
||||
@@ -212,46 +212,46 @@ jobs:
|
||||
- run: 'echo "TAG: $TAG"'
|
||||
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: ${{ env.FETCH_DEPTH }}
|
||||
|
||||
- run: echo "HEAD_SHA=$(git rev-parse HEAD)" >> $GITHUB_ENV
|
||||
- run: 'echo "HEAD_SHA: $HEAD_SHA"'
|
||||
|
||||
- uses: actions/download-artifact@v4
|
||||
- uses: actions/download-artifact@v8
|
||||
with:
|
||||
name: dist-aarch64-apple-darwin
|
||||
path: dist
|
||||
- uses: actions/download-artifact@v4
|
||||
- uses: actions/download-artifact@v8
|
||||
with:
|
||||
name: dist-x86_64-apple-darwin
|
||||
path: dist
|
||||
- uses: actions/download-artifact@v4
|
||||
- uses: actions/download-artifact@v8
|
||||
with:
|
||||
name: dist-x86_64-unknown-linux-gnu
|
||||
path: dist
|
||||
- uses: actions/download-artifact@v4
|
||||
- uses: actions/download-artifact@v8
|
||||
with:
|
||||
name: dist-x86_64-unknown-linux-musl
|
||||
path: dist
|
||||
- uses: actions/download-artifact@v4
|
||||
- uses: actions/download-artifact@v8
|
||||
with:
|
||||
name: dist-aarch64-unknown-linux-gnu
|
||||
path: dist
|
||||
- uses: actions/download-artifact@v4
|
||||
- uses: actions/download-artifact@v8
|
||||
with:
|
||||
name: dist-arm-unknown-linux-gnueabihf
|
||||
path: dist
|
||||
- uses: actions/download-artifact@v4
|
||||
- uses: actions/download-artifact@v8
|
||||
with:
|
||||
name: dist-x86_64-pc-windows-msvc
|
||||
path: dist
|
||||
- uses: actions/download-artifact@v4
|
||||
- uses: actions/download-artifact@v8
|
||||
with:
|
||||
name: dist-i686-pc-windows-msvc
|
||||
path: dist
|
||||
- uses: actions/download-artifact@v4
|
||||
- uses: actions/download-artifact@v8
|
||||
with:
|
||||
name: dist-aarch64-pc-windows-msvc
|
||||
path: dist
|
||||
|
||||
+16
-15
@@ -1,8 +1,8 @@
|
||||
name: rustdoc
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
branches:
|
||||
- master
|
||||
|
||||
env:
|
||||
CARGO_INCREMENTAL: 0
|
||||
@@ -10,6 +10,7 @@ env:
|
||||
RUSTFLAGS: "-D warnings -W unreachable-pub"
|
||||
RUSTDOCFLAGS: "-D warnings"
|
||||
RUSTUP_MAX_RETRIES: 10
|
||||
ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION: true
|
||||
|
||||
jobs:
|
||||
rustdoc:
|
||||
@@ -17,19 +18,19 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Install Rust toolchain
|
||||
run: rustup update --no-self-update stable
|
||||
- name: Install Rust toolchain
|
||||
run: rustup update --no-self-update stable
|
||||
|
||||
- name: Build Documentation
|
||||
run: cargo doc --all --no-deps --document-private-items
|
||||
- name: Build Documentation
|
||||
run: cargo doc --all --no-deps --document-private-items
|
||||
|
||||
- name: Deploy Docs
|
||||
uses: peaceiris/actions-gh-pages@4f9cc6602d3f66b9c108549d475ec49e8ef4d45e # v4.0.0
|
||||
with:
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
publish_branch: gh-pages
|
||||
publish_dir: ./target/doc
|
||||
force_orphan: true
|
||||
- name: Deploy Docs
|
||||
uses: peaceiris/actions-gh-pages@4f9cc6602d3f66b9c108549d475ec49e8ef4d45e # v4.0.0
|
||||
with:
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
publish_branch: gh-pages
|
||||
publish_dir: ./target/doc
|
||||
force_orphan: true
|
||||
|
||||
@@ -2315,6 +2315,7 @@ dependencies = [
|
||||
"ide-db",
|
||||
"ide-ssr",
|
||||
"indexmap",
|
||||
"intern",
|
||||
"itertools 0.14.0",
|
||||
"load-cargo",
|
||||
"lsp-server 0.7.9 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
||||
@@ -894,7 +894,7 @@ pub fn query_generic_params(
|
||||
def: GenericDefId,
|
||||
) -> &(ArenaMap<LocalLifetimeParamId, AttrFlags>, ArenaMap<LocalTypeOrConstParamId, AttrFlags>)
|
||||
{
|
||||
let generic_params = GenericParams::new(db, def);
|
||||
let generic_params = GenericParams::of(db, def);
|
||||
let params_count_excluding_self =
|
||||
generic_params.len() - usize::from(generic_params.trait_self_param().is_some());
|
||||
if params_count_excluding_self == 0 {
|
||||
|
||||
@@ -4,28 +4,18 @@
|
||||
EditionedFileId, HirFileId, InFile, Lookup, MacroCallId, MacroDefId, MacroDefKind,
|
||||
db::ExpandDatabase,
|
||||
};
|
||||
use la_arena::ArenaMap;
|
||||
use triomphe::Arc;
|
||||
|
||||
use crate::{
|
||||
AssocItemId, AttrDefId, BlockId, BlockLoc, ConstId, ConstLoc, DefWithBodyId, EnumId, EnumLoc,
|
||||
EnumVariantId, EnumVariantLoc, ExternBlockId, ExternBlockLoc, ExternCrateId, ExternCrateLoc,
|
||||
FunctionId, FunctionLoc, GenericDefId, ImplId, ImplLoc, LocalFieldId, Macro2Id, Macro2Loc,
|
||||
MacroExpander, MacroId, MacroRulesId, MacroRulesLoc, MacroRulesLocFlags, ProcMacroId,
|
||||
ProcMacroLoc, StaticId, StaticLoc, StructId, StructLoc, TraitId, TraitLoc, TypeAliasId,
|
||||
TypeAliasLoc, UnionId, UnionLoc, UseId, UseLoc, VariantId,
|
||||
AnonConstId, AnonConstLoc, AssocItemId, AttrDefId, BlockId, BlockLoc, ConstId, ConstLoc,
|
||||
EnumId, EnumLoc, EnumVariantId, EnumVariantLoc, ExternBlockId, ExternBlockLoc, ExternCrateId,
|
||||
ExternCrateLoc, FunctionId, FunctionLoc, ImplId, ImplLoc, Macro2Id, Macro2Loc, MacroExpander,
|
||||
MacroId, MacroRulesId, MacroRulesLoc, MacroRulesLocFlags, ProcMacroId, ProcMacroLoc, StaticId,
|
||||
StaticLoc, StructId, StructLoc, TraitId, TraitLoc, TypeAliasId, TypeAliasLoc, UnionId,
|
||||
UnionLoc, UseId, UseLoc,
|
||||
attrs::AttrFlags,
|
||||
expr_store::{
|
||||
Body, BodySourceMap, ExpressionStore, ExpressionStoreSourceMap, scope::ExprScopes,
|
||||
},
|
||||
hir::generics::GenericParams,
|
||||
import_map::ImportMap,
|
||||
item_tree::{ItemTree, file_item_tree_query},
|
||||
nameres::crate_def_map,
|
||||
signatures::{
|
||||
ConstSignature, EnumSignature, FunctionSignature, ImplSignature, StaticSignature,
|
||||
StructSignature, TraitSignature, TypeAliasSignature, UnionSignature,
|
||||
},
|
||||
visibility::{self, Visibility},
|
||||
};
|
||||
|
||||
@@ -61,6 +51,9 @@ pub trait InternDatabase: RootQueryDb {
|
||||
#[salsa::interned]
|
||||
fn intern_static(&self, loc: StaticLoc) -> StaticId;
|
||||
|
||||
#[salsa::interned]
|
||||
fn intern_anon_const(&self, loc: AnonConstLoc) -> AnonConstId;
|
||||
|
||||
#[salsa::interned]
|
||||
fn intern_trait(&self, loc: TraitLoc) -> TraitId;
|
||||
|
||||
@@ -102,145 +95,8 @@ pub trait DefDatabase: InternDatabase + ExpandDatabase + SourceDatabase {
|
||||
#[salsa::invoke(macro_def)]
|
||||
fn macro_def(&self, m: MacroId) -> MacroDefId;
|
||||
|
||||
// region:data
|
||||
|
||||
#[salsa::tracked]
|
||||
fn trait_signature(&self, trait_: TraitId) -> Arc<TraitSignature> {
|
||||
self.trait_signature_with_source_map(trait_).0
|
||||
}
|
||||
|
||||
#[salsa::tracked]
|
||||
fn impl_signature(&self, impl_: ImplId) -> Arc<ImplSignature> {
|
||||
self.impl_signature_with_source_map(impl_).0
|
||||
}
|
||||
|
||||
#[salsa::tracked]
|
||||
fn struct_signature(&self, struct_: StructId) -> Arc<StructSignature> {
|
||||
self.struct_signature_with_source_map(struct_).0
|
||||
}
|
||||
|
||||
#[salsa::tracked]
|
||||
fn union_signature(&self, union_: UnionId) -> Arc<UnionSignature> {
|
||||
self.union_signature_with_source_map(union_).0
|
||||
}
|
||||
|
||||
#[salsa::tracked]
|
||||
fn enum_signature(&self, e: EnumId) -> Arc<EnumSignature> {
|
||||
self.enum_signature_with_source_map(e).0
|
||||
}
|
||||
|
||||
#[salsa::tracked]
|
||||
fn const_signature(&self, e: ConstId) -> Arc<ConstSignature> {
|
||||
self.const_signature_with_source_map(e).0
|
||||
}
|
||||
|
||||
#[salsa::tracked]
|
||||
fn static_signature(&self, e: StaticId) -> Arc<StaticSignature> {
|
||||
self.static_signature_with_source_map(e).0
|
||||
}
|
||||
|
||||
#[salsa::tracked]
|
||||
fn function_signature(&self, e: FunctionId) -> Arc<FunctionSignature> {
|
||||
self.function_signature_with_source_map(e).0
|
||||
}
|
||||
|
||||
#[salsa::tracked]
|
||||
fn type_alias_signature(&self, e: TypeAliasId) -> Arc<TypeAliasSignature> {
|
||||
self.type_alias_signature_with_source_map(e).0
|
||||
}
|
||||
|
||||
#[salsa::invoke(TraitSignature::query)]
|
||||
fn trait_signature_with_source_map(
|
||||
&self,
|
||||
trait_: TraitId,
|
||||
) -> (Arc<TraitSignature>, Arc<ExpressionStoreSourceMap>);
|
||||
|
||||
#[salsa::invoke(ImplSignature::query)]
|
||||
fn impl_signature_with_source_map(
|
||||
&self,
|
||||
impl_: ImplId,
|
||||
) -> (Arc<ImplSignature>, Arc<ExpressionStoreSourceMap>);
|
||||
|
||||
#[salsa::invoke(StructSignature::query)]
|
||||
fn struct_signature_with_source_map(
|
||||
&self,
|
||||
struct_: StructId,
|
||||
) -> (Arc<StructSignature>, Arc<ExpressionStoreSourceMap>);
|
||||
|
||||
#[salsa::invoke(UnionSignature::query)]
|
||||
fn union_signature_with_source_map(
|
||||
&self,
|
||||
union_: UnionId,
|
||||
) -> (Arc<UnionSignature>, Arc<ExpressionStoreSourceMap>);
|
||||
|
||||
#[salsa::invoke(EnumSignature::query)]
|
||||
fn enum_signature_with_source_map(
|
||||
&self,
|
||||
e: EnumId,
|
||||
) -> (Arc<EnumSignature>, Arc<ExpressionStoreSourceMap>);
|
||||
|
||||
#[salsa::invoke(ConstSignature::query)]
|
||||
fn const_signature_with_source_map(
|
||||
&self,
|
||||
e: ConstId,
|
||||
) -> (Arc<ConstSignature>, Arc<ExpressionStoreSourceMap>);
|
||||
|
||||
#[salsa::invoke(StaticSignature::query)]
|
||||
fn static_signature_with_source_map(
|
||||
&self,
|
||||
e: StaticId,
|
||||
) -> (Arc<StaticSignature>, Arc<ExpressionStoreSourceMap>);
|
||||
|
||||
#[salsa::invoke(FunctionSignature::query)]
|
||||
fn function_signature_with_source_map(
|
||||
&self,
|
||||
e: FunctionId,
|
||||
) -> (Arc<FunctionSignature>, Arc<ExpressionStoreSourceMap>);
|
||||
|
||||
#[salsa::invoke(TypeAliasSignature::query)]
|
||||
fn type_alias_signature_with_source_map(
|
||||
&self,
|
||||
e: TypeAliasId,
|
||||
) -> (Arc<TypeAliasSignature>, Arc<ExpressionStoreSourceMap>);
|
||||
|
||||
// endregion:data
|
||||
|
||||
#[salsa::invoke(Body::body_with_source_map_query)]
|
||||
#[salsa::lru(512)]
|
||||
fn body_with_source_map(&self, def: DefWithBodyId) -> (Arc<Body>, Arc<BodySourceMap>);
|
||||
|
||||
#[salsa::invoke(Body::body_query)]
|
||||
fn body(&self, def: DefWithBodyId) -> Arc<Body>;
|
||||
|
||||
#[salsa::invoke(ExprScopes::expr_scopes_query)]
|
||||
fn expr_scopes(&self, def: DefWithBodyId) -> Arc<ExprScopes>;
|
||||
|
||||
#[salsa::transparent]
|
||||
#[salsa::invoke(GenericParams::new)]
|
||||
fn generic_params(&self, def: GenericDefId) -> Arc<GenericParams>;
|
||||
|
||||
#[salsa::transparent]
|
||||
#[salsa::invoke(GenericParams::generic_params_and_store)]
|
||||
fn generic_params_and_store(
|
||||
&self,
|
||||
def: GenericDefId,
|
||||
) -> (Arc<GenericParams>, Arc<ExpressionStore>);
|
||||
|
||||
#[salsa::transparent]
|
||||
#[salsa::invoke(GenericParams::generic_params_and_store_and_source_map)]
|
||||
fn generic_params_and_store_and_source_map(
|
||||
&self,
|
||||
def: GenericDefId,
|
||||
) -> (Arc<GenericParams>, Arc<ExpressionStore>, Arc<ExpressionStoreSourceMap>);
|
||||
|
||||
#[salsa::invoke(ImportMap::import_map_query)]
|
||||
fn import_map(&self, krate: Crate) -> Arc<ImportMap>;
|
||||
|
||||
// region:visibilities
|
||||
|
||||
#[salsa::invoke(visibility::field_visibilities_query)]
|
||||
fn field_visibilities(&self, var: VariantId) -> Arc<ArenaMap<LocalFieldId, Visibility>>;
|
||||
|
||||
#[salsa::invoke(visibility::assoc_visibility_query)]
|
||||
fn assoc_visibility(&self, def: AssocItemId) -> Visibility;
|
||||
|
||||
|
||||
@@ -9,10 +9,7 @@
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
|
||||
use std::{
|
||||
ops::{Deref, Index},
|
||||
sync::LazyLock,
|
||||
};
|
||||
use std::ops::{Deref, Index};
|
||||
|
||||
use cfg::{CfgExpr, CfgOptions};
|
||||
use either::Either;
|
||||
@@ -23,11 +20,10 @@
|
||||
use span::{Edition, SyntaxContext};
|
||||
use syntax::{AstPtr, SyntaxNodePtr, ast};
|
||||
use thin_vec::ThinVec;
|
||||
use triomphe::Arc;
|
||||
use tt::TextRange;
|
||||
|
||||
use crate::{
|
||||
BlockId, SyntheticSyntax,
|
||||
AdtId, BlockId, ExpressionStoreOwnerId, GenericDefId, SyntheticSyntax,
|
||||
db::DefDatabase,
|
||||
expr_store::path::Path,
|
||||
hir::{
|
||||
@@ -35,6 +31,7 @@
|
||||
PatId, RecordFieldPat, RecordSpread, Statement,
|
||||
},
|
||||
nameres::{DefMap, block_def_map},
|
||||
signatures::VariantFields,
|
||||
type_ref::{LifetimeRef, LifetimeRefId, PathId, TypeRef, TypeRefId},
|
||||
};
|
||||
|
||||
@@ -94,9 +91,26 @@ pub(crate) fn is_root(self) -> bool {
|
||||
pub type LifetimePtr = AstPtr<ast::Lifetime>;
|
||||
pub type LifetimeSource = InFile<LifetimePtr>;
|
||||
|
||||
/// Describes where a const expression originated from.
|
||||
///
|
||||
/// Used by signature/body inference to determine the expected type for each
|
||||
/// const expression root.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
pub enum RootExprOrigin {
|
||||
/// Array length expression: `[T; <expr>]` — expected type is `usize`.
|
||||
ArrayLength,
|
||||
/// Const parameter default value: `const N: usize = <expr>`.
|
||||
ConstParam(crate::hir::generics::LocalTypeOrConstParamId),
|
||||
/// Const generic argument in a path: `SomeType::<{ <expr> }>` or `some_fn::<{ <expr> }>()`.
|
||||
/// Determining the expected type requires path resolution, so it is deferred.
|
||||
GenericArgsPath,
|
||||
/// The root expression of a body.
|
||||
BodyRoot,
|
||||
}
|
||||
|
||||
// We split the store into types-only and expressions, because most stores (e.g. generics)
|
||||
// don't store any expressions and this saves memory. Same thing for the source map.
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
struct ExpressionOnlyStore {
|
||||
exprs: Arena<Expr>,
|
||||
pats: Arena<Pat>,
|
||||
@@ -113,9 +127,12 @@ struct ExpressionOnlyStore {
|
||||
/// Expressions (and destructuing patterns) that can be recorded here are single segment path, although not all single segments path refer
|
||||
/// to variables and have hygiene (some refer to items, we don't know at this stage).
|
||||
ident_hygiene: FxHashMap<ExprOrPatId, HygieneId>,
|
||||
|
||||
/// Maps expression roots to their origin.
|
||||
expr_roots: SmallVec<[(ExprId, RootExprOrigin); 1]>,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct ExpressionStore {
|
||||
expr_only: Option<Box<ExpressionOnlyStore>>,
|
||||
pub types: Arena<TypeRef>,
|
||||
@@ -226,6 +243,7 @@ pub struct ExpressionStoreBuilder {
|
||||
pub types: Arena<TypeRef>,
|
||||
block_scopes: Vec<BlockId>,
|
||||
ident_hygiene: FxHashMap<ExprOrPatId, HygieneId>,
|
||||
pub inference_roots: Option<SmallVec<[(ExprId, RootExprOrigin); 1]>>,
|
||||
|
||||
// AST expressions can create patterns in destructuring assignments. Therefore, `ExprSource` can also map
|
||||
// to `PatId`, and `PatId` can also map to `ExprSource` (the other way around is unaffected).
|
||||
@@ -297,6 +315,7 @@ pub fn finish(self) -> (ExpressionStore, ExpressionStoreSourceMap) {
|
||||
mut bindings,
|
||||
mut binding_owners,
|
||||
mut ident_hygiene,
|
||||
inference_roots: mut expr_roots,
|
||||
mut types,
|
||||
mut lifetimes,
|
||||
|
||||
@@ -356,6 +375,9 @@ pub fn finish(self) -> (ExpressionStore, ExpressionStoreSourceMap) {
|
||||
|
||||
let store = {
|
||||
let expr_only = if has_exprs {
|
||||
if let Some(const_expr_origins) = &mut expr_roots {
|
||||
const_expr_origins.shrink_to_fit();
|
||||
}
|
||||
Some(Box::new(ExpressionOnlyStore {
|
||||
exprs,
|
||||
pats,
|
||||
@@ -364,6 +386,7 @@ pub fn finish(self) -> (ExpressionStore, ExpressionStoreSourceMap) {
|
||||
binding_owners,
|
||||
block_scopes: block_scopes.into_boxed_slice(),
|
||||
ident_hygiene,
|
||||
expr_roots: expr_roots.unwrap_or_default(),
|
||||
}))
|
||||
} else {
|
||||
None
|
||||
@@ -404,13 +427,108 @@ pub fn finish(self) -> (ExpressionStore, ExpressionStoreSourceMap) {
|
||||
}
|
||||
|
||||
impl ExpressionStore {
|
||||
pub fn empty_singleton() -> (Arc<ExpressionStore>, Arc<ExpressionStoreSourceMap>) {
|
||||
static EMPTY: LazyLock<(Arc<ExpressionStore>, Arc<ExpressionStoreSourceMap>)> =
|
||||
LazyLock::new(|| {
|
||||
let (store, source_map) = ExpressionStoreBuilder::default().finish();
|
||||
(Arc::new(store), Arc::new(source_map))
|
||||
});
|
||||
EMPTY.clone()
|
||||
pub fn of(db: &dyn DefDatabase, def: ExpressionStoreOwnerId) -> &ExpressionStore {
|
||||
match def {
|
||||
ExpressionStoreOwnerId::Signature(def) => {
|
||||
use crate::signatures::{
|
||||
ConstSignature, EnumSignature, FunctionSignature, ImplSignature,
|
||||
StaticSignature, StructSignature, TraitSignature, TypeAliasSignature,
|
||||
UnionSignature,
|
||||
};
|
||||
match def {
|
||||
GenericDefId::AdtId(AdtId::EnumId(id)) => &EnumSignature::of(db, id).store,
|
||||
GenericDefId::AdtId(AdtId::StructId(id)) => &StructSignature::of(db, id).store,
|
||||
GenericDefId::AdtId(AdtId::UnionId(id)) => &UnionSignature::of(db, id).store,
|
||||
GenericDefId::ConstId(id) => &ConstSignature::of(db, id).store,
|
||||
GenericDefId::FunctionId(id) => &FunctionSignature::of(db, id).store,
|
||||
GenericDefId::ImplId(id) => &ImplSignature::of(db, id).store,
|
||||
GenericDefId::StaticId(id) => &StaticSignature::of(db, id).store,
|
||||
GenericDefId::TraitId(id) => &TraitSignature::of(db, id).store,
|
||||
GenericDefId::TypeAliasId(id) => &TypeAliasSignature::of(db, id).store,
|
||||
}
|
||||
}
|
||||
ExpressionStoreOwnerId::Body(body) => &Body::of(db, body).store,
|
||||
ExpressionStoreOwnerId::VariantFields(variant_id) => {
|
||||
&VariantFields::of(db, variant_id).store
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with_source_map(
|
||||
db: &dyn DefDatabase,
|
||||
def: ExpressionStoreOwnerId,
|
||||
) -> (&ExpressionStore, &ExpressionStoreSourceMap) {
|
||||
match def {
|
||||
ExpressionStoreOwnerId::Signature(def) => {
|
||||
use crate::signatures::{
|
||||
ConstSignature, EnumSignature, FunctionSignature, ImplSignature,
|
||||
StaticSignature, StructSignature, TraitSignature, TypeAliasSignature,
|
||||
UnionSignature,
|
||||
};
|
||||
match def {
|
||||
GenericDefId::AdtId(AdtId::EnumId(id)) => {
|
||||
let sig = EnumSignature::with_source_map(db, id);
|
||||
(&sig.0.store, &sig.1)
|
||||
}
|
||||
GenericDefId::AdtId(AdtId::StructId(id)) => {
|
||||
let sig = StructSignature::with_source_map(db, id);
|
||||
(&sig.0.store, &sig.1)
|
||||
}
|
||||
GenericDefId::AdtId(AdtId::UnionId(id)) => {
|
||||
let sig = UnionSignature::with_source_map(db, id);
|
||||
(&sig.0.store, &sig.1)
|
||||
}
|
||||
GenericDefId::ConstId(id) => {
|
||||
let sig = ConstSignature::with_source_map(db, id);
|
||||
(&sig.0.store, &sig.1)
|
||||
}
|
||||
GenericDefId::FunctionId(id) => {
|
||||
let sig = FunctionSignature::with_source_map(db, id);
|
||||
(&sig.0.store, &sig.1)
|
||||
}
|
||||
GenericDefId::ImplId(id) => {
|
||||
let sig = ImplSignature::with_source_map(db, id);
|
||||
(&sig.0.store, &sig.1)
|
||||
}
|
||||
GenericDefId::StaticId(id) => {
|
||||
let sig = StaticSignature::with_source_map(db, id);
|
||||
(&sig.0.store, &sig.1)
|
||||
}
|
||||
GenericDefId::TraitId(id) => {
|
||||
let sig = TraitSignature::with_source_map(db, id);
|
||||
(&sig.0.store, &sig.1)
|
||||
}
|
||||
GenericDefId::TypeAliasId(id) => {
|
||||
let sig = TypeAliasSignature::with_source_map(db, id);
|
||||
(&sig.0.store, &sig.1)
|
||||
}
|
||||
}
|
||||
}
|
||||
ExpressionStoreOwnerId::Body(body) => {
|
||||
let (store, sm) = Body::with_source_map(db, body);
|
||||
(&store.store, &sm.store)
|
||||
}
|
||||
ExpressionStoreOwnerId::VariantFields(variant_id) => {
|
||||
let (store, sm) = VariantFields::with_source_map(db, variant_id);
|
||||
(&store.store, sm)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns all expression root `ExprId`s found in this store.
|
||||
pub fn expr_roots(&self) -> impl Iterator<Item = ExprId> {
|
||||
self.const_expr_origins().iter().map(|&(id, _)| id)
|
||||
}
|
||||
|
||||
/// Like [`Self::signature_const_expr_roots`], but also returns the origin
|
||||
/// of each expression.
|
||||
pub fn expr_roots_with_origins(&self) -> impl Iterator<Item = (ExprId, RootExprOrigin)> {
|
||||
self.const_expr_origins().iter().map(|&(id, origin)| (id, origin))
|
||||
}
|
||||
|
||||
/// Returns the map of const expression roots to their origins.
|
||||
pub fn const_expr_origins(&self) -> &[(ExprId, RootExprOrigin)] {
|
||||
self.expr_only.as_ref().map_or(&[], |it| &it.expr_roots)
|
||||
}
|
||||
|
||||
/// Returns an iterator over all block expressions in this store that define inner items.
|
||||
|
||||
@@ -29,8 +29,6 @@ pub struct Body {
|
||||
/// empty.
|
||||
pub params: Box<[PatId]>,
|
||||
pub self_param: Option<BindingId>,
|
||||
/// The `ExprId` of the actual body expression.
|
||||
pub body_expr: ExprId,
|
||||
}
|
||||
|
||||
impl ops::Deref for Body {
|
||||
@@ -68,11 +66,10 @@ fn deref(&self) -> &Self::Target {
|
||||
}
|
||||
}
|
||||
|
||||
#[salsa::tracked]
|
||||
impl Body {
|
||||
pub(crate) fn body_with_source_map_query(
|
||||
db: &dyn DefDatabase,
|
||||
def: DefWithBodyId,
|
||||
) -> (Arc<Body>, Arc<BodySourceMap>) {
|
||||
#[salsa::tracked(lru = 512, returns(ref))]
|
||||
pub fn with_source_map(db: &dyn DefDatabase, def: DefWithBodyId) -> (Arc<Body>, BodySourceMap) {
|
||||
let _p = tracing::info_span!("body_with_source_map_query").entered();
|
||||
let mut params = None;
|
||||
|
||||
@@ -99,18 +96,25 @@ pub(crate) fn body_with_source_map_query(
|
||||
DefWithBodyId::VariantId(v) => {
|
||||
let s = v.lookup(db);
|
||||
let src = s.source(db);
|
||||
src.map(|it| it.expr())
|
||||
src.map(|it| it.const_arg()?.expr())
|
||||
}
|
||||
}
|
||||
};
|
||||
let module = def.module(db);
|
||||
let (body, source_map) = lower_body(db, def, file_id, module, params, body, is_async_fn);
|
||||
|
||||
(Arc::new(body), Arc::new(source_map))
|
||||
(Arc::new(body), source_map)
|
||||
}
|
||||
|
||||
pub(crate) fn body_query(db: &dyn DefDatabase, def: DefWithBodyId) -> Arc<Body> {
|
||||
db.body_with_source_map(def).0
|
||||
#[salsa::tracked(returns(deref))]
|
||||
pub fn of(db: &dyn DefDatabase, def: DefWithBodyId) -> Arc<Body> {
|
||||
Self::with_source_map(db, def).0.clone()
|
||||
}
|
||||
}
|
||||
|
||||
impl Body {
|
||||
pub fn root_expr(&self) -> ExprId {
|
||||
self.store.expr_roots().next().unwrap()
|
||||
}
|
||||
|
||||
pub fn pretty_print(
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
use span::{AstIdMap, SyntaxContext};
|
||||
use syntax::ast::HasAttrs;
|
||||
use syntax::{AstNode, Parse, ast};
|
||||
use triomphe::Arc;
|
||||
use tt::TextRange;
|
||||
|
||||
use crate::{
|
||||
@@ -23,21 +22,21 @@
|
||||
};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(super) struct Expander {
|
||||
pub(super) struct Expander<'db> {
|
||||
span_map: SpanMap,
|
||||
current_file_id: HirFileId,
|
||||
ast_id_map: Arc<AstIdMap>,
|
||||
ast_id_map: &'db AstIdMap,
|
||||
/// `recursion_depth == usize::MAX` indicates that the recursion limit has been reached.
|
||||
recursion_depth: u32,
|
||||
recursion_limit: usize,
|
||||
}
|
||||
|
||||
impl Expander {
|
||||
impl<'db> Expander<'db> {
|
||||
pub(super) fn new(
|
||||
db: &dyn DefDatabase,
|
||||
db: &'db dyn DefDatabase,
|
||||
current_file_id: HirFileId,
|
||||
def_map: &DefMap,
|
||||
) -> Expander {
|
||||
def_map: &'db DefMap,
|
||||
) -> Expander<'db> {
|
||||
let recursion_limit = def_map.recursion_limit() as usize;
|
||||
let recursion_limit = if cfg!(test) {
|
||||
// Without this, `body::tests::your_stack_belongs_to_me` stack-overflows in debug
|
||||
@@ -77,12 +76,12 @@ pub(super) fn is_cfg_enabled(
|
||||
|
||||
pub(super) fn enter_expand<T: ast::AstNode>(
|
||||
&mut self,
|
||||
db: &dyn DefDatabase,
|
||||
db: &'db dyn DefDatabase,
|
||||
macro_call: ast::MacroCall,
|
||||
krate: Crate,
|
||||
resolver: impl Fn(&ModPath) -> Option<MacroId>,
|
||||
eager_callback: EagerCallBackFn<'_>,
|
||||
) -> Result<ExpandResult<Option<(Mark, Option<Parse<T>>)>>, UnresolvedMacro> {
|
||||
) -> Result<ExpandResult<Option<(Mark<'db>, Option<Parse<T>>)>>, UnresolvedMacro> {
|
||||
// FIXME: within_limit should support this, instead of us having to extract the error
|
||||
let mut unresolved_macro_err = None;
|
||||
|
||||
@@ -130,13 +129,13 @@ pub(super) fn enter_expand<T: ast::AstNode>(
|
||||
|
||||
pub(super) fn enter_expand_id<T: ast::AstNode>(
|
||||
&mut self,
|
||||
db: &dyn DefDatabase,
|
||||
db: &'db dyn DefDatabase,
|
||||
call_id: MacroCallId,
|
||||
) -> ExpandResult<Option<(Mark, Option<Parse<T>>)>> {
|
||||
) -> ExpandResult<Option<(Mark<'db>, Option<Parse<T>>)>> {
|
||||
self.within_limit(db, |_this| ExpandResult::ok(Some(call_id)))
|
||||
}
|
||||
|
||||
pub(super) fn exit(&mut self, Mark { file_id, span_map, ast_id_map, mut bomb }: Mark) {
|
||||
pub(super) fn exit(&mut self, Mark { file_id, span_map, ast_id_map, mut bomb }: Mark<'db>) {
|
||||
self.span_map = span_map;
|
||||
self.current_file_id = file_id;
|
||||
self.ast_id_map = ast_id_map;
|
||||
@@ -162,9 +161,9 @@ pub(super) fn current_file_id(&self) -> HirFileId {
|
||||
|
||||
fn within_limit<F, T: ast::AstNode>(
|
||||
&mut self,
|
||||
db: &dyn DefDatabase,
|
||||
db: &'db dyn DefDatabase,
|
||||
op: F,
|
||||
) -> ExpandResult<Option<(Mark, Option<Parse<T>>)>>
|
||||
) -> ExpandResult<Option<(Mark<'db>, Option<Parse<T>>)>>
|
||||
where
|
||||
F: FnOnce(&mut Self) -> ExpandResult<Option<MacroCallId>>,
|
||||
{
|
||||
@@ -219,7 +218,7 @@ fn within_limit<F, T: ast::AstNode>(
|
||||
|
||||
#[inline]
|
||||
pub(super) fn ast_id_map(&self) -> &AstIdMap {
|
||||
&self.ast_id_map
|
||||
self.ast_id_map
|
||||
}
|
||||
|
||||
#[inline]
|
||||
@@ -229,9 +228,9 @@ pub(super) fn span_map(&self) -> SpanMapRef<'_> {
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(super) struct Mark {
|
||||
pub(super) struct Mark<'db> {
|
||||
file_id: HirFileId,
|
||||
span_map: SpanMap,
|
||||
ast_id_map: Arc<AstIdMap>,
|
||||
ast_id_map: &'db AstIdMap,
|
||||
bomb: DropBomb,
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
};
|
||||
use intern::{Symbol, sym};
|
||||
use rustc_hash::FxHashMap;
|
||||
use smallvec::smallvec;
|
||||
use stdx::never;
|
||||
use syntax::{
|
||||
AstNode, AstPtr, SyntaxNodePtr,
|
||||
@@ -28,7 +29,6 @@
|
||||
},
|
||||
};
|
||||
use thin_vec::ThinVec;
|
||||
use triomphe::Arc;
|
||||
use tt::TextRange;
|
||||
|
||||
use crate::{
|
||||
@@ -39,7 +39,7 @@
|
||||
expr_store::{
|
||||
Body, BodySourceMap, ExprPtr, ExpressionStore, ExpressionStoreBuilder,
|
||||
ExpressionStoreDiagnostics, ExpressionStoreSourceMap, HygieneId, LabelPtr, LifetimePtr,
|
||||
PatPtr, TypePtr,
|
||||
PatPtr, RootExprOrigin, TypePtr,
|
||||
expander::Expander,
|
||||
lower::generics::ImplTraitLowerFn,
|
||||
path::{AssociatedTypeBinding, GenericArg, GenericArgs, GenericArgsParentheses, Path},
|
||||
@@ -53,6 +53,7 @@
|
||||
item_tree::FieldsShape,
|
||||
lang_item::{LangItemTarget, LangItems},
|
||||
nameres::{DefMap, LocalDefMap, MacroSubNs, block_def_map},
|
||||
signatures::StructSignature,
|
||||
type_ref::{
|
||||
ArrayType, ConstRef, FnType, LifetimeRef, LifetimeRefId, Mutability, PathId, Rawness,
|
||||
RefType, TraitBoundModifier, TraitRef, TypeBound, TypeRef, TypeRefId, UseArgRef,
|
||||
@@ -79,7 +80,7 @@ pub(super) fn lower_body(
|
||||
let mut self_param = None;
|
||||
let mut source_map_self_param = None;
|
||||
let mut params = vec![];
|
||||
let mut collector = ExprCollector::new(db, module, current_file_id);
|
||||
let mut collector = ExprCollector::body(db, module, current_file_id);
|
||||
|
||||
let skip_body = AttrFlags::query(
|
||||
db,
|
||||
@@ -117,9 +118,10 @@ pub(super) fn lower_body(
|
||||
params = (0..count).map(|_| collector.missing_pat()).collect();
|
||||
};
|
||||
let body_expr = collector.missing_expr();
|
||||
collector.store.inference_roots = Some(smallvec![(body_expr, RootExprOrigin::BodyRoot)]);
|
||||
let (store, source_map) = collector.store.finish();
|
||||
return (
|
||||
Body { store, params: params.into_boxed_slice(), self_param, body_expr },
|
||||
Body { store, params: params.into_boxed_slice(), self_param },
|
||||
BodySourceMap { self_param: source_map_self_param, store: source_map },
|
||||
);
|
||||
}
|
||||
@@ -173,10 +175,11 @@ pub(super) fn lower_body(
|
||||
}
|
||||
},
|
||||
);
|
||||
collector.store.inference_roots = Some(smallvec![(body_expr, RootExprOrigin::BodyRoot)]);
|
||||
|
||||
let (store, source_map) = collector.store.finish();
|
||||
(
|
||||
Body { store, params: params.into_boxed_slice(), self_param, body_expr },
|
||||
Body { store, params: params.into_boxed_slice(), self_param },
|
||||
BodySourceMap { self_param: source_map_self_param, store: source_map },
|
||||
)
|
||||
}
|
||||
@@ -186,7 +189,7 @@ pub(crate) fn lower_type_ref(
|
||||
module: ModuleId,
|
||||
type_ref: InFile<Option<ast::Type>>,
|
||||
) -> (ExpressionStore, ExpressionStoreSourceMap, TypeRefId) {
|
||||
let mut expr_collector = ExprCollector::new(db, module, type_ref.file_id);
|
||||
let mut expr_collector = ExprCollector::signature(db, module, type_ref.file_id);
|
||||
let type_ref =
|
||||
expr_collector.lower_type_ref_opt(type_ref.value, &mut ExprCollector::impl_trait_allocator);
|
||||
let (store, source_map) = expr_collector.store.finish();
|
||||
@@ -200,13 +203,13 @@ pub(crate) fn lower_generic_params(
|
||||
file_id: HirFileId,
|
||||
param_list: Option<ast::GenericParamList>,
|
||||
where_clause: Option<ast::WhereClause>,
|
||||
) -> (Arc<ExpressionStore>, Arc<GenericParams>, ExpressionStoreSourceMap) {
|
||||
let mut expr_collector = ExprCollector::new(db, module, file_id);
|
||||
) -> (ExpressionStore, GenericParams, ExpressionStoreSourceMap) {
|
||||
let mut expr_collector = ExprCollector::signature(db, module, file_id);
|
||||
let mut collector = generics::GenericParamsCollector::new(def);
|
||||
collector.lower(&mut expr_collector, param_list, where_clause);
|
||||
let params = collector.finish();
|
||||
let (store, source_map) = expr_collector.store.finish();
|
||||
(Arc::new(store), params, source_map)
|
||||
(store, params, source_map)
|
||||
}
|
||||
|
||||
pub(crate) fn lower_impl(
|
||||
@@ -214,8 +217,8 @@ pub(crate) fn lower_impl(
|
||||
module: ModuleId,
|
||||
impl_syntax: InFile<ast::Impl>,
|
||||
impl_id: ImplId,
|
||||
) -> (ExpressionStore, ExpressionStoreSourceMap, TypeRefId, Option<TraitRef>, Arc<GenericParams>) {
|
||||
let mut expr_collector = ExprCollector::new(db, module, impl_syntax.file_id);
|
||||
) -> (ExpressionStore, ExpressionStoreSourceMap, TypeRefId, Option<TraitRef>, GenericParams) {
|
||||
let mut expr_collector = ExprCollector::signature(db, module, impl_syntax.file_id);
|
||||
let self_ty =
|
||||
expr_collector.lower_type_ref_opt_disallow_impl_trait(impl_syntax.value.self_ty());
|
||||
let trait_ = impl_syntax.value.trait_().and_then(|it| match &it {
|
||||
@@ -242,8 +245,8 @@ pub(crate) fn lower_trait(
|
||||
module: ModuleId,
|
||||
trait_syntax: InFile<ast::Trait>,
|
||||
trait_id: TraitId,
|
||||
) -> (ExpressionStore, ExpressionStoreSourceMap, Arc<GenericParams>) {
|
||||
let mut expr_collector = ExprCollector::new(db, module, trait_syntax.file_id);
|
||||
) -> (ExpressionStore, ExpressionStoreSourceMap, GenericParams) {
|
||||
let mut expr_collector = ExprCollector::signature(db, module, trait_syntax.file_id);
|
||||
let mut collector = generics::GenericParamsCollector::with_self_param(
|
||||
&mut expr_collector,
|
||||
trait_id.into(),
|
||||
@@ -264,14 +267,9 @@ pub(crate) fn lower_type_alias(
|
||||
module: ModuleId,
|
||||
alias: InFile<ast::TypeAlias>,
|
||||
type_alias_id: TypeAliasId,
|
||||
) -> (
|
||||
ExpressionStore,
|
||||
ExpressionStoreSourceMap,
|
||||
Arc<GenericParams>,
|
||||
Box<[TypeBound]>,
|
||||
Option<TypeRefId>,
|
||||
) {
|
||||
let mut expr_collector = ExprCollector::new(db, module, alias.file_id);
|
||||
) -> (ExpressionStore, ExpressionStoreSourceMap, GenericParams, Box<[TypeBound]>, Option<TypeRefId>)
|
||||
{
|
||||
let mut expr_collector = ExprCollector::signature(db, module, alias.file_id);
|
||||
let bounds = alias
|
||||
.value
|
||||
.type_bound_list()
|
||||
@@ -307,13 +305,13 @@ pub(crate) fn lower_function(
|
||||
) -> (
|
||||
ExpressionStore,
|
||||
ExpressionStoreSourceMap,
|
||||
Arc<GenericParams>,
|
||||
GenericParams,
|
||||
Box<[TypeRefId]>,
|
||||
Option<TypeRefId>,
|
||||
bool,
|
||||
bool,
|
||||
) {
|
||||
let mut expr_collector = ExprCollector::new(db, module, fn_.file_id);
|
||||
let mut expr_collector = ExprCollector::signature(db, module, fn_.file_id);
|
||||
let mut collector = generics::GenericParamsCollector::new(function_id.into());
|
||||
collector.lower(&mut expr_collector, fn_.value.generic_param_list(), fn_.value.where_clause());
|
||||
let mut params = vec![];
|
||||
@@ -419,7 +417,7 @@ pub(crate) fn lower_function(
|
||||
pub struct ExprCollector<'db> {
|
||||
db: &'db dyn DefDatabase,
|
||||
cfg_options: &'db CfgOptions,
|
||||
expander: Expander,
|
||||
expander: Expander<'db>,
|
||||
def_map: &'db DefMap,
|
||||
local_def_map: &'db LocalDefMap,
|
||||
module: ModuleId,
|
||||
@@ -532,7 +530,20 @@ fn check_is_used(&mut self, ec: &mut ExprCollector<'_>, id: BindingId) {
|
||||
}
|
||||
|
||||
impl<'db> ExprCollector<'db> {
|
||||
pub fn new(
|
||||
/// Creates a collector for a signature store, this will populate `const_expr_origins` to any
|
||||
/// top level const arg roots.
|
||||
pub fn signature(
|
||||
db: &dyn DefDatabase,
|
||||
module: ModuleId,
|
||||
current_file_id: HirFileId,
|
||||
) -> ExprCollector<'_> {
|
||||
let mut this = Self::body(db, module, current_file_id);
|
||||
this.store.inference_roots = Some(Default::default());
|
||||
this
|
||||
}
|
||||
|
||||
/// Creates a collector for a bidy store.
|
||||
pub fn body(
|
||||
db: &dyn DefDatabase,
|
||||
module: ModuleId,
|
||||
current_file_id: HirFileId,
|
||||
@@ -577,7 +588,10 @@ pub(crate) fn span_map(&self) -> SpanMapRef<'_> {
|
||||
self.expander.span_map()
|
||||
}
|
||||
|
||||
pub fn lower_lifetime_ref(&mut self, lifetime: ast::Lifetime) -> LifetimeRefId {
|
||||
pub(in crate::expr_store) fn lower_lifetime_ref(
|
||||
&mut self,
|
||||
lifetime: ast::Lifetime,
|
||||
) -> LifetimeRefId {
|
||||
// FIXME: Keyword check?
|
||||
let lifetime_ref = match &*lifetime.text() {
|
||||
"" | "'" => LifetimeRef::Error,
|
||||
@@ -588,7 +602,10 @@ pub fn lower_lifetime_ref(&mut self, lifetime: ast::Lifetime) -> LifetimeRefId {
|
||||
self.alloc_lifetime_ref(lifetime_ref, AstPtr::new(&lifetime))
|
||||
}
|
||||
|
||||
pub fn lower_lifetime_ref_opt(&mut self, lifetime: Option<ast::Lifetime>) -> LifetimeRefId {
|
||||
pub(in crate::expr_store) fn lower_lifetime_ref_opt(
|
||||
&mut self,
|
||||
lifetime: Option<ast::Lifetime>,
|
||||
) -> LifetimeRefId {
|
||||
match lifetime {
|
||||
Some(lifetime) => self.lower_lifetime_ref(lifetime),
|
||||
None => self.alloc_lifetime_ref_desugared(LifetimeRef::Placeholder),
|
||||
@@ -596,7 +613,7 @@ pub fn lower_lifetime_ref_opt(&mut self, lifetime: Option<ast::Lifetime>) -> Lif
|
||||
}
|
||||
|
||||
/// Converts an `ast::TypeRef` to a `hir::TypeRef`.
|
||||
pub fn lower_type_ref(
|
||||
pub(in crate::expr_store) fn lower_type_ref(
|
||||
&mut self,
|
||||
node: ast::Type,
|
||||
impl_trait_lower_fn: ImplTraitLowerFn<'_>,
|
||||
@@ -621,6 +638,9 @@ pub fn lower_type_ref(
|
||||
}
|
||||
ast::Type::ArrayType(inner) => {
|
||||
let len = self.lower_const_arg_opt(inner.const_arg());
|
||||
if let Some(const_expr_origins) = &mut self.store.inference_roots {
|
||||
const_expr_origins.push((len.expr, RootExprOrigin::ArrayLength));
|
||||
}
|
||||
TypeRef::Array(ArrayType {
|
||||
ty: self.lower_type_ref_opt(inner.ty(), impl_trait_lower_fn),
|
||||
len,
|
||||
@@ -810,7 +830,7 @@ fn alloc_path(&mut self, path: Path, node: TypePtr) -> PathId {
|
||||
|
||||
/// Collect `GenericArgs` from the parts of a fn-like path, i.e. `Fn(X, Y)
|
||||
/// -> Z` (which desugars to `Fn<(X, Y), Output=Z>`).
|
||||
pub fn lower_generic_args_from_fn_path(
|
||||
pub(in crate::expr_store) fn lower_generic_args_from_fn_path(
|
||||
&mut self,
|
||||
args: Option<ast::ParenthesizedArgList>,
|
||||
ret_type: Option<ast::RetType>,
|
||||
@@ -905,6 +925,9 @@ pub(super) fn lower_generic_args(
|
||||
}
|
||||
ast::GenericArg::ConstArg(arg) => {
|
||||
let arg = self.lower_const_arg(arg);
|
||||
if let Some(const_expr_origins) = &mut self.store.inference_roots {
|
||||
const_expr_origins.push((arg.expr, RootExprOrigin::GenericArgsPath));
|
||||
}
|
||||
args.push(GenericArg::Const(arg))
|
||||
}
|
||||
}
|
||||
@@ -1045,17 +1068,30 @@ fn lower_type_bound(
|
||||
}
|
||||
|
||||
fn lower_const_arg_opt(&mut self, arg: Option<ast::ConstArg>) -> ConstRef {
|
||||
ConstRef { expr: self.collect_expr_opt(arg.and_then(|it| it.expr())) }
|
||||
let const_expr_origins = self.store.inference_roots.take();
|
||||
let r = ConstRef { expr: self.collect_expr_opt(arg.and_then(|it| it.expr())) };
|
||||
self.store.inference_roots = const_expr_origins;
|
||||
r
|
||||
}
|
||||
|
||||
fn lower_const_arg(&mut self, arg: ast::ConstArg) -> ConstRef {
|
||||
ConstRef { expr: self.collect_expr_opt(arg.expr()) }
|
||||
pub fn lower_const_arg(&mut self, arg: ast::ConstArg) -> ConstRef {
|
||||
let const_expr_origins = self.store.inference_roots.take();
|
||||
let r = ConstRef { expr: self.collect_expr_opt(arg.expr()) };
|
||||
self.store.inference_roots = const_expr_origins;
|
||||
r
|
||||
}
|
||||
|
||||
fn collect_expr(&mut self, expr: ast::Expr) -> ExprId {
|
||||
self.maybe_collect_expr(expr).unwrap_or_else(|| self.missing_expr())
|
||||
}
|
||||
|
||||
pub(in crate::expr_store) fn collect_expr_opt(&mut self, expr: Option<ast::Expr>) -> ExprId {
|
||||
match expr {
|
||||
Some(expr) => self.collect_expr(expr),
|
||||
None => self.missing_expr(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns `None` if and only if the expression is `#[cfg]`d out.
|
||||
fn maybe_collect_expr(&mut self, expr: ast::Expr) -> Option<ExprId> {
|
||||
let syntax_ptr = AstPtr::new(&expr);
|
||||
@@ -2065,13 +2101,6 @@ fn collect_macro_call<T, U>(
|
||||
}
|
||||
}
|
||||
|
||||
pub fn collect_expr_opt(&mut self, expr: Option<ast::Expr>) -> ExprId {
|
||||
match expr {
|
||||
Some(expr) => self.collect_expr(expr),
|
||||
None => self.missing_expr(),
|
||||
}
|
||||
}
|
||||
|
||||
fn collect_macro_as_stmt(
|
||||
&mut self,
|
||||
statements: &mut Vec<Statement>,
|
||||
@@ -2332,7 +2361,7 @@ fn collect_pat(&mut self, pat: ast::Pat, binding_list: &mut BindingList) -> PatI
|
||||
}
|
||||
Some(ModuleDefId::AdtId(AdtId::StructId(s)))
|
||||
// FIXME: This can cause a cycle if the user is writing invalid code
|
||||
if self.db.struct_signature(s).shape != FieldsShape::Record =>
|
||||
if StructSignature::of(self.db, s).shape != FieldsShape::Record =>
|
||||
{
|
||||
(None, Pat::Path(name.into()))
|
||||
}
|
||||
|
||||
@@ -3,15 +3,12 @@
|
||||
//! generic parameters. See also the `Generics` type and the `generics_of` query
|
||||
//! in rustc.
|
||||
|
||||
use std::sync::LazyLock;
|
||||
|
||||
use either::Either;
|
||||
use hir_expand::name::{AsName, Name};
|
||||
use intern::sym;
|
||||
use la_arena::Arena;
|
||||
use syntax::ast::{self, HasName, HasTypeBounds};
|
||||
use thin_vec::ThinVec;
|
||||
use triomphe::Arc;
|
||||
|
||||
use crate::{
|
||||
GenericDefId, TypeOrConstParamId, TypeParamId,
|
||||
@@ -84,28 +81,16 @@ pub(crate) fn collect_impl_trait<R>(
|
||||
)
|
||||
}
|
||||
|
||||
pub(crate) fn finish(self) -> Arc<GenericParams> {
|
||||
let Self { mut lifetimes, mut type_or_consts, mut where_predicates, parent: _ } = self;
|
||||
|
||||
if lifetimes.is_empty() && type_or_consts.is_empty() && where_predicates.is_empty() {
|
||||
static EMPTY: LazyLock<Arc<GenericParams>> = LazyLock::new(|| {
|
||||
Arc::new(GenericParams {
|
||||
lifetimes: Arena::new(),
|
||||
type_or_consts: Arena::new(),
|
||||
where_predicates: Box::default(),
|
||||
})
|
||||
});
|
||||
return Arc::clone(&EMPTY);
|
||||
}
|
||||
pub(crate) fn finish(self) -> GenericParams {
|
||||
let Self { mut lifetimes, mut type_or_consts, where_predicates, parent: _ } = self;
|
||||
|
||||
lifetimes.shrink_to_fit();
|
||||
type_or_consts.shrink_to_fit();
|
||||
where_predicates.shrink_to_fit();
|
||||
Arc::new(GenericParams {
|
||||
GenericParams {
|
||||
type_or_consts,
|
||||
lifetimes,
|
||||
where_predicates: where_predicates.into_boxed_slice(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
fn lower_param_list(&mut self, ec: &mut ExprCollector<'_>, params: ast::GenericParamList) {
|
||||
@@ -141,12 +126,17 @@ fn lower_param_list(&mut self, ec: &mut ExprCollector<'_>, params: ast::GenericP
|
||||
const_param.ty(),
|
||||
&mut ExprCollector::impl_trait_error_allocator,
|
||||
);
|
||||
let param = ConstParamData {
|
||||
name,
|
||||
ty,
|
||||
default: const_param.default_val().map(|it| ec.lower_const_arg(it)),
|
||||
};
|
||||
let _idx = self.type_or_consts.alloc(param.into());
|
||||
let default = const_param.default_val().map(|it| ec.lower_const_arg(it));
|
||||
let param = ConstParamData { name, ty, default };
|
||||
let idx = self.type_or_consts.alloc(param.into());
|
||||
if let Some(default) = default
|
||||
&& let Some(const_expr_origins) = &mut ec.store.inference_roots
|
||||
{
|
||||
const_expr_origins.push((
|
||||
default.expr,
|
||||
crate::expr_store::RootExprOrigin::ConstParam(idx),
|
||||
));
|
||||
}
|
||||
}
|
||||
ast::GenericParam::LifetimeParam(lifetime_param) => {
|
||||
let lifetime = ec.lower_lifetime_ref_opt(lifetime_param.lifetime());
|
||||
|
||||
@@ -21,7 +21,7 @@ fn lower_path(path: ast::Path) -> (TestDB, ExpressionStore, Option<Path>) {
|
||||
let (db, file_id) = TestDB::with_single_file("");
|
||||
let krate = db.fetch_test_crate();
|
||||
let mut ctx =
|
||||
ExprCollector::new(&db, crate_def_map(&db, krate).root_module_id(), file_id.into());
|
||||
ExprCollector::signature(&db, crate_def_map(&db, krate).root_module_id(), file_id.into());
|
||||
let lowered_path = ctx.lower_path(path, &mut ExprCollector::impl_trait_allocator);
|
||||
let (store, _) = ctx.store.finish();
|
||||
(db, store, lowered_path)
|
||||
|
||||
@@ -105,7 +105,7 @@ pub fn print_body_hir(
|
||||
p.buf.push(')');
|
||||
p.buf.push(' ');
|
||||
}
|
||||
p.print_expr(body.body_expr);
|
||||
p.print_expr(body.root_expr());
|
||||
if matches!(owner, DefWithBodyId::StaticId(_) | DefWithBodyId::ConstId(_)) {
|
||||
p.buf.push(';');
|
||||
}
|
||||
@@ -168,8 +168,8 @@ pub fn print_signature(db: &dyn DefDatabase, owner: GenericDefId, edition: Editi
|
||||
match owner {
|
||||
GenericDefId::AdtId(id) => match id {
|
||||
AdtId::StructId(id) => {
|
||||
let signature = db.struct_signature(id);
|
||||
print_struct(db, id, &signature, edition)
|
||||
let signature = StructSignature::of(db, id);
|
||||
print_struct(db, id, signature, edition)
|
||||
}
|
||||
AdtId::UnionId(id) => {
|
||||
format!("unimplemented {id:?}")
|
||||
@@ -180,8 +180,8 @@ pub fn print_signature(db: &dyn DefDatabase, owner: GenericDefId, edition: Editi
|
||||
},
|
||||
GenericDefId::ConstId(id) => format!("unimplemented {id:?}"),
|
||||
GenericDefId::FunctionId(id) => {
|
||||
let signature = db.function_signature(id);
|
||||
print_function(db, id, &signature, edition)
|
||||
let signature = FunctionSignature::of(db, id);
|
||||
print_function(db, id, signature, edition)
|
||||
}
|
||||
GenericDefId::ImplId(id) => format!("unimplemented {id:?}"),
|
||||
GenericDefId::StaticId(id) => format!("unimplemented {id:?}"),
|
||||
@@ -1212,7 +1212,7 @@ pub(crate) fn print_generic_arg(&mut self, arg: &GenericArg) {
|
||||
}
|
||||
|
||||
pub(crate) fn print_type_param(&mut self, param: TypeParamId) {
|
||||
let generic_params = self.db.generic_params(param.parent());
|
||||
let generic_params = GenericParams::of(self.db, param.parent());
|
||||
|
||||
match generic_params[param.local_id()].name() {
|
||||
Some(name) => w!(self, "{}", name.display(self.db, self.edition)),
|
||||
@@ -1221,7 +1221,7 @@ pub(crate) fn print_type_param(&mut self, param: TypeParamId) {
|
||||
}
|
||||
|
||||
pub(crate) fn print_lifetime_param(&mut self, param: LifetimeParamId) {
|
||||
let generic_params = self.db.generic_params(param.parent);
|
||||
let generic_params = GenericParams::of(self.db, param.parent);
|
||||
w!(self, "{}", generic_params[param.local_id].name.display(self.db, self.edition))
|
||||
}
|
||||
|
||||
|
||||
@@ -1,13 +1,16 @@
|
||||
//! Name resolution for expressions.
|
||||
use hir_expand::{MacroDefId, name::Name};
|
||||
use la_arena::{Arena, ArenaMap, Idx, IdxRange, RawIdx};
|
||||
use triomphe::Arc;
|
||||
|
||||
use crate::{
|
||||
BlockId, DefWithBodyId,
|
||||
BlockId, DefWithBodyId, ExpressionStoreOwnerId, GenericDefId, VariantId,
|
||||
db::DefDatabase,
|
||||
expr_store::{Body, ExpressionStore, HygieneId},
|
||||
hir::{Binding, BindingId, Expr, ExprId, Item, LabelId, Pat, PatId, Statement},
|
||||
hir::{
|
||||
Binding, BindingId, Expr, ExprId, Item, LabelId, Pat, PatId, Statement,
|
||||
generics::GenericParams,
|
||||
},
|
||||
signatures::VariantFields,
|
||||
};
|
||||
|
||||
pub type ScopeId = Idx<ScopeData>;
|
||||
@@ -50,12 +53,45 @@ pub struct ScopeData {
|
||||
entries: IdxRange<ScopeEntry>,
|
||||
}
|
||||
|
||||
#[salsa::tracked]
|
||||
impl ExprScopes {
|
||||
pub(crate) fn expr_scopes_query(db: &dyn DefDatabase, def: DefWithBodyId) -> Arc<ExprScopes> {
|
||||
let body = db.body(def);
|
||||
let mut scopes = ExprScopes::new_body(&body);
|
||||
#[salsa::tracked(returns(ref))]
|
||||
pub fn body_expr_scopes(db: &dyn DefDatabase, def: DefWithBodyId) -> ExprScopes {
|
||||
let body = Body::of(db, def);
|
||||
let mut scopes = ExprScopes::new_body(body);
|
||||
scopes.shrink_to_fit();
|
||||
Arc::new(scopes)
|
||||
scopes
|
||||
}
|
||||
|
||||
#[salsa::tracked(returns(ref))]
|
||||
pub fn sig_expr_scopes(db: &dyn DefDatabase, def: GenericDefId) -> ExprScopes {
|
||||
let (_, store) = GenericParams::with_store(db, def);
|
||||
let roots = store.expr_roots();
|
||||
let mut scopes = ExprScopes::new_store(store, roots);
|
||||
scopes.shrink_to_fit();
|
||||
scopes
|
||||
}
|
||||
|
||||
#[salsa::tracked(returns(ref))]
|
||||
pub fn variant_scopes(db: &dyn DefDatabase, def: VariantId) -> ExprScopes {
|
||||
let fields = VariantFields::of(db, def);
|
||||
let roots = fields.store.expr_roots();
|
||||
let mut scopes = ExprScopes::new_store(&fields.store, roots);
|
||||
scopes.shrink_to_fit();
|
||||
scopes
|
||||
}
|
||||
}
|
||||
|
||||
impl ExprScopes {
|
||||
#[inline]
|
||||
pub fn of(db: &dyn DefDatabase, def: impl Into<ExpressionStoreOwnerId>) -> &ExprScopes {
|
||||
match def.into() {
|
||||
ExpressionStoreOwnerId::Body(def) => Self::body_expr_scopes(db, def),
|
||||
ExpressionStoreOwnerId::Signature(def) => Self::sig_expr_scopes(db, def),
|
||||
ExpressionStoreOwnerId::VariantFields(variant_id) => {
|
||||
Self::variant_scopes(db, variant_id)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn entries(&self, scope: ScopeId) -> &[ScopeEntry] {
|
||||
@@ -115,7 +151,23 @@ fn new_body(body: &Body) -> ExprScopes {
|
||||
scopes.add_bindings(body, root, self_param, body.binding_hygiene(self_param));
|
||||
}
|
||||
scopes.add_params_bindings(body, root, &body.params);
|
||||
compute_expr_scopes(body.body_expr, body, &mut scopes, &mut root);
|
||||
compute_expr_scopes(body.root_expr(), body, &mut scopes, &mut root);
|
||||
scopes
|
||||
}
|
||||
|
||||
fn new_store(store: &ExpressionStore, roots: impl IntoIterator<Item = ExprId>) -> ExprScopes {
|
||||
let mut scopes = ExprScopes {
|
||||
scopes: Arena::default(),
|
||||
scope_entries: Arena::default(),
|
||||
scope_by_expr: ArenaMap::with_capacity(
|
||||
store.expr_only.as_ref().map_or(0, |it| it.exprs.len()),
|
||||
),
|
||||
};
|
||||
let root = scopes.root_scope();
|
||||
for root_expr in roots {
|
||||
let mut scope = scopes.new_scope(root);
|
||||
compute_expr_scopes(root_expr, store, &mut scopes, &mut scope);
|
||||
}
|
||||
scopes
|
||||
}
|
||||
|
||||
@@ -327,7 +379,10 @@ mod tests {
|
||||
use test_utils::{assert_eq_text, extract_offset};
|
||||
|
||||
use crate::{
|
||||
FunctionId, ModuleDefId, db::DefDatabase, nameres::crate_def_map, test_db::TestDB,
|
||||
DefWithBodyId, FunctionId, ModuleDefId,
|
||||
expr_store::{Body, scope::ExprScopes},
|
||||
nameres::crate_def_map,
|
||||
test_db::TestDB,
|
||||
};
|
||||
|
||||
fn find_function(db: &TestDB, file_id: FileId) -> FunctionId {
|
||||
@@ -363,8 +418,8 @@ fn do_check(#[rust_analyzer::rust_fixture] ra_fixture: &str, expected: &[&str])
|
||||
let marker: ast::PathExpr = find_node_at_offset(&file_syntax, offset).unwrap();
|
||||
let function = find_function(&db, file_id);
|
||||
|
||||
let scopes = db.expr_scopes(function.into());
|
||||
let (_body, source_map) = db.body_with_source_map(function.into());
|
||||
let scopes = ExprScopes::of(&db, DefWithBodyId::from(function));
|
||||
let (_body, source_map) = Body::with_source_map(&db, function.into());
|
||||
|
||||
let expr_id = source_map
|
||||
.node_expr(InFile { file_id: editioned_file_id.into(), value: &marker.into() })
|
||||
@@ -522,8 +577,8 @@ fn do_check_local_name(#[rust_analyzer::rust_fixture] ra_fixture: &str, expected
|
||||
|
||||
let function = find_function(&db, file_id);
|
||||
|
||||
let scopes = db.expr_scopes(function.into());
|
||||
let (_, source_map) = db.body_with_source_map(function.into());
|
||||
let scopes = ExprScopes::body_expr_scopes(&db, DefWithBodyId::from(function));
|
||||
let (_, source_map) = Body::with_source_map(&db, function.into());
|
||||
|
||||
let expr_scope = {
|
||||
let expr_ast = name_ref.syntax().ancestors().find_map(ast::Expr::cast).unwrap();
|
||||
|
||||
@@ -4,11 +4,10 @@
|
||||
use expect_test::{Expect, expect};
|
||||
use la_arena::RawIdx;
|
||||
use test_fixture::WithFixture;
|
||||
use triomphe::Arc;
|
||||
|
||||
use super::super::*;
|
||||
|
||||
fn lower(#[rust_analyzer::rust_fixture] ra_fixture: &str) -> (TestDB, Arc<Body>, DefWithBodyId) {
|
||||
fn lower(#[rust_analyzer::rust_fixture] ra_fixture: &str) -> (TestDB, DefWithBodyId) {
|
||||
let db = TestDB::with_files(ra_fixture);
|
||||
|
||||
let krate = db.fetch_test_crate();
|
||||
@@ -24,8 +23,27 @@ fn lower(#[rust_analyzer::rust_fixture] ra_fixture: &str) -> (TestDB, Arc<Body>,
|
||||
}
|
||||
let fn_def = fn_def.unwrap().into();
|
||||
|
||||
let body = db.body(fn_def);
|
||||
(db, body, fn_def)
|
||||
Body::of(&db, fn_def);
|
||||
(db, fn_def)
|
||||
}
|
||||
|
||||
fn pretty_print(#[rust_analyzer::rust_fixture] ra_fixture: &str, expect: Expect) {
|
||||
let db = TestDB::with_files(ra_fixture);
|
||||
|
||||
let krate = db.fetch_test_crate();
|
||||
let def_map = crate_def_map(&db, krate);
|
||||
let mut fn_def = None;
|
||||
'outer: for (_, module) in def_map.modules() {
|
||||
for decl in module.scope.declarations() {
|
||||
if let ModuleDefId::FunctionId(it) = decl {
|
||||
fn_def = Some(it);
|
||||
break 'outer;
|
||||
}
|
||||
}
|
||||
}
|
||||
let fn_def = fn_def.unwrap().into();
|
||||
|
||||
expect.assert_eq(&Body::of(&db, fn_def).pretty_print(&db, fn_def, Edition::CURRENT));
|
||||
}
|
||||
|
||||
fn def_map_at(#[rust_analyzer::rust_fixture] ra_fixture: &str) -> String {
|
||||
@@ -144,7 +162,7 @@ fn outer() {
|
||||
|
||||
#[test]
|
||||
fn desugar_for_loop() {
|
||||
let (db, body, def) = lower(
|
||||
pretty_print(
|
||||
r#"
|
||||
//- minicore: iterator
|
||||
fn main() {
|
||||
@@ -154,9 +172,7 @@ fn main() {
|
||||
}
|
||||
}
|
||||
"#,
|
||||
);
|
||||
|
||||
expect![[r#"
|
||||
expect![[r#"
|
||||
fn main() {
|
||||
match builtin#lang(into_iter)(
|
||||
0..10,
|
||||
@@ -173,13 +189,13 @@ fn main() {
|
||||
}
|
||||
},
|
||||
}
|
||||
}"#]]
|
||||
.assert_eq(&body.pretty_print(&db, def, Edition::CURRENT))
|
||||
}"#]],
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn desugar_builtin_format_args_before_1_89_0() {
|
||||
let (db, body, def) = lower(
|
||||
pretty_print(
|
||||
r#"
|
||||
//- minicore: fmt_before_1_89_0
|
||||
fn main() {
|
||||
@@ -188,9 +204,7 @@ fn main() {
|
||||
builtin#format_args("\u{1b}hello {count:02} {} friends, we {are:?} {0}{last}", "fancy", orphan = (), last = "!");
|
||||
}
|
||||
"#,
|
||||
);
|
||||
|
||||
expect![[r#"
|
||||
expect![[r#"
|
||||
fn main() {
|
||||
let are = "are";
|
||||
let count = 10;
|
||||
@@ -256,13 +270,13 @@ fn main() {
|
||||
}
|
||||
},
|
||||
);
|
||||
}"#]]
|
||||
.assert_eq(&body.pretty_print(&db, def, Edition::CURRENT))
|
||||
}"#]],
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn desugar_builtin_format_args_before_1_93_0() {
|
||||
let (db, body, def) = lower(
|
||||
pretty_print(
|
||||
r#"
|
||||
//- minicore: fmt_before_1_93_0
|
||||
fn main() {
|
||||
@@ -271,9 +285,7 @@ fn main() {
|
||||
builtin#format_args("\u{1b}hello {count:02} {} friends, we {are:?} {0}{last}", "fancy", orphan = (), last = "!");
|
||||
}
|
||||
"#,
|
||||
);
|
||||
|
||||
expect![[r#"
|
||||
expect![[r#"
|
||||
fn main() {
|
||||
let are = "are";
|
||||
let count = 10;
|
||||
@@ -339,13 +351,13 @@ fn main() {
|
||||
)
|
||||
}
|
||||
};
|
||||
}"#]]
|
||||
.assert_eq(&body.pretty_print(&db, def, Edition::CURRENT))
|
||||
}"#]],
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn desugar_builtin_format_args() {
|
||||
let (db, body, def) = lower(
|
||||
pretty_print(
|
||||
r#"
|
||||
//- minicore: fmt
|
||||
fn main() {
|
||||
@@ -356,9 +368,7 @@ fn main() {
|
||||
builtin#format_args("hello world", orphan = ());
|
||||
}
|
||||
"#,
|
||||
);
|
||||
|
||||
expect![[r#"
|
||||
expect![[r#"
|
||||
fn main() {
|
||||
let are = "are";
|
||||
let count = 10;
|
||||
@@ -392,13 +402,13 @@ fn main() {
|
||||
"hello world",
|
||||
)
|
||||
};
|
||||
}"#]]
|
||||
.assert_eq(&body.pretty_print(&db, def, Edition::CURRENT))
|
||||
}"#]],
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_macro_hygiene() {
|
||||
let (db, body, def) = lower(
|
||||
pretty_print(
|
||||
r##"
|
||||
//- minicore: fmt, from
|
||||
//- /main.rs
|
||||
@@ -428,10 +438,7 @@ pub(crate) fn new(message: impl Into<core::fmt::Arguments>) -> SsrError {
|
||||
}
|
||||
}
|
||||
"##,
|
||||
);
|
||||
|
||||
assert_eq!(db.body_with_source_map(def).1.diagnostics(), &[]);
|
||||
expect![[r#"
|
||||
expect![[r#"
|
||||
fn main() {
|
||||
_ = ra_test_fixture::error::SsrError::new(
|
||||
{
|
||||
@@ -449,13 +456,13 @@ fn main() {
|
||||
}
|
||||
},
|
||||
);
|
||||
}"#]]
|
||||
.assert_eq(&body.pretty_print(&db, def, Edition::CURRENT))
|
||||
}"#]],
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn regression_10300() {
|
||||
let (db, body, def) = lower(
|
||||
pretty_print(
|
||||
r#"
|
||||
//- minicore: concat, panic, fmt_before_1_89_0
|
||||
mod private {
|
||||
@@ -472,16 +479,7 @@ fn f(a: i32, b: u32) -> String {
|
||||
m!();
|
||||
}
|
||||
"#,
|
||||
);
|
||||
|
||||
let (_, source_map) = db.body_with_source_map(def);
|
||||
assert_eq!(source_map.diagnostics(), &[]);
|
||||
|
||||
for (_, def_map) in body.blocks(&db) {
|
||||
assert_eq!(def_map.diagnostics(), &[]);
|
||||
}
|
||||
|
||||
expect![[r#"
|
||||
expect![[r#"
|
||||
fn f(a, b) {
|
||||
{
|
||||
core::panicking::panic_fmt(
|
||||
@@ -497,8 +495,8 @@ fn f(a, b) {
|
||||
),
|
||||
);
|
||||
};
|
||||
}"#]]
|
||||
.assert_eq(&body.pretty_print(&db, def, Edition::CURRENT))
|
||||
}"#]],
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -507,7 +505,7 @@ fn destructuring_assignment_tuple_macro() {
|
||||
// but in destructuring assignment it is valid, because `m!()()` is a valid expression, and destructuring
|
||||
// assignments start their lives as expressions. So we have to do the same.
|
||||
|
||||
let (db, body, def) = lower(
|
||||
pretty_print(
|
||||
r#"
|
||||
struct Bar();
|
||||
|
||||
@@ -519,25 +517,16 @@ fn foo() {
|
||||
m!()() = Bar();
|
||||
}
|
||||
"#,
|
||||
);
|
||||
|
||||
let (_, source_map) = db.body_with_source_map(def);
|
||||
assert_eq!(source_map.diagnostics(), &[]);
|
||||
|
||||
for (_, def_map) in body.blocks(&db) {
|
||||
assert_eq!(def_map.diagnostics(), &[]);
|
||||
}
|
||||
|
||||
expect![[r#"
|
||||
expect![[r#"
|
||||
fn foo() {
|
||||
Bar() = Bar();
|
||||
}"#]]
|
||||
.assert_eq(&body.pretty_print(&db, def, Edition::CURRENT))
|
||||
}"#]],
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn shadowing_record_variant() {
|
||||
let (_, body, _) = lower(
|
||||
let (db, def) = lower(
|
||||
r#"
|
||||
enum A {
|
||||
B { field: i32 },
|
||||
@@ -550,6 +539,7 @@ fn f() {
|
||||
}
|
||||
"#,
|
||||
);
|
||||
let body = Body::of(&db, def);
|
||||
assert_eq!(body.assert_expr_only().bindings.len(), 1, "should have a binding for `B`");
|
||||
assert_eq!(
|
||||
body[BindingId::from_raw(RawIdx::from_u32(0))].name.as_str(),
|
||||
@@ -560,39 +550,35 @@ fn f() {
|
||||
|
||||
#[test]
|
||||
fn regression_pretty_print_bind_pat() {
|
||||
let (db, body, owner) = lower(
|
||||
pretty_print(
|
||||
r#"
|
||||
fn foo() {
|
||||
let v @ u = 123;
|
||||
}
|
||||
"#,
|
||||
);
|
||||
let printed = body.pretty_print(&db, owner, Edition::CURRENT);
|
||||
|
||||
expect![[r#"
|
||||
expect![[r#"
|
||||
fn foo() {
|
||||
let v @ u = 123;
|
||||
}"#]]
|
||||
.assert_eq(&printed);
|
||||
}"#]],
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn skip_skips_body() {
|
||||
let (db, body, owner) = lower(
|
||||
pretty_print(
|
||||
r#"
|
||||
#[rust_analyzer::skip]
|
||||
async fn foo(a: (), b: i32) -> u32 {
|
||||
0 + 1 + b()
|
||||
}
|
||||
"#,
|
||||
expect!["fn foo(�, �) �"],
|
||||
);
|
||||
let printed = body.pretty_print(&db, owner, Edition::CURRENT);
|
||||
expect!["fn foo(�, �) �"].assert_eq(&printed);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn range_bounds_are_hir_exprs() {
|
||||
let (_, body, _) = lower(
|
||||
let (db, body) = lower(
|
||||
r#"
|
||||
pub const L: i32 = 6;
|
||||
mod x {
|
||||
@@ -607,6 +593,7 @@ const fn f(x: i32) -> i32 {
|
||||
}"#,
|
||||
);
|
||||
|
||||
let body = Body::of(&db, body);
|
||||
let mtch_arms = body
|
||||
.assert_expr_only()
|
||||
.exprs
|
||||
@@ -635,7 +622,7 @@ const fn f(x: i32) -> i32 {
|
||||
|
||||
#[test]
|
||||
fn print_hir_precedences() {
|
||||
let (db, body, def) = lower(
|
||||
pretty_print(
|
||||
r#"
|
||||
fn main() {
|
||||
_ = &(1 - (2 - 3) + 4 * 5 * (6 + 7));
|
||||
@@ -646,9 +633,7 @@ fn main() {
|
||||
let _ = &mut (*r as i32)
|
||||
}
|
||||
"#,
|
||||
);
|
||||
|
||||
expect![[r#"
|
||||
expect![[r#"
|
||||
fn main() {
|
||||
_ = &((1 - (2 - 3)) + (4 * 5) * (6 + 7));
|
||||
_ = 1 + 2 < 3 && true && 4 < 5 && (a || b || c) || d && e;
|
||||
@@ -656,24 +641,22 @@ fn main() {
|
||||
break a && b || (return) || (return 2);
|
||||
let r = &2;
|
||||
let _ = &mut (*r as i32);
|
||||
}"#]]
|
||||
.assert_eq(&body.pretty_print(&db, def, Edition::CURRENT))
|
||||
}"#]],
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn async_fn_weird_param_patterns() {
|
||||
let (db, body, def) = lower(
|
||||
pretty_print(
|
||||
r#"
|
||||
async fn main(&self, param1: i32, ref mut param2: i32, _: i32, param4 @ _: i32, 123: i32) {}
|
||||
"#,
|
||||
);
|
||||
|
||||
expect![[r#"
|
||||
expect![[r#"
|
||||
fn main(self, param1, mut param2, mut <ra@gennew>0, param4 @ _, mut <ra@gennew>1) async {
|
||||
let ref mut param2 = param2;
|
||||
let _ = <ra@gennew>0;
|
||||
let 123 = <ra@gennew>1;
|
||||
{}
|
||||
}"#]]
|
||||
.assert_eq(&body.pretty_print(&db, def, Edition::CURRENT))
|
||||
}"#]],
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
GenericDefId, ModuleDefId,
|
||||
expr_store::pretty::{print_function, print_struct},
|
||||
nameres::crate_def_map,
|
||||
signatures::{FunctionSignature, StructSignature},
|
||||
test_db::TestDB,
|
||||
};
|
||||
use expect_test::{Expect, expect};
|
||||
@@ -41,7 +42,7 @@ fn lower_and_print(#[rust_analyzer::rust_fixture] ra_fixture: &str, expect: Expe
|
||||
out += &print_struct(
|
||||
&db,
|
||||
struct_id,
|
||||
&db.struct_signature(struct_id),
|
||||
StructSignature::of(&db, struct_id),
|
||||
Edition::CURRENT,
|
||||
);
|
||||
}
|
||||
@@ -53,7 +54,7 @@ fn lower_and_print(#[rust_analyzer::rust_fixture] ra_fixture: &str, expect: Expe
|
||||
out += &print_function(
|
||||
&db,
|
||||
function_id,
|
||||
&db.function_signature(function_id),
|
||||
FunctionSignature::of(&db, function_id),
|
||||
Edition::CURRENT,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
use crate::{
|
||||
FindPathConfig, ModuleDefId, ModuleId,
|
||||
db::DefDatabase,
|
||||
import_map::ImportMap,
|
||||
item_scope::ItemInNs,
|
||||
nameres::DefMap,
|
||||
visibility::{Visibility, VisibilityExplicitness},
|
||||
@@ -426,7 +427,7 @@ fn find_in_dep(
|
||||
best_choice: &mut Option<Choice>,
|
||||
dep: Crate,
|
||||
) {
|
||||
let import_map = ctx.db.import_map(dep);
|
||||
let import_map = ImportMap::of(ctx.db, dep);
|
||||
let Some(import_info_for) = import_map.import_info_for(item) else {
|
||||
return;
|
||||
};
|
||||
|
||||
@@ -5,12 +5,15 @@
|
||||
use la_arena::{Arena, Idx, RawIdx};
|
||||
use stdx::impl_from;
|
||||
use thin_vec::ThinVec;
|
||||
use triomphe::Arc;
|
||||
|
||||
use crate::{
|
||||
AdtId, ConstParamId, GenericDefId, LifetimeParamId, TypeOrConstParamId, TypeParamId,
|
||||
db::DefDatabase,
|
||||
expr_store::{ExpressionStore, ExpressionStoreSourceMap},
|
||||
signatures::{
|
||||
ConstSignature, EnumSignature, FunctionSignature, ImplSignature, StaticSignature,
|
||||
StructSignature, TraitSignature, TypeAliasSignature, UnionSignature,
|
||||
},
|
||||
type_ref::{ConstRef, LifetimeRefId, TypeBound, TypeRefId},
|
||||
};
|
||||
|
||||
@@ -142,7 +145,7 @@ pub enum GenericParamDataRef<'a> {
|
||||
}
|
||||
|
||||
/// Data about the generic parameters of a function, struct, impl, etc.
|
||||
#[derive(Clone, PartialEq, Eq, Debug, Hash)]
|
||||
#[derive(PartialEq, Eq, Debug, Hash, Default)]
|
||||
pub struct GenericParams {
|
||||
pub(crate) type_or_consts: Arena<TypeOrConstParamData>,
|
||||
pub(crate) lifetimes: Arena<LifetimeParamData>,
|
||||
@@ -174,12 +177,10 @@ pub enum WherePredicate {
|
||||
ForLifetime { lifetimes: ThinVec<Name>, target: TypeRefId, bound: TypeBound },
|
||||
}
|
||||
|
||||
static EMPTY: LazyLock<Arc<GenericParams>> = LazyLock::new(|| {
|
||||
Arc::new(GenericParams {
|
||||
type_or_consts: Arena::default(),
|
||||
lifetimes: Arena::default(),
|
||||
where_predicates: Box::default(),
|
||||
})
|
||||
static EMPTY: LazyLock<GenericParams> = LazyLock::new(|| GenericParams {
|
||||
type_or_consts: Arena::default(),
|
||||
lifetimes: Arena::default(),
|
||||
where_predicates: Box::default(),
|
||||
});
|
||||
|
||||
impl GenericParams {
|
||||
@@ -187,112 +188,94 @@ impl GenericParams {
|
||||
pub const SELF_PARAM_ID_IN_SELF: la_arena::Idx<TypeOrConstParamData> =
|
||||
LocalTypeOrConstParamId::from_raw(RawIdx::from_u32(0));
|
||||
|
||||
pub fn new(db: &dyn DefDatabase, def: GenericDefId) -> Arc<GenericParams> {
|
||||
pub fn of(db: &dyn DefDatabase, def: GenericDefId) -> &GenericParams {
|
||||
Self::with_store(db, def).0
|
||||
}
|
||||
|
||||
pub fn with_store(
|
||||
db: &dyn DefDatabase,
|
||||
def: GenericDefId,
|
||||
) -> (&GenericParams, &ExpressionStore) {
|
||||
match def {
|
||||
GenericDefId::AdtId(AdtId::EnumId(it)) => db.enum_signature(it).generic_params.clone(),
|
||||
GenericDefId::AdtId(AdtId::StructId(it)) => {
|
||||
db.struct_signature(it).generic_params.clone()
|
||||
GenericDefId::AdtId(AdtId::EnumId(id)) => {
|
||||
let sig = EnumSignature::of(db, id);
|
||||
(&sig.generic_params, &sig.store)
|
||||
}
|
||||
GenericDefId::AdtId(AdtId::UnionId(it)) => {
|
||||
db.union_signature(it).generic_params.clone()
|
||||
GenericDefId::AdtId(AdtId::StructId(id)) => {
|
||||
let sig = StructSignature::of(db, id);
|
||||
(&sig.generic_params, &sig.store)
|
||||
}
|
||||
GenericDefId::ConstId(_) => EMPTY.clone(),
|
||||
GenericDefId::FunctionId(function_id) => {
|
||||
db.function_signature(function_id).generic_params.clone()
|
||||
GenericDefId::AdtId(AdtId::UnionId(id)) => {
|
||||
let sig = UnionSignature::of(db, id);
|
||||
(&sig.generic_params, &sig.store)
|
||||
}
|
||||
GenericDefId::ImplId(impl_id) => db.impl_signature(impl_id).generic_params.clone(),
|
||||
GenericDefId::StaticId(_) => EMPTY.clone(),
|
||||
GenericDefId::TraitId(trait_id) => db.trait_signature(trait_id).generic_params.clone(),
|
||||
GenericDefId::TypeAliasId(type_alias_id) => {
|
||||
db.type_alias_signature(type_alias_id).generic_params.clone()
|
||||
GenericDefId::ConstId(id) => {
|
||||
let sig = ConstSignature::of(db, id);
|
||||
(&EMPTY, &sig.store)
|
||||
}
|
||||
GenericDefId::FunctionId(id) => {
|
||||
let sig = FunctionSignature::of(db, id);
|
||||
(&sig.generic_params, &sig.store)
|
||||
}
|
||||
GenericDefId::ImplId(id) => {
|
||||
let sig = ImplSignature::of(db, id);
|
||||
(&sig.generic_params, &sig.store)
|
||||
}
|
||||
GenericDefId::StaticId(id) => {
|
||||
let sig = StaticSignature::of(db, id);
|
||||
(&EMPTY, &sig.store)
|
||||
}
|
||||
GenericDefId::TraitId(id) => {
|
||||
let sig = TraitSignature::of(db, id);
|
||||
(&sig.generic_params, &sig.store)
|
||||
}
|
||||
GenericDefId::TypeAliasId(id) => {
|
||||
let sig = TypeAliasSignature::of(db, id);
|
||||
(&sig.generic_params, &sig.store)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn generic_params_and_store(
|
||||
pub fn with_source_map(
|
||||
db: &dyn DefDatabase,
|
||||
def: GenericDefId,
|
||||
) -> (Arc<GenericParams>, Arc<ExpressionStore>) {
|
||||
) -> (&GenericParams, &ExpressionStore, &ExpressionStoreSourceMap) {
|
||||
match def {
|
||||
GenericDefId::AdtId(AdtId::EnumId(id)) => {
|
||||
let sig = db.enum_signature(id);
|
||||
(sig.generic_params.clone(), sig.store.clone())
|
||||
let (sig, sm) = EnumSignature::with_source_map(db, id);
|
||||
(&sig.generic_params, &sig.store, sm)
|
||||
}
|
||||
GenericDefId::AdtId(AdtId::StructId(id)) => {
|
||||
let sig = db.struct_signature(id);
|
||||
(sig.generic_params.clone(), sig.store.clone())
|
||||
let (sig, sm) = StructSignature::with_source_map(db, id);
|
||||
(&sig.generic_params, &sig.store, sm)
|
||||
}
|
||||
GenericDefId::AdtId(AdtId::UnionId(id)) => {
|
||||
let sig = db.union_signature(id);
|
||||
(sig.generic_params.clone(), sig.store.clone())
|
||||
let (sig, sm) = UnionSignature::with_source_map(db, id);
|
||||
(&sig.generic_params, &sig.store, sm)
|
||||
}
|
||||
GenericDefId::ConstId(id) => {
|
||||
let sig = db.const_signature(id);
|
||||
(EMPTY.clone(), sig.store.clone())
|
||||
let (sig, sm) = ConstSignature::with_source_map(db, id);
|
||||
(&EMPTY, &sig.store, sm)
|
||||
}
|
||||
GenericDefId::FunctionId(id) => {
|
||||
let sig = db.function_signature(id);
|
||||
(sig.generic_params.clone(), sig.store.clone())
|
||||
let (sig, sm) = FunctionSignature::with_source_map(db, id);
|
||||
(&sig.generic_params, &sig.store, sm)
|
||||
}
|
||||
GenericDefId::ImplId(id) => {
|
||||
let sig = db.impl_signature(id);
|
||||
(sig.generic_params.clone(), sig.store.clone())
|
||||
let (sig, sm) = ImplSignature::with_source_map(db, id);
|
||||
(&sig.generic_params, &sig.store, sm)
|
||||
}
|
||||
GenericDefId::StaticId(id) => {
|
||||
let sig = db.static_signature(id);
|
||||
(EMPTY.clone(), sig.store.clone())
|
||||
let (sig, sm) = StaticSignature::with_source_map(db, id);
|
||||
(&EMPTY, &sig.store, sm)
|
||||
}
|
||||
GenericDefId::TraitId(id) => {
|
||||
let sig = db.trait_signature(id);
|
||||
(sig.generic_params.clone(), sig.store.clone())
|
||||
let (sig, sm) = TraitSignature::with_source_map(db, id);
|
||||
(&sig.generic_params, &sig.store, sm)
|
||||
}
|
||||
GenericDefId::TypeAliasId(id) => {
|
||||
let sig = db.type_alias_signature(id);
|
||||
(sig.generic_params.clone(), sig.store.clone())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn generic_params_and_store_and_source_map(
|
||||
db: &dyn DefDatabase,
|
||||
def: GenericDefId,
|
||||
) -> (Arc<GenericParams>, Arc<ExpressionStore>, Arc<ExpressionStoreSourceMap>) {
|
||||
match def {
|
||||
GenericDefId::AdtId(AdtId::EnumId(id)) => {
|
||||
let (sig, sm) = db.enum_signature_with_source_map(id);
|
||||
(sig.generic_params.clone(), sig.store.clone(), sm)
|
||||
}
|
||||
GenericDefId::AdtId(AdtId::StructId(id)) => {
|
||||
let (sig, sm) = db.struct_signature_with_source_map(id);
|
||||
(sig.generic_params.clone(), sig.store.clone(), sm)
|
||||
}
|
||||
GenericDefId::AdtId(AdtId::UnionId(id)) => {
|
||||
let (sig, sm) = db.union_signature_with_source_map(id);
|
||||
(sig.generic_params.clone(), sig.store.clone(), sm)
|
||||
}
|
||||
GenericDefId::ConstId(id) => {
|
||||
let (sig, sm) = db.const_signature_with_source_map(id);
|
||||
(EMPTY.clone(), sig.store.clone(), sm)
|
||||
}
|
||||
GenericDefId::FunctionId(id) => {
|
||||
let (sig, sm) = db.function_signature_with_source_map(id);
|
||||
(sig.generic_params.clone(), sig.store.clone(), sm)
|
||||
}
|
||||
GenericDefId::ImplId(id) => {
|
||||
let (sig, sm) = db.impl_signature_with_source_map(id);
|
||||
(sig.generic_params.clone(), sig.store.clone(), sm)
|
||||
}
|
||||
GenericDefId::StaticId(id) => {
|
||||
let (sig, sm) = db.static_signature_with_source_map(id);
|
||||
(EMPTY.clone(), sig.store.clone(), sm)
|
||||
}
|
||||
GenericDefId::TraitId(id) => {
|
||||
let (sig, sm) = db.trait_signature_with_source_map(id);
|
||||
(sig.generic_params.clone(), sig.store.clone(), sm)
|
||||
}
|
||||
GenericDefId::TypeAliasId(id) => {
|
||||
let (sig, sm) = db.type_alias_signature_with_source_map(id);
|
||||
(sig.generic_params.clone(), sig.store.clone(), sm)
|
||||
let (sig, sm) = TypeAliasSignature::with_source_map(db, id);
|
||||
(&sig.generic_params, &sig.store, sm)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
use smallvec::SmallVec;
|
||||
use span::Edition;
|
||||
use stdx::format_to;
|
||||
use triomphe::Arc;
|
||||
|
||||
use crate::{
|
||||
AssocItemId, AttrDefId, Complete, FxIndexMap, ModuleDefId, ModuleId, TraitId,
|
||||
@@ -63,6 +62,14 @@ enum IsTraitAssocItem {
|
||||
|
||||
type ImportMapIndex = FxIndexMap<ItemInNs, (SmallVec<[ImportInfo; 1]>, IsTraitAssocItem)>;
|
||||
|
||||
#[salsa::tracked]
|
||||
impl ImportMap {
|
||||
#[salsa::tracked(returns(ref))]
|
||||
pub fn of(db: &dyn DefDatabase, krate: Crate) -> Self {
|
||||
Self::import_map_query_impl(db, krate)
|
||||
}
|
||||
}
|
||||
|
||||
impl ImportMap {
|
||||
pub fn dump(&self, db: &dyn DefDatabase) -> String {
|
||||
let mut out = String::new();
|
||||
@@ -76,7 +83,7 @@ pub fn dump(&self, db: &dyn DefDatabase) -> String {
|
||||
out
|
||||
}
|
||||
|
||||
pub(crate) fn import_map_query(db: &dyn DefDatabase, krate: Crate) -> Arc<Self> {
|
||||
fn import_map_query_impl(db: &dyn DefDatabase, krate: Crate) -> Self {
|
||||
let _p = tracing::info_span!("import_map_query").entered();
|
||||
|
||||
let map = Self::collect_import_map(db, krate);
|
||||
@@ -120,7 +127,7 @@ pub(crate) fn import_map_query(db: &dyn DefDatabase, krate: Crate) -> Arc<Self>
|
||||
}
|
||||
|
||||
let importables = importables.into_iter().map(|(item, _, idx)| (item, idx)).collect();
|
||||
Arc::new(ImportMap { item_to_info_map: map, fst: builder.into_map(), importables })
|
||||
ImportMap { item_to_info_map: map, fst: builder.into_map(), importables }
|
||||
}
|
||||
|
||||
pub fn import_info_for(&self, item: ItemInNs) -> Option<&[ImportInfo]> {
|
||||
@@ -424,7 +431,7 @@ pub fn search_dependencies(
|
||||
let _p = tracing::info_span!("search_dependencies", ?query).entered();
|
||||
|
||||
let import_maps: Vec<_> =
|
||||
krate.data(db).dependencies.iter().map(|dep| db.import_map(dep.crate_id)).collect();
|
||||
krate.data(db).dependencies.iter().map(|dep| ImportMap::of(db, dep.crate_id)).collect();
|
||||
|
||||
let mut op = fst::map::OpBuilder::new();
|
||||
|
||||
@@ -458,7 +465,7 @@ pub fn search_dependencies(
|
||||
|
||||
fn search_maps(
|
||||
_db: &dyn DefDatabase,
|
||||
import_maps: &[Arc<ImportMap>],
|
||||
import_maps: &[&ImportMap],
|
||||
mut stream: fst::map::Union<'_>,
|
||||
query: &Query,
|
||||
) -> FxHashSet<(ItemInNs, Complete)> {
|
||||
@@ -467,7 +474,7 @@ fn search_maps(
|
||||
for &IndexedValue { index: import_map_idx, value } in indexed_values {
|
||||
let end = (value & 0xFFFF_FFFF) as usize;
|
||||
let start = (value >> 32) as usize;
|
||||
let ImportMap { item_to_info_map, importables, .. } = &*import_maps[import_map_idx];
|
||||
let ImportMap { item_to_info_map, importables, .. } = import_maps[import_map_idx];
|
||||
let importables = &importables[start..end];
|
||||
|
||||
let iter = importables
|
||||
@@ -546,9 +553,9 @@ fn check_search(
|
||||
.into_iter()
|
||||
.filter_map(|(dependency, _)| {
|
||||
let dependency_krate = dependency.krate(&db)?;
|
||||
let dependency_imports = db.import_map(dependency_krate);
|
||||
let dependency_imports = ImportMap::of(&db, dependency_krate);
|
||||
|
||||
let (path, mark) = match assoc_item_path(&db, &dependency_imports, dependency) {
|
||||
let (path, mark) = match assoc_item_path(&db, dependency_imports, dependency) {
|
||||
Some(assoc_item_path) => (assoc_item_path, "a"),
|
||||
None => (
|
||||
render_path(&db, &dependency_imports.import_info_for(dependency)?[0]),
|
||||
@@ -618,7 +625,7 @@ fn check(#[rust_analyzer::rust_fixture] ra_fixture: &str, expect: Expect) {
|
||||
let cdata = &krate.extra_data(&db);
|
||||
let name = cdata.display_name.as_ref()?;
|
||||
|
||||
let map = db.import_map(krate);
|
||||
let map = ImportMap::of(&db, krate);
|
||||
|
||||
Some(format!("{name}:\n{}\n", map.fmt_for_test(&db)))
|
||||
})
|
||||
|
||||
@@ -192,45 +192,22 @@ pub(crate) fn file_item_tree_query(
|
||||
}
|
||||
}
|
||||
|
||||
#[salsa_macros::tracked(returns(deref))]
|
||||
#[salsa_macros::tracked(returns(ref))]
|
||||
pub(crate) fn block_item_tree_query(
|
||||
db: &dyn DefDatabase,
|
||||
block: BlockId,
|
||||
krate: Crate,
|
||||
) -> Arc<ItemTree> {
|
||||
) -> ItemTree {
|
||||
let _p = tracing::info_span!("block_item_tree_query", ?block).entered();
|
||||
static EMPTY: OnceLock<Arc<ItemTree>> = OnceLock::new();
|
||||
|
||||
let loc = block.lookup(db);
|
||||
let block = loc.ast_id.to_node(db);
|
||||
|
||||
let ctx = lower::Ctx::new(db, loc.ast_id.file_id, krate);
|
||||
let mut item_tree = ctx.lower_block(&block);
|
||||
let ItemTree { top_level, top_attrs, attrs, vis, big_data, small_data } = &item_tree;
|
||||
if small_data.is_empty()
|
||||
&& big_data.is_empty()
|
||||
&& top_level.is_empty()
|
||||
&& attrs.is_empty()
|
||||
&& top_attrs.is_empty()
|
||||
&& vis.arena.is_empty()
|
||||
{
|
||||
EMPTY
|
||||
.get_or_init(|| {
|
||||
Arc::new(ItemTree {
|
||||
top_level: Box::new([]),
|
||||
attrs: FxHashMap::default(),
|
||||
small_data: FxHashMap::default(),
|
||||
big_data: FxHashMap::default(),
|
||||
top_attrs: AttrsOrCfg::empty(),
|
||||
vis: ItemVisibilities { arena: ThinVec::new() },
|
||||
})
|
||||
})
|
||||
.clone()
|
||||
} else {
|
||||
item_tree.shrink_to_fit();
|
||||
Arc::new(item_tree)
|
||||
}
|
||||
item_tree.shrink_to_fit();
|
||||
item_tree
|
||||
}
|
||||
|
||||
/// The item tree of a source file.
|
||||
#[derive(Debug, Default, Eq, PartialEq)]
|
||||
pub struct ItemTree {
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
AstNode,
|
||||
ast::{self, HasModuleItem, HasName},
|
||||
};
|
||||
use triomphe::Arc;
|
||||
|
||||
use crate::{
|
||||
db::DefDatabase,
|
||||
@@ -29,20 +28,20 @@
|
||||
},
|
||||
};
|
||||
|
||||
pub(super) struct Ctx<'a> {
|
||||
pub(super) db: &'a dyn DefDatabase,
|
||||
pub(super) struct Ctx<'db> {
|
||||
pub(super) db: &'db dyn DefDatabase,
|
||||
tree: ItemTree,
|
||||
source_ast_id_map: Arc<AstIdMap>,
|
||||
source_ast_id_map: &'db AstIdMap,
|
||||
span_map: OnceCell<SpanMap>,
|
||||
file: HirFileId,
|
||||
cfg_options: OnceCell<&'a CfgOptions>,
|
||||
cfg_options: OnceCell<&'db CfgOptions>,
|
||||
krate: Crate,
|
||||
top_level: Vec<ModItemId>,
|
||||
visibilities: FxIndexSet<RawVisibility>,
|
||||
}
|
||||
|
||||
impl<'a> Ctx<'a> {
|
||||
pub(super) fn new(db: &'a dyn DefDatabase, file: HirFileId, krate: Crate) -> Self {
|
||||
impl<'db> Ctx<'db> {
|
||||
pub(super) fn new(db: &'db dyn DefDatabase, file: HirFileId, krate: Crate) -> Self {
|
||||
Self {
|
||||
db,
|
||||
tree: ItemTree::default(),
|
||||
@@ -57,7 +56,7 @@ pub(super) fn new(db: &'a dyn DefDatabase, file: HirFileId, krate: Crate) -> Sel
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(super) fn cfg_options(&self) -> &'a CfgOptions {
|
||||
pub(super) fn cfg_options(&self) -> &'db CfgOptions {
|
||||
self.cfg_options.get_or_init(|| self.krate.cfg_options(self.db))
|
||||
}
|
||||
|
||||
|
||||
@@ -49,7 +49,6 @@
|
||||
use intern::{Interned, Symbol};
|
||||
pub use rustc_abi as layout;
|
||||
use thin_vec::ThinVec;
|
||||
use triomphe::Arc;
|
||||
|
||||
pub use crate::signatures::LocalFieldId;
|
||||
|
||||
@@ -86,14 +85,19 @@
|
||||
builtin_type::BuiltinType,
|
||||
db::DefDatabase,
|
||||
expr_store::ExpressionStoreSourceMap,
|
||||
hir::generics::{GenericParams, LocalLifetimeParamId, LocalTypeOrConstParamId},
|
||||
hir::{
|
||||
ExprId,
|
||||
generics::{GenericParams, LocalLifetimeParamId, LocalTypeOrConstParamId},
|
||||
},
|
||||
nameres::{
|
||||
LocalDefMap,
|
||||
assoc::{ImplItems, TraitItems},
|
||||
block_def_map, crate_def_map, crate_local_def_map,
|
||||
diagnostics::DefDiagnostics,
|
||||
},
|
||||
signatures::{EnumVariants, InactiveEnumVariantCode, VariantFields},
|
||||
signatures::{
|
||||
ConstSignature, EnumVariants, InactiveEnumVariantCode, StaticSignature, VariantFields,
|
||||
},
|
||||
};
|
||||
|
||||
type FxIndexMap<K, V> = indexmap::IndexMap<K, V, rustc_hash::FxBuildHasher>;
|
||||
@@ -255,14 +259,15 @@ fn module(&self, db: &dyn DefDatabase) -> ModuleId {
|
||||
|
||||
impl StructId {
|
||||
pub fn fields(self, db: &dyn DefDatabase) -> &VariantFields {
|
||||
VariantFields::firewall(db, self.into())
|
||||
VariantFields::of(db, self.into())
|
||||
}
|
||||
|
||||
pub fn fields_with_source_map(
|
||||
self,
|
||||
db: &dyn DefDatabase,
|
||||
) -> (Arc<VariantFields>, Arc<ExpressionStoreSourceMap>) {
|
||||
VariantFields::query(db, self.into())
|
||||
) -> (&VariantFields, &ExpressionStoreSourceMap) {
|
||||
let r = VariantFields::with_source_map(db, self.into());
|
||||
(&r.0, &r.1)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -271,14 +276,15 @@ pub fn fields_with_source_map(
|
||||
|
||||
impl UnionId {
|
||||
pub fn fields(self, db: &dyn DefDatabase) -> &VariantFields {
|
||||
VariantFields::firewall(db, self.into())
|
||||
VariantFields::of(db, self.into())
|
||||
}
|
||||
|
||||
pub fn fields_with_source_map(
|
||||
self,
|
||||
db: &dyn DefDatabase,
|
||||
) -> (Arc<VariantFields>, Arc<ExpressionStoreSourceMap>) {
|
||||
VariantFields::query(db, self.into())
|
||||
) -> (&VariantFields, &ExpressionStoreSourceMap) {
|
||||
let r = VariantFields::with_source_map(db, self.into());
|
||||
(&r.0, &r.1)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -306,6 +312,19 @@ pub fn enum_variants_with_diagnostics(
|
||||
pub type StaticLoc = AssocItemLoc<ast::Static>;
|
||||
impl_intern!(StaticId, StaticLoc, intern_static, lookup_intern_static);
|
||||
|
||||
/// An anonymous const expression that appears in a type position (e.g., array lengths,
|
||||
/// const generic arguments like `{ N + 1 }`). Unlike named constants, these don't have
|
||||
/// their own `Body` — their expressions live in the parent's signature `ExpressionStore`.
|
||||
#[derive(Debug, Hash, PartialEq, Eq, Clone)]
|
||||
pub struct AnonConstLoc {
|
||||
/// The owner store containing this expression.
|
||||
pub owner: ExpressionStoreOwnerId,
|
||||
/// The ExprId within the owner's ExpressionStore that is the root
|
||||
/// of this anonymous const expression.
|
||||
pub expr: ExprId,
|
||||
}
|
||||
impl_intern!(AnonConstId, AnonConstLoc, intern_anon_const, lookup_intern_anon_const);
|
||||
|
||||
pub type TraitLoc = ItemLoc<ast::Trait>;
|
||||
impl_intern!(TraitId, TraitLoc, intern_trait, lookup_intern_trait);
|
||||
|
||||
@@ -377,14 +396,15 @@ pub struct EnumVariantLoc {
|
||||
|
||||
impl EnumVariantId {
|
||||
pub fn fields(self, db: &dyn DefDatabase) -> &VariantFields {
|
||||
VariantFields::firewall(db, self.into())
|
||||
VariantFields::of(db, self.into())
|
||||
}
|
||||
|
||||
pub fn fields_with_source_map(
|
||||
self,
|
||||
db: &dyn DefDatabase,
|
||||
) -> (Arc<VariantFields>, Arc<ExpressionStoreSourceMap>) {
|
||||
VariantFields::query(db, self.into())
|
||||
) -> (&VariantFields, &ExpressionStoreSourceMap) {
|
||||
let r = VariantFields::with_source_map(db, self.into());
|
||||
(&r.0, &r.1)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -706,46 +726,47 @@ fn from(value: DefWithBodyId) -> Self {
|
||||
pub enum GeneralConstId {
|
||||
ConstId(ConstId),
|
||||
StaticId(StaticId),
|
||||
AnonConstId(AnonConstId),
|
||||
}
|
||||
|
||||
impl_from!(ConstId, StaticId for GeneralConstId);
|
||||
impl_from!(ConstId, StaticId, AnonConstId for GeneralConstId);
|
||||
|
||||
impl GeneralConstId {
|
||||
pub fn generic_def(self, _db: &dyn DefDatabase) -> Option<GenericDefId> {
|
||||
pub fn generic_def(self, db: &dyn DefDatabase) -> Option<GenericDefId> {
|
||||
match self {
|
||||
GeneralConstId::ConstId(it) => Some(it.into()),
|
||||
GeneralConstId::StaticId(it) => Some(it.into()),
|
||||
GeneralConstId::AnonConstId(it) => Some(it.lookup(db).owner.generic_def(db)),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn name(self, db: &dyn DefDatabase) -> String {
|
||||
match self {
|
||||
GeneralConstId::StaticId(it) => {
|
||||
db.static_signature(it).name.display(db, Edition::CURRENT).to_string()
|
||||
StaticSignature::of(db, it).name.display(db, Edition::CURRENT).to_string()
|
||||
}
|
||||
GeneralConstId::ConstId(const_id) => {
|
||||
db.const_signature(const_id).name.as_ref().map_or_else(
|
||||
ConstSignature::of(db, const_id).name.as_ref().map_or_else(
|
||||
|| "_".to_owned(),
|
||||
|name| name.display(db, Edition::CURRENT).to_string(),
|
||||
)
|
||||
}
|
||||
GeneralConstId::AnonConstId(_) => "{anon const}".to_owned(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// The defs which have a body (have root expressions for type inference).
|
||||
/// The defs which have a body.
|
||||
#[derive(Debug, PartialOrd, Ord, Clone, Copy, PartialEq, Eq, Hash, salsa_macros::Supertype)]
|
||||
pub enum DefWithBodyId {
|
||||
/// A function body.
|
||||
FunctionId(FunctionId),
|
||||
/// A static item initializer.
|
||||
StaticId(StaticId),
|
||||
/// A const item initializer
|
||||
ConstId(ConstId),
|
||||
/// An enum variant discrimiant
|
||||
VariantId(EnumVariantId),
|
||||
// /// All fields of a variant are inference roots
|
||||
// VariantId(VariantId),
|
||||
// /// The signature can contain inference roots in a bunch of places
|
||||
// /// like const parameters or const arguments in paths
|
||||
// This should likely be kept on its own with a separate query
|
||||
// GenericDefId(GenericDefId),
|
||||
}
|
||||
impl_from!(FunctionId, ConstId, StaticId for DefWithBodyId);
|
||||
|
||||
@@ -814,6 +835,62 @@ pub enum GenericDefId {
|
||||
for GenericDefId
|
||||
);
|
||||
|
||||
/// Owner of an expression store - either a body or a signature.
|
||||
/// This is used for queries that operate on expression stores generically,
|
||||
/// such as `expr_scopes`.
|
||||
// NOTE: This type cannot be `salsa::Supertype` as its variants are overlapping.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord /* !salsa::Supertype */)]
|
||||
pub enum ExpressionStoreOwnerId {
|
||||
Signature(GenericDefId),
|
||||
/// A body, something with a root expression.
|
||||
///
|
||||
/// An enum variant's body is considered its discriminant initializer.
|
||||
Body(DefWithBodyId),
|
||||
VariantFields(VariantId),
|
||||
}
|
||||
|
||||
impl ExpressionStoreOwnerId {
|
||||
// FIXME: Check callers of this, this method likely can be removed
|
||||
pub fn as_def_with_body(self) -> Option<DefWithBodyId> {
|
||||
if let Self::Body(v) = self { Some(v) } else { None }
|
||||
}
|
||||
|
||||
pub fn generic_def(self, db: &dyn DefDatabase) -> GenericDefId {
|
||||
match self {
|
||||
ExpressionStoreOwnerId::Signature(generic_def_id) => generic_def_id,
|
||||
ExpressionStoreOwnerId::Body(def_with_body_id) => match def_with_body_id {
|
||||
DefWithBodyId::FunctionId(id) => GenericDefId::FunctionId(id),
|
||||
DefWithBodyId::StaticId(id) => GenericDefId::StaticId(id),
|
||||
DefWithBodyId::ConstId(id) => GenericDefId::ConstId(id),
|
||||
DefWithBodyId::VariantId(it) => it.lookup(db).parent.into(),
|
||||
},
|
||||
ExpressionStoreOwnerId::VariantFields(variant_id) => match variant_id {
|
||||
VariantId::EnumVariantId(it) => it.lookup(db).parent.into(),
|
||||
VariantId::StructId(it) => it.into(),
|
||||
VariantId::UnionId(it) => it.into(),
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<GenericDefId> for ExpressionStoreOwnerId {
|
||||
fn from(id: GenericDefId) -> Self {
|
||||
ExpressionStoreOwnerId::Signature(id)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<DefWithBodyId> for ExpressionStoreOwnerId {
|
||||
fn from(id: DefWithBodyId) -> Self {
|
||||
ExpressionStoreOwnerId::Body(id)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<VariantId> for ExpressionStoreOwnerId {
|
||||
fn from(id: VariantId) -> Self {
|
||||
ExpressionStoreOwnerId::VariantFields(id)
|
||||
}
|
||||
}
|
||||
|
||||
impl GenericDefId {
|
||||
pub fn file_id_and_params_of(
|
||||
self,
|
||||
@@ -954,7 +1031,9 @@ fn from(vid: VariantId) -> Self {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, salsa_macros::Supertype, salsa::Update)]
|
||||
#[derive(
|
||||
Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, salsa_macros::Supertype, salsa::Update,
|
||||
)]
|
||||
pub enum VariantId {
|
||||
EnumVariantId(EnumVariantId),
|
||||
StructId(StructId),
|
||||
@@ -964,14 +1043,15 @@ pub enum VariantId {
|
||||
|
||||
impl VariantId {
|
||||
pub fn fields(self, db: &dyn DefDatabase) -> &VariantFields {
|
||||
VariantFields::firewall(db, self)
|
||||
VariantFields::of(db, self)
|
||||
}
|
||||
|
||||
pub fn fields_with_source_map(
|
||||
self,
|
||||
db: &dyn DefDatabase,
|
||||
) -> (Arc<VariantFields>, Arc<ExpressionStoreSourceMap>) {
|
||||
VariantFields::query(db, self)
|
||||
) -> (&VariantFields, &ExpressionStoreSourceMap) {
|
||||
let r = VariantFields::with_source_map(db, self);
|
||||
(&r.0, &r.1)
|
||||
}
|
||||
|
||||
pub fn file_id(self, db: &dyn DefDatabase) -> HirFileId {
|
||||
@@ -1172,6 +1252,16 @@ fn module(&self, db: &dyn DefDatabase) -> ModuleId {
|
||||
}
|
||||
}
|
||||
|
||||
impl HasModule for ExpressionStoreOwnerId {
|
||||
fn module(&self, db: &dyn DefDatabase) -> ModuleId {
|
||||
match self {
|
||||
ExpressionStoreOwnerId::Signature(def) => def.module(db),
|
||||
ExpressionStoreOwnerId::Body(def) => def.module(db),
|
||||
ExpressionStoreOwnerId::VariantFields(variant_id) => variant_id.module(db),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl HasModule for GenericDefId {
|
||||
fn module(&self, db: &dyn DefDatabase) -> ModuleId {
|
||||
match self {
|
||||
|
||||
@@ -45,6 +45,7 @@
|
||||
use crate::{
|
||||
AdtId, Lookup, ModuleDefId,
|
||||
db::DefDatabase,
|
||||
expr_store::Body,
|
||||
nameres::{DefMap, ModuleSource, crate_def_map},
|
||||
src::HasSource,
|
||||
test_db::TestDB,
|
||||
@@ -276,7 +277,7 @@ fn resolve_macro_call_id(
|
||||
_ => continue,
|
||||
};
|
||||
|
||||
let (body, sm) = db.body_with_source_map(body);
|
||||
let (body, sm) = Body::with_source_map(db, body);
|
||||
if let Some(it) = body
|
||||
.blocks(db)
|
||||
.find_map(|block| resolve_macro_call_id(db, block.1, ast_id, ast_ptr))
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
ast::{self, HasModuleItem, HasName},
|
||||
};
|
||||
use thin_vec::ThinVec;
|
||||
use triomphe::Arc;
|
||||
|
||||
use crate::{
|
||||
AssocItemId, AstIdWithPath, ConstLoc, FunctionId, FunctionLoc, ImplId, ItemContainerId,
|
||||
@@ -133,14 +132,14 @@ pub fn macro_calls(&self) -> impl Iterator<Item = (AstId<ast::Item>, MacroCallId
|
||||
}
|
||||
}
|
||||
|
||||
struct AssocItemCollector<'a> {
|
||||
db: &'a dyn DefDatabase,
|
||||
struct AssocItemCollector<'db> {
|
||||
db: &'db dyn DefDatabase,
|
||||
module_id: ModuleId,
|
||||
def_map: &'a DefMap,
|
||||
local_def_map: &'a LocalDefMap,
|
||||
ast_id_map: Arc<AstIdMap>,
|
||||
def_map: &'db DefMap,
|
||||
local_def_map: &'db LocalDefMap,
|
||||
ast_id_map: &'db AstIdMap,
|
||||
span_map: SpanMap,
|
||||
cfg_options: &'a CfgOptions,
|
||||
cfg_options: &'db CfgOptions,
|
||||
file_id: HirFileId,
|
||||
diagnostics: Vec<DefDiagnostic>,
|
||||
container: ItemContainerId,
|
||||
@@ -150,9 +149,9 @@ struct AssocItemCollector<'a> {
|
||||
macro_calls: ThinVec<(AstId<ast::Item>, MacroCallId)>,
|
||||
}
|
||||
|
||||
impl<'a> AssocItemCollector<'a> {
|
||||
impl<'db> AssocItemCollector<'db> {
|
||||
fn new(
|
||||
db: &'a dyn DefDatabase,
|
||||
db: &'db dyn DefDatabase,
|
||||
module_id: ModuleId,
|
||||
container: ItemContainerId,
|
||||
file_id: HirFileId,
|
||||
|
||||
@@ -166,15 +166,15 @@ fn no() {}
|
||||
[
|
||||
"crate_local_def_map",
|
||||
"file_item_tree_query",
|
||||
"ast_id_map_shim",
|
||||
"ast_id_map",
|
||||
"parse_shim",
|
||||
"real_span_map_shim",
|
||||
"file_item_tree_query",
|
||||
"ast_id_map_shim",
|
||||
"ast_id_map",
|
||||
"parse_shim",
|
||||
"real_span_map_shim",
|
||||
"file_item_tree_query",
|
||||
"ast_id_map_shim",
|
||||
"ast_id_map",
|
||||
"parse_shim",
|
||||
"real_span_map_shim",
|
||||
"EnumVariants::of_",
|
||||
@@ -183,7 +183,7 @@ fn no() {}
|
||||
expect![[r#"
|
||||
[
|
||||
"parse_shim",
|
||||
"ast_id_map_shim",
|
||||
"ast_id_map",
|
||||
"file_item_tree_query",
|
||||
"real_span_map_shim",
|
||||
"EnumVariants::of_",
|
||||
@@ -224,21 +224,21 @@ pub struct S {}
|
||||
[
|
||||
"crate_local_def_map",
|
||||
"file_item_tree_query",
|
||||
"ast_id_map_shim",
|
||||
"ast_id_map",
|
||||
"parse_shim",
|
||||
"real_span_map_shim",
|
||||
"decl_macro_expander_shim",
|
||||
"file_item_tree_query",
|
||||
"ast_id_map_shim",
|
||||
"ast_id_map",
|
||||
"parse_shim",
|
||||
"real_span_map_shim",
|
||||
"file_item_tree_query",
|
||||
"ast_id_map_shim",
|
||||
"ast_id_map",
|
||||
"parse_shim",
|
||||
"real_span_map_shim",
|
||||
"macro_def_shim",
|
||||
"file_item_tree_query",
|
||||
"ast_id_map_shim",
|
||||
"ast_id_map",
|
||||
"parse_macro_expansion_shim",
|
||||
"macro_arg_shim",
|
||||
]
|
||||
@@ -246,12 +246,12 @@ pub struct S {}
|
||||
expect![[r#"
|
||||
[
|
||||
"parse_shim",
|
||||
"ast_id_map_shim",
|
||||
"ast_id_map",
|
||||
"file_item_tree_query",
|
||||
"real_span_map_shim",
|
||||
"macro_arg_shim",
|
||||
"parse_macro_expansion_shim",
|
||||
"ast_id_map_shim",
|
||||
"ast_id_map",
|
||||
"file_item_tree_query",
|
||||
]
|
||||
"#]],
|
||||
@@ -282,26 +282,26 @@ fn f() { foo }
|
||||
[
|
||||
"crate_local_def_map",
|
||||
"file_item_tree_query",
|
||||
"ast_id_map_shim",
|
||||
"ast_id_map",
|
||||
"parse_shim",
|
||||
"real_span_map_shim",
|
||||
"crate_local_def_map",
|
||||
"proc_macros_for_crate_shim",
|
||||
"file_item_tree_query",
|
||||
"ast_id_map_shim",
|
||||
"ast_id_map",
|
||||
"parse_shim",
|
||||
"real_span_map_shim",
|
||||
"file_item_tree_query",
|
||||
"ast_id_map_shim",
|
||||
"ast_id_map",
|
||||
"parse_shim",
|
||||
"real_span_map_shim",
|
||||
"file_item_tree_query",
|
||||
"ast_id_map_shim",
|
||||
"ast_id_map",
|
||||
"parse_shim",
|
||||
"real_span_map_shim",
|
||||
"macro_def_shim",
|
||||
"file_item_tree_query",
|
||||
"ast_id_map_shim",
|
||||
"ast_id_map",
|
||||
"parse_macro_expansion_shim",
|
||||
"expand_proc_macro_shim",
|
||||
"macro_arg_shim",
|
||||
@@ -311,13 +311,13 @@ fn f() { foo }
|
||||
expect![[r#"
|
||||
[
|
||||
"parse_shim",
|
||||
"ast_id_map_shim",
|
||||
"ast_id_map",
|
||||
"file_item_tree_query",
|
||||
"real_span_map_shim",
|
||||
"macro_arg_shim",
|
||||
"expand_proc_macro_shim",
|
||||
"parse_macro_expansion_shim",
|
||||
"ast_id_map_shim",
|
||||
"ast_id_map",
|
||||
"file_item_tree_query",
|
||||
]
|
||||
"#]],
|
||||
@@ -406,38 +406,38 @@ pub struct S {}
|
||||
[
|
||||
"crate_local_def_map",
|
||||
"file_item_tree_query",
|
||||
"ast_id_map_shim",
|
||||
"ast_id_map",
|
||||
"parse_shim",
|
||||
"real_span_map_shim",
|
||||
"crate_local_def_map",
|
||||
"proc_macros_for_crate_shim",
|
||||
"file_item_tree_query",
|
||||
"ast_id_map_shim",
|
||||
"ast_id_map",
|
||||
"parse_shim",
|
||||
"real_span_map_shim",
|
||||
"decl_macro_expander_shim",
|
||||
"file_item_tree_query",
|
||||
"ast_id_map_shim",
|
||||
"ast_id_map",
|
||||
"parse_shim",
|
||||
"real_span_map_shim",
|
||||
"file_item_tree_query",
|
||||
"ast_id_map_shim",
|
||||
"ast_id_map",
|
||||
"parse_shim",
|
||||
"real_span_map_shim",
|
||||
"macro_def_shim",
|
||||
"file_item_tree_query",
|
||||
"ast_id_map_shim",
|
||||
"ast_id_map",
|
||||
"parse_macro_expansion_shim",
|
||||
"macro_arg_shim",
|
||||
"decl_macro_expander_shim",
|
||||
"macro_def_shim",
|
||||
"file_item_tree_query",
|
||||
"ast_id_map_shim",
|
||||
"ast_id_map",
|
||||
"parse_macro_expansion_shim",
|
||||
"macro_arg_shim",
|
||||
"macro_def_shim",
|
||||
"file_item_tree_query",
|
||||
"ast_id_map_shim",
|
||||
"ast_id_map",
|
||||
"parse_macro_expansion_shim",
|
||||
"expand_proc_macro_shim",
|
||||
"macro_arg_shim",
|
||||
@@ -447,7 +447,7 @@ pub struct S {}
|
||||
expect![[r#"
|
||||
[
|
||||
"parse_shim",
|
||||
"ast_id_map_shim",
|
||||
"ast_id_map",
|
||||
"file_item_tree_query",
|
||||
"real_span_map_shim",
|
||||
"macro_arg_shim",
|
||||
@@ -523,29 +523,29 @@ fn quux() { 1$0 }
|
||||
[
|
||||
"crate_local_def_map",
|
||||
"file_item_tree_query",
|
||||
"ast_id_map_shim",
|
||||
"ast_id_map",
|
||||
"parse_shim",
|
||||
"real_span_map_shim",
|
||||
"decl_macro_expander_shim",
|
||||
"file_item_tree_query",
|
||||
"ast_id_map_shim",
|
||||
"ast_id_map",
|
||||
"parse_shim",
|
||||
"real_span_map_shim",
|
||||
"file_item_tree_query",
|
||||
"ast_id_map_shim",
|
||||
"ast_id_map",
|
||||
"parse_shim",
|
||||
"real_span_map_shim",
|
||||
"macro_def_shim",
|
||||
"file_item_tree_query",
|
||||
"ast_id_map_shim",
|
||||
"ast_id_map",
|
||||
"parse_macro_expansion_shim",
|
||||
"macro_arg_shim",
|
||||
"file_item_tree_query",
|
||||
"ast_id_map_shim",
|
||||
"ast_id_map",
|
||||
"parse_macro_expansion_shim",
|
||||
"macro_arg_shim",
|
||||
"file_item_tree_query",
|
||||
"ast_id_map_shim",
|
||||
"ast_id_map",
|
||||
"parse_macro_expansion_shim",
|
||||
"macro_arg_shim",
|
||||
]
|
||||
@@ -572,7 +572,7 @@ fn quux() { 92 }
|
||||
expect![[r#"
|
||||
[
|
||||
"parse_shim",
|
||||
"ast_id_map_shim",
|
||||
"ast_id_map",
|
||||
"file_item_tree_query",
|
||||
"real_span_map_shim",
|
||||
"macro_arg_shim",
|
||||
@@ -610,7 +610,7 @@ impl Tr for () {}
|
||||
expect![[r#"
|
||||
[
|
||||
"file_item_tree_query",
|
||||
"ast_id_map_shim",
|
||||
"ast_id_map",
|
||||
"parse_shim",
|
||||
"real_span_map_shim",
|
||||
]
|
||||
@@ -630,7 +630,7 @@ impl Tr for () {}
|
||||
expect![[r#"
|
||||
[
|
||||
"parse_shim",
|
||||
"ast_id_map_shim",
|
||||
"ast_id_map",
|
||||
"file_item_tree_query",
|
||||
"real_span_map_shim",
|
||||
]
|
||||
|
||||
@@ -13,14 +13,13 @@
|
||||
use smallvec::{SmallVec, smallvec};
|
||||
use span::SyntaxContext;
|
||||
use syntax::ast::HasName;
|
||||
use triomphe::Arc;
|
||||
|
||||
use crate::{
|
||||
AdtId, AstIdLoc, ConstId, ConstParamId, DefWithBodyId, EnumId, EnumVariantId, ExternBlockId,
|
||||
ExternCrateId, FunctionId, FxIndexMap, GenericDefId, GenericParamId, HasModule, ImplId,
|
||||
ItemContainerId, LifetimeParamId, Lookup, Macro2Id, MacroId, MacroRulesId, ModuleDefId,
|
||||
ModuleId, ProcMacroId, StaticId, StructId, TraitId, TypeAliasId, TypeOrConstParamId,
|
||||
TypeParamId, UseId, VariantId,
|
||||
AdtId, AstIdLoc, ConstId, ConstParamId, DefWithBodyId, EnumId, EnumVariantId,
|
||||
ExpressionStoreOwnerId, ExternBlockId, ExternCrateId, FunctionId, FxIndexMap, GenericDefId,
|
||||
GenericParamId, HasModule, ImplId, ItemContainerId, LifetimeParamId, Lookup, Macro2Id, MacroId,
|
||||
MacroRulesId, ModuleDefId, ModuleId, ProcMacroId, StaticId, StructId, TraitId, TypeAliasId,
|
||||
TypeOrConstParamId, TypeParamId, UseId, VariantId,
|
||||
builtin_type::BuiltinType,
|
||||
db::DefDatabase,
|
||||
expr_store::{
|
||||
@@ -36,6 +35,7 @@
|
||||
lang_item::LangItemTarget,
|
||||
nameres::{DefMap, LocalDefMap, MacroSubNs, ResolvePathResultPrefixInfo, block_def_map},
|
||||
per_ns::PerNs,
|
||||
signatures::ImplSignature,
|
||||
src::HasSource,
|
||||
type_ref::LifetimeRef,
|
||||
visibility::{RawVisibility, Visibility},
|
||||
@@ -65,13 +65,13 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
struct ExprScope {
|
||||
owner: DefWithBodyId,
|
||||
expr_scopes: Arc<ExprScopes>,
|
||||
struct ExprScope<'db> {
|
||||
owner: ExpressionStoreOwnerId,
|
||||
expr_scopes: &'db ExprScopes,
|
||||
scope_id: ScopeId,
|
||||
}
|
||||
|
||||
impl fmt::Debug for ExprScope {
|
||||
impl fmt::Debug for ExprScope<'_> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.debug_struct("ExprScope")
|
||||
.field("owner", &self.owner)
|
||||
@@ -86,9 +86,9 @@ enum Scope<'db> {
|
||||
BlockScope(ModuleItemMap<'db>),
|
||||
/// Brings the generic parameters of an item into scope as well as the `Self` type alias /
|
||||
/// generic for ADTs and impls.
|
||||
GenericParams { def: GenericDefId, params: Arc<GenericParams> },
|
||||
GenericParams { def: GenericDefId, params: &'db GenericParams },
|
||||
/// Local bindings
|
||||
ExprScope(ExprScope),
|
||||
ExprScope(ExprScope<'db>),
|
||||
/// Macro definition inside bodies that affects all paths after it in the same block.
|
||||
MacroDefScope(MacroDefId),
|
||||
}
|
||||
@@ -653,7 +653,7 @@ pub fn traits_in_scope(&self, db: &dyn DefDatabase) -> FxHashSet<TraitId> {
|
||||
match scope {
|
||||
Scope::BlockScope(m) => traits.extend(m.def_map[m.module_id].scope.traits()),
|
||||
&Scope::GenericParams { def: GenericDefId::ImplId(impl_), .. } => {
|
||||
let impl_data = db.impl_signature(impl_);
|
||||
let impl_data = ImplSignature::of(db, impl_);
|
||||
if let Some(target_trait) = impl_data.target_trait
|
||||
&& let Some(TypeNs::TraitId(trait_)) = self
|
||||
.resolve_path_in_type_ns_fully(db, &impl_data.store[target_trait.path])
|
||||
@@ -724,19 +724,19 @@ pub fn generic_def(&self) -> Option<GenericDefId> {
|
||||
|
||||
pub fn generic_params(&self) -> Option<&GenericParams> {
|
||||
self.scopes().find_map(|scope| match scope {
|
||||
Scope::GenericParams { params, .. } => Some(&**params),
|
||||
&Scope::GenericParams { params, .. } => Some(params),
|
||||
_ => None,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn all_generic_params(&self) -> impl Iterator<Item = (&GenericParams, &GenericDefId)> {
|
||||
pub fn all_generic_params(&self) -> impl Iterator<Item = (&GenericParams, GenericDefId)> {
|
||||
self.scopes().filter_map(|scope| match scope {
|
||||
Scope::GenericParams { params, def } => Some((&**params, def)),
|
||||
&Scope::GenericParams { params, def } => Some((params, def)),
|
||||
_ => None,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn body_owner(&self) -> Option<DefWithBodyId> {
|
||||
pub fn expression_store_owner(&self) -> Option<ExpressionStoreOwnerId> {
|
||||
self.scopes().find_map(|scope| match scope {
|
||||
Scope::ExprScope(it) => Some(it.owner),
|
||||
_ => None,
|
||||
@@ -854,25 +854,30 @@ pub fn rename_will_conflict_with_renamed(
|
||||
pub fn update_to_inner_scope(
|
||||
&mut self,
|
||||
db: &'db dyn DefDatabase,
|
||||
owner: DefWithBodyId,
|
||||
owner: impl Into<ExpressionStoreOwnerId>,
|
||||
expr_id: ExprId,
|
||||
) -> UpdateGuard {
|
||||
self.update_to_inner_scope_(db, owner.into(), expr_id)
|
||||
}
|
||||
|
||||
fn update_to_inner_scope_(
|
||||
&mut self,
|
||||
db: &'db dyn DefDatabase,
|
||||
owner: ExpressionStoreOwnerId,
|
||||
expr_id: ExprId,
|
||||
) -> UpdateGuard {
|
||||
#[inline(always)]
|
||||
fn append_expr_scope<'db>(
|
||||
db: &'db dyn DefDatabase,
|
||||
resolver: &mut Resolver<'db>,
|
||||
owner: DefWithBodyId,
|
||||
expr_scopes: &Arc<ExprScopes>,
|
||||
owner: ExpressionStoreOwnerId,
|
||||
expr_scopes: &'db ExprScopes,
|
||||
scope_id: ScopeId,
|
||||
) {
|
||||
if let Some(macro_id) = expr_scopes.macro_def(scope_id) {
|
||||
resolver.scopes.push(Scope::MacroDefScope(**macro_id));
|
||||
}
|
||||
resolver.scopes.push(Scope::ExprScope(ExprScope {
|
||||
owner,
|
||||
expr_scopes: expr_scopes.clone(),
|
||||
scope_id,
|
||||
}));
|
||||
resolver.scopes.push(Scope::ExprScope(ExprScope { owner, expr_scopes, scope_id }));
|
||||
if let Some(block) = expr_scopes.block(scope_id) {
|
||||
let def_map = block_def_map(db, block);
|
||||
let local_def_map = block.lookup(db).module.only_local_def_map(db);
|
||||
@@ -890,21 +895,20 @@ fn append_expr_scope<'db>(
|
||||
let start = self.scopes.len();
|
||||
let innermost_scope = self.scopes().find(|scope| !matches!(scope, Scope::MacroDefScope(_)));
|
||||
match innermost_scope {
|
||||
Some(&Scope::ExprScope(ExprScope { scope_id, ref expr_scopes, owner })) => {
|
||||
let expr_scopes = expr_scopes.clone();
|
||||
Some(&Scope::ExprScope(ExprScope { scope_id, expr_scopes, owner })) => {
|
||||
let scope_chain = expr_scopes
|
||||
.scope_chain(expr_scopes.scope_for(expr_id))
|
||||
.take_while(|&it| it != scope_id);
|
||||
for scope_id in scope_chain {
|
||||
append_expr_scope(db, self, owner, &expr_scopes, scope_id);
|
||||
append_expr_scope(db, self, owner, expr_scopes, scope_id);
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
let expr_scopes = db.expr_scopes(owner);
|
||||
let expr_scopes = ExprScopes::of(db, owner);
|
||||
let scope_chain = expr_scopes.scope_chain(expr_scopes.scope_for(expr_id));
|
||||
|
||||
for scope_id in scope_chain {
|
||||
append_expr_scope(db, self, owner, &expr_scopes, scope_id);
|
||||
append_expr_scope(db, self, owner, expr_scopes, scope_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1016,7 +1020,7 @@ fn process_names(&self, acc: &mut ScopeNames, db: &'db dyn DefDatabase) {
|
||||
})
|
||||
});
|
||||
}
|
||||
&Scope::GenericParams { ref params, def: parent } => {
|
||||
&Scope::GenericParams { params, def: parent } => {
|
||||
if let GenericDefId::ImplId(impl_) = parent {
|
||||
acc.add(&Name::new_symbol_root(sym::Self_), ScopeDef::ImplSelfType(impl_));
|
||||
} else if let GenericDefId::AdtId(adt) = parent {
|
||||
@@ -1026,7 +1030,7 @@ fn process_names(&self, acc: &mut ScopeNames, db: &'db dyn DefDatabase) {
|
||||
for (local_id, param) in params.iter_type_or_consts() {
|
||||
if let Some(name) = ¶m.name() {
|
||||
let id = TypeOrConstParamId { parent, local_id };
|
||||
let data = &db.generic_params(parent)[local_id];
|
||||
let data = &GenericParams::of(db, parent)[local_id];
|
||||
acc.add(
|
||||
name,
|
||||
ScopeDef::GenericParam(match data {
|
||||
@@ -1060,20 +1064,21 @@ fn process_names(&self, acc: &mut ScopeNames, db: &'db dyn DefDatabase) {
|
||||
|
||||
pub fn resolver_for_scope(
|
||||
db: &dyn DefDatabase,
|
||||
owner: DefWithBodyId,
|
||||
owner: impl Into<ExpressionStoreOwnerId> + HasResolver,
|
||||
scope_id: Option<ScopeId>,
|
||||
) -> Resolver<'_> {
|
||||
let r = owner.resolver(db);
|
||||
let scopes = db.expr_scopes(owner);
|
||||
resolver_for_scope_(db, scopes, scope_id, r, owner)
|
||||
let store_owner = owner.into();
|
||||
let r = store_owner.resolver(db);
|
||||
let scopes = ExprScopes::of(db, store_owner);
|
||||
resolver_for_scope_(db, scopes, scope_id, r, store_owner)
|
||||
}
|
||||
|
||||
fn resolver_for_scope_<'db>(
|
||||
db: &'db dyn DefDatabase,
|
||||
scopes: Arc<ExprScopes>,
|
||||
scopes: &'db ExprScopes,
|
||||
scope_id: Option<ScopeId>,
|
||||
mut r: Resolver<'db>,
|
||||
owner: DefWithBodyId,
|
||||
owner: ExpressionStoreOwnerId,
|
||||
) -> Resolver<'db> {
|
||||
let scope_chain = scopes.scope_chain(scope_id).collect::<Vec<_>>();
|
||||
r.scopes.reserve(scope_chain.len());
|
||||
@@ -1093,7 +1098,7 @@ fn resolver_for_scope_<'db>(
|
||||
r = r.push_scope(Scope::MacroDefScope(**macro_id));
|
||||
}
|
||||
|
||||
r = r.push_expr_scope(owner, Arc::clone(&scopes), scope);
|
||||
r = r.push_expr_scope(owner, scopes, scope);
|
||||
}
|
||||
r
|
||||
}
|
||||
@@ -1109,7 +1114,7 @@ fn push_generic_params_scope(
|
||||
db: &'db dyn DefDatabase,
|
||||
def: GenericDefId,
|
||||
) -> Resolver<'db> {
|
||||
let params = db.generic_params(def);
|
||||
let params = GenericParams::of(db, def);
|
||||
self.push_scope(Scope::GenericParams { def, params })
|
||||
}
|
||||
|
||||
@@ -1124,8 +1129,8 @@ fn push_block_scope(
|
||||
|
||||
fn push_expr_scope(
|
||||
self,
|
||||
owner: DefWithBodyId,
|
||||
expr_scopes: Arc<ExprScopes>,
|
||||
owner: ExpressionStoreOwnerId,
|
||||
expr_scopes: &'db ExprScopes,
|
||||
scope_id: ScopeId,
|
||||
) -> Resolver<'db> {
|
||||
self.push_scope(Scope::ExprScope(ExprScope { owner, expr_scopes, scope_id }))
|
||||
@@ -1409,6 +1414,16 @@ fn resolver(self, db: &dyn DefDatabase) -> Resolver<'_> {
|
||||
}
|
||||
}
|
||||
|
||||
impl HasResolver for ExpressionStoreOwnerId {
|
||||
fn resolver(self, db: &dyn DefDatabase) -> Resolver<'_> {
|
||||
match self {
|
||||
ExpressionStoreOwnerId::Signature(def) => def.resolver(db),
|
||||
ExpressionStoreOwnerId::Body(def) => def.resolver(db),
|
||||
ExpressionStoreOwnerId::VariantFields(variant_id) => variant_id.resolver(db),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl HasResolver for EnumVariantId {
|
||||
fn resolver(self, db: &dyn DefDatabase) -> Resolver<'_> {
|
||||
self.lookup(db).parent.resolver(db)
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
attrs::AttrFlags,
|
||||
db::DefDatabase,
|
||||
expr_store::{
|
||||
ExpressionStore, ExpressionStoreSourceMap,
|
||||
Body, ExpressionStore, ExpressionStoreBuilder, ExpressionStoreSourceMap,
|
||||
lower::{
|
||||
ExprCollector, lower_function, lower_generic_params, lower_trait, lower_type_alias,
|
||||
},
|
||||
@@ -32,7 +32,7 @@
|
||||
hir::{ExprId, PatId, generics::GenericParams},
|
||||
item_tree::{FieldsShape, RawVisibility, visibility_from_ast},
|
||||
src::HasSource,
|
||||
type_ref::{TraitRef, TypeBound, TypeRefId},
|
||||
type_ref::{ConstRef, TraitRef, TypeBound, TypeRefId},
|
||||
};
|
||||
|
||||
#[inline]
|
||||
@@ -43,8 +43,8 @@ fn as_name_opt(name: Option<ast::Name>) -> Name {
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
pub struct StructSignature {
|
||||
pub name: Name,
|
||||
pub generic_params: Arc<GenericParams>,
|
||||
pub store: Arc<ExpressionStore>,
|
||||
pub generic_params: GenericParams,
|
||||
pub store: ExpressionStore,
|
||||
pub flags: StructFlags,
|
||||
pub shape: FieldsShape,
|
||||
}
|
||||
@@ -71,8 +71,18 @@ pub struct StructFlags: u8 {
|
||||
}
|
||||
}
|
||||
|
||||
#[salsa::tracked]
|
||||
impl StructSignature {
|
||||
pub fn query(db: &dyn DefDatabase, id: StructId) -> (Arc<Self>, Arc<ExpressionStoreSourceMap>) {
|
||||
#[salsa::tracked(returns(deref))]
|
||||
pub fn of(db: &dyn DefDatabase, id: StructId) -> Arc<Self> {
|
||||
Self::with_source_map(db, id).0.clone()
|
||||
}
|
||||
|
||||
#[salsa::tracked(returns(ref))]
|
||||
pub fn with_source_map(
|
||||
db: &dyn DefDatabase,
|
||||
id: StructId,
|
||||
) -> (Arc<Self>, ExpressionStoreSourceMap) {
|
||||
let loc = id.lookup(db);
|
||||
let InFile { file_id, value: source } = loc.source(db);
|
||||
let attrs = AttrFlags::query(db, id.into());
|
||||
@@ -115,10 +125,12 @@ pub fn query(db: &dyn DefDatabase, id: StructId) -> (Arc<Self>, Arc<ExpressionSt
|
||||
shape,
|
||||
name: as_name_opt(source.name()),
|
||||
}),
|
||||
Arc::new(source_map),
|
||||
source_map,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl StructSignature {
|
||||
#[inline]
|
||||
pub fn repr(&self, db: &dyn DefDatabase, id: StructId) -> Option<ReprOptions> {
|
||||
if self.flags.contains(StructFlags::HAS_REPR) {
|
||||
@@ -141,13 +153,23 @@ fn adt_shape(adt_kind: ast::StructKind) -> FieldsShape {
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
pub struct UnionSignature {
|
||||
pub name: Name,
|
||||
pub generic_params: Arc<GenericParams>,
|
||||
pub store: Arc<ExpressionStore>,
|
||||
pub generic_params: GenericParams,
|
||||
pub store: ExpressionStore,
|
||||
pub flags: StructFlags,
|
||||
}
|
||||
|
||||
#[salsa::tracked]
|
||||
impl UnionSignature {
|
||||
pub fn query(db: &dyn DefDatabase, id: UnionId) -> (Arc<Self>, Arc<ExpressionStoreSourceMap>) {
|
||||
#[salsa::tracked(returns(deref))]
|
||||
pub fn of(db: &dyn DefDatabase, id: UnionId) -> Arc<Self> {
|
||||
Self::with_source_map(db, id).0.clone()
|
||||
}
|
||||
|
||||
#[salsa::tracked(returns(ref))]
|
||||
pub fn with_source_map(
|
||||
db: &dyn DefDatabase,
|
||||
id: UnionId,
|
||||
) -> (Arc<Self>, ExpressionStoreSourceMap) {
|
||||
let loc = id.lookup(db);
|
||||
let attrs = AttrFlags::query(db, id.into());
|
||||
let mut flags = StructFlags::empty();
|
||||
@@ -177,7 +199,7 @@ pub fn query(db: &dyn DefDatabase, id: UnionId) -> (Arc<Self>, Arc<ExpressionSto
|
||||
flags,
|
||||
name: as_name_opt(source.name()),
|
||||
}),
|
||||
Arc::new(source_map),
|
||||
source_map,
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -195,13 +217,23 @@ pub struct EnumFlags: u8 {
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
pub struct EnumSignature {
|
||||
pub name: Name,
|
||||
pub generic_params: Arc<GenericParams>,
|
||||
pub store: Arc<ExpressionStore>,
|
||||
pub generic_params: GenericParams,
|
||||
pub store: ExpressionStore,
|
||||
pub flags: EnumFlags,
|
||||
}
|
||||
|
||||
#[salsa::tracked]
|
||||
impl EnumSignature {
|
||||
pub fn query(db: &dyn DefDatabase, id: EnumId) -> (Arc<Self>, Arc<ExpressionStoreSourceMap>) {
|
||||
#[salsa::tracked(returns(deref))]
|
||||
pub fn of(db: &dyn DefDatabase, id: EnumId) -> Arc<Self> {
|
||||
Self::with_source_map(db, id).0.clone()
|
||||
}
|
||||
|
||||
#[salsa::tracked(returns(ref))]
|
||||
pub fn with_source_map(
|
||||
db: &dyn DefDatabase,
|
||||
id: EnumId,
|
||||
) -> (Arc<Self>, ExpressionStoreSourceMap) {
|
||||
let loc = id.lookup(db);
|
||||
let attrs = AttrFlags::query(db, id.into());
|
||||
let mut flags = EnumFlags::empty();
|
||||
@@ -229,10 +261,12 @@ pub fn query(db: &dyn DefDatabase, id: EnumId) -> (Arc<Self>, Arc<ExpressionStor
|
||||
flags,
|
||||
name: as_name_opt(source.name()),
|
||||
}),
|
||||
Arc::new(source_map),
|
||||
source_map,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl EnumSignature {
|
||||
pub fn variant_body_type(db: &dyn DefDatabase, id: EnumId) -> IntegerType {
|
||||
match AttrFlags::repr(db, id.into()) {
|
||||
Some(ReprOptions { int: Some(builtin), .. }) => builtin,
|
||||
@@ -256,14 +290,24 @@ pub struct ConstFlags: u8 {
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
pub struct ConstSignature {
|
||||
pub name: Option<Name>,
|
||||
// generic_params: Arc<GenericParams>,
|
||||
pub store: Arc<ExpressionStore>,
|
||||
// generic_params: GenericParams,
|
||||
pub store: ExpressionStore,
|
||||
pub type_ref: TypeRefId,
|
||||
pub flags: ConstFlags,
|
||||
}
|
||||
|
||||
#[salsa::tracked]
|
||||
impl ConstSignature {
|
||||
pub fn query(db: &dyn DefDatabase, id: ConstId) -> (Arc<Self>, Arc<ExpressionStoreSourceMap>) {
|
||||
#[salsa::tracked(returns(deref))]
|
||||
pub fn of(db: &dyn DefDatabase, id: ConstId) -> Arc<Self> {
|
||||
Self::with_source_map(db, id).0.clone()
|
||||
}
|
||||
|
||||
#[salsa::tracked(returns(ref))]
|
||||
pub fn with_source_map(
|
||||
db: &dyn DefDatabase,
|
||||
id: ConstId,
|
||||
) -> (Arc<Self>, ExpressionStoreSourceMap) {
|
||||
let loc = id.lookup(db);
|
||||
|
||||
let module = loc.container.module(db);
|
||||
@@ -282,15 +326,17 @@ pub fn query(db: &dyn DefDatabase, id: ConstId) -> (Arc<Self>, Arc<ExpressionSto
|
||||
|
||||
(
|
||||
Arc::new(ConstSignature {
|
||||
store: Arc::new(store),
|
||||
store,
|
||||
type_ref,
|
||||
flags,
|
||||
name: source.value.name().map(|it| it.as_name()),
|
||||
}),
|
||||
Arc::new(source_map),
|
||||
source_map,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl ConstSignature {
|
||||
pub fn has_body(&self) -> bool {
|
||||
self.flags.contains(ConstFlags::HAS_BODY)
|
||||
}
|
||||
@@ -312,13 +358,24 @@ pub struct StaticFlags: u8 {
|
||||
pub struct StaticSignature {
|
||||
pub name: Name,
|
||||
|
||||
// generic_params: Arc<GenericParams>,
|
||||
pub store: Arc<ExpressionStore>,
|
||||
// generic_params: GenericParams,
|
||||
pub store: ExpressionStore,
|
||||
pub type_ref: TypeRefId,
|
||||
pub flags: StaticFlags,
|
||||
}
|
||||
|
||||
#[salsa::tracked]
|
||||
impl StaticSignature {
|
||||
pub fn query(db: &dyn DefDatabase, id: StaticId) -> (Arc<Self>, Arc<ExpressionStoreSourceMap>) {
|
||||
#[salsa::tracked(returns(deref))]
|
||||
pub fn of(db: &dyn DefDatabase, id: StaticId) -> Arc<Self> {
|
||||
Self::with_source_map(db, id).0.clone()
|
||||
}
|
||||
|
||||
#[salsa::tracked(returns(ref))]
|
||||
pub fn with_source_map(
|
||||
db: &dyn DefDatabase,
|
||||
id: StaticId,
|
||||
) -> (Arc<Self>, ExpressionStoreSourceMap) {
|
||||
let loc = id.lookup(db);
|
||||
|
||||
let module = loc.container.module(db);
|
||||
@@ -351,12 +408,12 @@ pub fn query(db: &dyn DefDatabase, id: StaticId) -> (Arc<Self>, Arc<ExpressionSt
|
||||
|
||||
(
|
||||
Arc::new(StaticSignature {
|
||||
store: Arc::new(store),
|
||||
store,
|
||||
type_ref,
|
||||
flags,
|
||||
name: as_name_opt(source.value.name()),
|
||||
}),
|
||||
Arc::new(source_map),
|
||||
source_map,
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -372,15 +429,25 @@ pub struct ImplFlags: u8 {
|
||||
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
pub struct ImplSignature {
|
||||
pub generic_params: Arc<GenericParams>,
|
||||
pub store: Arc<ExpressionStore>,
|
||||
pub generic_params: GenericParams,
|
||||
pub store: ExpressionStore,
|
||||
pub self_ty: TypeRefId,
|
||||
pub target_trait: Option<TraitRef>,
|
||||
pub flags: ImplFlags,
|
||||
}
|
||||
|
||||
#[salsa::tracked]
|
||||
impl ImplSignature {
|
||||
pub fn query(db: &dyn DefDatabase, id: ImplId) -> (Arc<Self>, Arc<ExpressionStoreSourceMap>) {
|
||||
#[salsa::tracked(returns(deref))]
|
||||
pub fn of(db: &dyn DefDatabase, id: ImplId) -> Arc<Self> {
|
||||
Self::with_source_map(db, id).0.clone()
|
||||
}
|
||||
|
||||
#[salsa::tracked(returns(ref))]
|
||||
pub fn with_source_map(
|
||||
db: &dyn DefDatabase,
|
||||
id: ImplId,
|
||||
) -> (Arc<Self>, ExpressionStoreSourceMap) {
|
||||
let loc = id.lookup(db);
|
||||
|
||||
let mut flags = ImplFlags::empty();
|
||||
@@ -399,17 +466,13 @@ pub fn query(db: &dyn DefDatabase, id: ImplId) -> (Arc<Self>, Arc<ExpressionStor
|
||||
crate::expr_store::lower::lower_impl(db, loc.container, src, id);
|
||||
|
||||
(
|
||||
Arc::new(ImplSignature {
|
||||
store: Arc::new(store),
|
||||
generic_params,
|
||||
self_ty,
|
||||
target_trait,
|
||||
flags,
|
||||
}),
|
||||
Arc::new(source_map),
|
||||
Arc::new(ImplSignature { store, generic_params, self_ty, target_trait, flags }),
|
||||
source_map,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl ImplSignature {
|
||||
#[inline]
|
||||
pub fn is_negative(&self) -> bool {
|
||||
self.flags.contains(ImplFlags::NEGATIVE)
|
||||
@@ -439,13 +502,23 @@ pub struct TraitFlags: u16 {
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
pub struct TraitSignature {
|
||||
pub name: Name,
|
||||
pub generic_params: Arc<GenericParams>,
|
||||
pub store: Arc<ExpressionStore>,
|
||||
pub generic_params: GenericParams,
|
||||
pub store: ExpressionStore,
|
||||
pub flags: TraitFlags,
|
||||
}
|
||||
|
||||
#[salsa::tracked]
|
||||
impl TraitSignature {
|
||||
pub fn query(db: &dyn DefDatabase, id: TraitId) -> (Arc<Self>, Arc<ExpressionStoreSourceMap>) {
|
||||
#[salsa::tracked(returns(deref))]
|
||||
pub fn of(db: &dyn DefDatabase, id: TraitId) -> Arc<Self> {
|
||||
Self::with_source_map(db, id).0.clone()
|
||||
}
|
||||
|
||||
#[salsa::tracked(returns(ref))]
|
||||
pub fn with_source_map(
|
||||
db: &dyn DefDatabase,
|
||||
id: TraitId,
|
||||
) -> (Arc<Self>, ExpressionStoreSourceMap) {
|
||||
let loc = id.lookup(db);
|
||||
|
||||
let mut flags = TraitFlags::empty();
|
||||
@@ -483,10 +556,7 @@ pub fn query(db: &dyn DefDatabase, id: TraitId) -> (Arc<Self>, Arc<ExpressionSto
|
||||
let name = as_name_opt(source.value.name());
|
||||
let (store, source_map, generic_params) = lower_trait(db, loc.container, source, id);
|
||||
|
||||
(
|
||||
Arc::new(TraitSignature { store: Arc::new(store), generic_params, flags, name }),
|
||||
Arc::new(source_map),
|
||||
)
|
||||
(Arc::new(TraitSignature { store, generic_params, flags, name }), source_map)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -516,19 +586,26 @@ pub struct FnFlags: u16 {
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
pub struct FunctionSignature {
|
||||
pub name: Name,
|
||||
pub generic_params: Arc<GenericParams>,
|
||||
pub store: Arc<ExpressionStore>,
|
||||
pub generic_params: GenericParams,
|
||||
pub store: ExpressionStore,
|
||||
pub params: Box<[TypeRefId]>,
|
||||
pub ret_type: Option<TypeRefId>,
|
||||
pub abi: Option<Symbol>,
|
||||
pub flags: FnFlags,
|
||||
}
|
||||
|
||||
#[salsa::tracked]
|
||||
impl FunctionSignature {
|
||||
pub fn query(
|
||||
#[salsa::tracked(returns(deref))]
|
||||
pub fn of(db: &dyn DefDatabase, id: FunctionId) -> Arc<Self> {
|
||||
Self::with_source_map(db, id).0.clone()
|
||||
}
|
||||
|
||||
#[salsa::tracked(returns(ref))]
|
||||
pub fn with_source_map(
|
||||
db: &dyn DefDatabase,
|
||||
id: FunctionId,
|
||||
) -> (Arc<Self>, Arc<ExpressionStoreSourceMap>) {
|
||||
) -> (Arc<Self>, ExpressionStoreSourceMap) {
|
||||
let loc = id.lookup(db);
|
||||
let module = loc.container.module(db);
|
||||
|
||||
@@ -589,17 +666,19 @@ pub fn query(
|
||||
(
|
||||
Arc::new(FunctionSignature {
|
||||
generic_params,
|
||||
store: Arc::new(store),
|
||||
store,
|
||||
params,
|
||||
ret_type,
|
||||
abi,
|
||||
flags,
|
||||
name,
|
||||
}),
|
||||
Arc::new(source_map),
|
||||
source_map,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl FunctionSignature {
|
||||
pub fn has_body(&self) -> bool {
|
||||
self.flags.contains(FnFlags::HAS_BODY)
|
||||
}
|
||||
@@ -656,7 +735,7 @@ pub fn legacy_const_generics_indices<'db>(
|
||||
}
|
||||
|
||||
pub fn is_intrinsic(db: &dyn DefDatabase, id: FunctionId) -> bool {
|
||||
let data = db.function_signature(id);
|
||||
let data = FunctionSignature::of(db, id);
|
||||
data.flags.contains(FnFlags::RUSTC_INTRINSIC)
|
||||
// Keep this around for a bit until extern "rustc-intrinsic" abis are no longer used
|
||||
|| match &data.abi {
|
||||
@@ -683,18 +762,25 @@ pub struct TypeAliasFlags: u8 {
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
pub struct TypeAliasSignature {
|
||||
pub name: Name,
|
||||
pub generic_params: Arc<GenericParams>,
|
||||
pub store: Arc<ExpressionStore>,
|
||||
pub generic_params: GenericParams,
|
||||
pub store: ExpressionStore,
|
||||
pub bounds: Box<[TypeBound]>,
|
||||
pub ty: Option<TypeRefId>,
|
||||
pub flags: TypeAliasFlags,
|
||||
}
|
||||
|
||||
#[salsa::tracked]
|
||||
impl TypeAliasSignature {
|
||||
pub fn query(
|
||||
#[salsa::tracked(returns(deref))]
|
||||
pub fn of(db: &dyn DefDatabase, id: TypeAliasId) -> Arc<Self> {
|
||||
Self::with_source_map(db, id).0.clone()
|
||||
}
|
||||
|
||||
#[salsa::tracked(returns(ref))]
|
||||
pub fn with_source_map(
|
||||
db: &dyn DefDatabase,
|
||||
id: TypeAliasId,
|
||||
) -> (Arc<Self>, Arc<ExpressionStoreSourceMap>) {
|
||||
) -> (Arc<Self>, ExpressionStoreSourceMap) {
|
||||
let loc = id.lookup(db);
|
||||
|
||||
let mut flags = TypeAliasFlags::empty();
|
||||
@@ -714,28 +800,21 @@ pub fn query(
|
||||
lower_type_alias(db, loc.container.module(db), source, id);
|
||||
|
||||
(
|
||||
Arc::new(TypeAliasSignature {
|
||||
store: Arc::new(store),
|
||||
generic_params,
|
||||
flags,
|
||||
bounds,
|
||||
name,
|
||||
ty,
|
||||
}),
|
||||
Arc::new(source_map),
|
||||
Arc::new(TypeAliasSignature { store, generic_params, flags, bounds, name, ty }),
|
||||
source_map,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
pub struct FunctionBody {
|
||||
pub store: Arc<ExpressionStore>,
|
||||
pub store: ExpressionStore,
|
||||
pub parameters: Box<[PatId]>,
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
pub struct SimpleBody {
|
||||
pub store: Arc<ExpressionStore>,
|
||||
pub store: ExpressionStore,
|
||||
}
|
||||
pub type StaticBody = SimpleBody;
|
||||
pub type ConstBody = SimpleBody;
|
||||
@@ -743,7 +822,7 @@ pub struct SimpleBody {
|
||||
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
pub struct VariantFieldsBody {
|
||||
pub store: Arc<ExpressionStore>,
|
||||
pub store: ExpressionStore,
|
||||
pub fields: Box<[Option<ExprId>]>,
|
||||
}
|
||||
|
||||
@@ -754,7 +833,7 @@ pub struct FieldData {
|
||||
pub type_ref: TypeRefId,
|
||||
pub visibility: RawVisibility,
|
||||
pub is_unsafe: bool,
|
||||
pub default_value: Option<ExprId>,
|
||||
pub default_value: Option<ConstRef>,
|
||||
}
|
||||
|
||||
pub type LocalFieldId = Idx<FieldData>;
|
||||
@@ -762,17 +841,17 @@ pub struct FieldData {
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct VariantFields {
|
||||
fields: Arena<FieldData>,
|
||||
pub store: Arc<ExpressionStore>,
|
||||
pub store: ExpressionStore,
|
||||
pub shape: FieldsShape,
|
||||
}
|
||||
|
||||
#[salsa::tracked]
|
||||
impl VariantFields {
|
||||
#[salsa::tracked(returns(clone))]
|
||||
pub(crate) fn query(
|
||||
#[salsa::tracked(returns(ref))]
|
||||
pub fn with_source_map(
|
||||
db: &dyn DefDatabase,
|
||||
id: VariantId,
|
||||
) -> (Arc<Self>, Arc<ExpressionStoreSourceMap>) {
|
||||
) -> (Arc<Self>, ExpressionStoreSourceMap) {
|
||||
let (shape, result) = match id {
|
||||
VariantId::EnumVariantId(id) => {
|
||||
let loc = id.lookup(db);
|
||||
@@ -809,20 +888,26 @@ pub(crate) fn query(
|
||||
}
|
||||
};
|
||||
match result {
|
||||
Some((fields, store, source_map)) => (
|
||||
Arc::new(VariantFields { fields, store: Arc::new(store), shape }),
|
||||
Arc::new(source_map),
|
||||
),
|
||||
Some((fields, store, source_map)) => {
|
||||
(Arc::new(VariantFields { fields, store, shape }), source_map)
|
||||
}
|
||||
None => {
|
||||
let (store, source_map) = ExpressionStore::empty_singleton();
|
||||
(Arc::new(VariantFields { fields: Arena::default(), store, shape }), source_map)
|
||||
let source_map = ExpressionStoreSourceMap::default();
|
||||
(
|
||||
Arc::new(VariantFields {
|
||||
fields: Arena::default(),
|
||||
store: ExpressionStoreBuilder::default().finish().0,
|
||||
shape,
|
||||
}),
|
||||
source_map,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[salsa::tracked(returns(deref))]
|
||||
pub(crate) fn firewall(db: &dyn DefDatabase, id: VariantId) -> Arc<Self> {
|
||||
Self::query(db, id).0
|
||||
pub fn of(db: &dyn DefDatabase, id: VariantId) -> Arc<Self> {
|
||||
Self::with_source_map(db, id).0.clone()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -873,7 +958,7 @@ fn lower_fields<Field: ast::HasAttrs + ast::HasVisibility>(
|
||||
override_visibility: Option<Option<ast::Visibility>>,
|
||||
) -> Option<(Arena<FieldData>, ExpressionStore, ExpressionStoreSourceMap)> {
|
||||
let cfg_options = module.krate(db).cfg_options(db);
|
||||
let mut col = ExprCollector::new(db, module, fields.file_id);
|
||||
let mut col = ExprCollector::signature(db, module, fields.file_id);
|
||||
let override_visibility = override_visibility.map(|vis| {
|
||||
LazyCell::new(|| {
|
||||
let span_map = db.span_map(fields.file_id);
|
||||
@@ -907,9 +992,9 @@ fn lower_fields<Field: ast::HasAttrs + ast::HasVisibility>(
|
||||
|
||||
// Check if field has default value (only for record fields)
|
||||
let default_value = ast::RecordField::cast(field.syntax().clone())
|
||||
.and_then(|rf| rf.eq_token().is_some().then_some(rf.expr()))
|
||||
.and_then(|rf| rf.eq_token().is_some().then_some(rf.default_val()))
|
||||
.flatten()
|
||||
.map(|expr| col.collect_expr_opt(Some(expr)));
|
||||
.map(|expr| col.lower_const_arg(expr));
|
||||
|
||||
arena.alloc(FieldData { name, type_ref, visibility, is_unsafe, default_value });
|
||||
idx += 1;
|
||||
@@ -1014,9 +1099,9 @@ pub fn is_payload_free(&self, db: &dyn DefDatabase) -> bool {
|
||||
}
|
||||
// The outer if condition is whether this variant has const ctor or not
|
||||
if !matches!(variant.shape, FieldsShape::Unit) {
|
||||
let body = db.body(v.into());
|
||||
let body = Body::of(db, v.into());
|
||||
// A variant with explicit discriminant
|
||||
if !matches!(body[body.body_expr], crate::hir::Expr::Missing) {
|
||||
if !matches!(body[body.root_expr()], crate::hir::Expr::Missing) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
use crate::{
|
||||
AstIdLoc, GenericDefId, LocalFieldId, LocalLifetimeParamId, LocalTypeOrConstParamId, Lookup,
|
||||
UseId, VariantId, attrs::AttrFlags, db::DefDatabase,
|
||||
UseId, VariantId, attrs::AttrFlags, db::DefDatabase, hir::generics::GenericParams,
|
||||
};
|
||||
|
||||
pub trait HasSource {
|
||||
@@ -76,7 +76,7 @@ fn child_source(
|
||||
&self,
|
||||
db: &dyn DefDatabase,
|
||||
) -> InFile<ArenaMap<LocalTypeOrConstParamId, Self::Value>> {
|
||||
let generic_params = db.generic_params(*self);
|
||||
let generic_params = GenericParams::of(db, *self);
|
||||
let mut idx_iter = generic_params.iter_type_or_consts().map(|(idx, _)| idx);
|
||||
|
||||
let (file_id, generic_params_list) = self.file_id_and_params_of(db);
|
||||
@@ -110,7 +110,7 @@ fn child_source(
|
||||
&self,
|
||||
db: &dyn DefDatabase,
|
||||
) -> InFile<ArenaMap<LocalLifetimeParamId, Self::Value>> {
|
||||
let generic_params = db.generic_params(*self);
|
||||
let generic_params = GenericParams::of(db, *self);
|
||||
let idx_iter = generic_params.iter_lt().map(|(idx, _)| idx);
|
||||
|
||||
let (file_id, generic_params_list) = self.file_id_and_params_of(db);
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
use crate::{
|
||||
Lookup, ModuleDefId, ModuleId,
|
||||
db::DefDatabase,
|
||||
expr_store::{Body, scope::ExprScopes},
|
||||
nameres::{DefMap, ModuleSource, block_def_map, crate_def_map},
|
||||
src::HasSource,
|
||||
};
|
||||
@@ -284,8 +285,8 @@ fn block_at_position(&self, def_map: &DefMap, position: FilePosition) -> Option<
|
||||
// Find the innermost block expression that has a `DefMap`.
|
||||
let (def_with_body, file_id) = fn_def?;
|
||||
let def_with_body = def_with_body.into();
|
||||
let source_map = self.body_with_source_map(def_with_body).1;
|
||||
let scopes = self.expr_scopes(def_with_body);
|
||||
let source_map = &Body::with_source_map(self, def_with_body).1;
|
||||
let scopes = ExprScopes::body_expr_scopes(self, def_with_body);
|
||||
|
||||
let root_syntax_node = self.parse(file_id).syntax_node();
|
||||
let scope_iter =
|
||||
|
||||
@@ -6,11 +6,11 @@
|
||||
use hir_expand::{InFile, Lookup};
|
||||
use la_arena::ArenaMap;
|
||||
use syntax::ast::{self, HasVisibility};
|
||||
use triomphe::Arc;
|
||||
|
||||
use crate::{
|
||||
AssocItemId, HasModule, ItemContainerId, LocalFieldId, ModuleId, TraitId, VariantId,
|
||||
db::DefDatabase, nameres::DefMap, resolver::HasResolver, src::HasSource,
|
||||
db::DefDatabase, nameres::DefMap, resolver::HasResolver, signatures::VariantFields,
|
||||
src::HasSource,
|
||||
};
|
||||
|
||||
pub use crate::item_tree::{RawVisibility, VisibilityExplicitness};
|
||||
@@ -277,23 +277,26 @@ pub(crate) fn min(
|
||||
}
|
||||
}
|
||||
|
||||
/// Resolve visibility of all specific fields of a struct or union variant.
|
||||
pub(crate) fn field_visibilities_query(
|
||||
db: &dyn DefDatabase,
|
||||
variant_id: VariantId,
|
||||
) -> Arc<ArenaMap<LocalFieldId, Visibility>> {
|
||||
let variant_fields = variant_id.fields(db);
|
||||
let fields = variant_fields.fields();
|
||||
if fields.is_empty() {
|
||||
return Arc::default();
|
||||
#[salsa::tracked]
|
||||
impl VariantFields {
|
||||
/// Resolve visibility of all specific fields of a struct or union variant.
|
||||
#[salsa::tracked(returns(ref))]
|
||||
pub fn field_visibilities(
|
||||
db: &dyn DefDatabase,
|
||||
variant_id: VariantId,
|
||||
) -> ArenaMap<LocalFieldId, Visibility> {
|
||||
let variant_fields = variant_id.fields(db);
|
||||
let fields = variant_fields.fields();
|
||||
if fields.is_empty() {
|
||||
return ArenaMap::default();
|
||||
}
|
||||
let resolver = variant_id.module(db).resolver(db);
|
||||
let mut res = ArenaMap::with_capacity(fields.len());
|
||||
for (field_id, field_data) in fields.iter() {
|
||||
res.insert(field_id, Visibility::resolve(db, &resolver, &field_data.visibility));
|
||||
}
|
||||
res
|
||||
}
|
||||
let resolver = variant_id.module(db).resolver(db);
|
||||
let mut res = ArenaMap::default();
|
||||
for (field_id, field_data) in fields.iter() {
|
||||
res.insert(field_id, Visibility::resolve(db, &resolver, &field_data.visibility));
|
||||
}
|
||||
res.shrink_to_fit();
|
||||
Arc::new(res)
|
||||
}
|
||||
|
||||
pub fn visibility_from_ast(
|
||||
|
||||
@@ -58,8 +58,8 @@ pub trait ExpandDatabase: RootQueryDb {
|
||||
fn proc_macros_for_crate(&self, krate: Crate) -> Option<Arc<CrateProcMacros>>;
|
||||
|
||||
#[salsa::invoke(ast_id_map)]
|
||||
#[salsa::lru(1024)]
|
||||
fn ast_id_map(&self, file_id: HirFileId) -> Arc<AstIdMap>;
|
||||
#[salsa::transparent]
|
||||
fn ast_id_map(&self, file_id: HirFileId) -> &AstIdMap;
|
||||
|
||||
#[salsa::transparent]
|
||||
fn resolve_span(&self, span: Span) -> FileRange;
|
||||
@@ -334,8 +334,9 @@ pub fn expand_speculative(
|
||||
Some((node.syntax_node(), token))
|
||||
}
|
||||
|
||||
fn ast_id_map(db: &dyn ExpandDatabase, file_id: HirFileId) -> triomphe::Arc<AstIdMap> {
|
||||
triomphe::Arc::new(AstIdMap::from_source(&db.parse_or_expand(file_id)))
|
||||
#[salsa::tracked(lru = 1024, returns(ref))]
|
||||
fn ast_id_map(db: &dyn ExpandDatabase, file_id: HirFileId) -> AstIdMap {
|
||||
AstIdMap::from_source(&db.parse_or_expand(file_id))
|
||||
}
|
||||
|
||||
/// Main public API -- parses a hir file, not caring whether it's a real
|
||||
|
||||
@@ -80,7 +80,7 @@ pub(crate) fn generics_of<'db>(interner: DbInterner<'db>, id: BuiltinDeriveImplI
|
||||
|
||||
pub fn generic_params_count(db: &dyn HirDatabase, id: BuiltinDeriveImplId) -> usize {
|
||||
let loc = id.loc(db);
|
||||
let adt_params = GenericParams::new(db, loc.adt.into());
|
||||
let adt_params = GenericParams::of(db, loc.adt.into());
|
||||
let extra_params_count = match loc.trait_ {
|
||||
BuiltinDeriveImplTrait::Copy
|
||||
| BuiltinDeriveImplTrait::Clone
|
||||
@@ -128,12 +128,12 @@ pub fn impl_trait<'db>(
|
||||
))
|
||||
}
|
||||
BuiltinDeriveImplTrait::CoerceUnsized | BuiltinDeriveImplTrait::DispatchFromDyn => {
|
||||
let generic_params = GenericParams::new(db, loc.adt.into());
|
||||
let generic_params = GenericParams::of(db, loc.adt.into());
|
||||
let interner = DbInterner::new_no_crate(db);
|
||||
let args = GenericArgs::identity_for_item(interner, loc.adt.into());
|
||||
let self_ty = Ty::new_adt(interner, loc.adt, args);
|
||||
let Some((pointee_param_idx, _, new_param_ty)) =
|
||||
coerce_pointee_params(interner, loc, &generic_params, trait_id)
|
||||
coerce_pointee_params(interner, loc, generic_params, trait_id)
|
||||
else {
|
||||
// Malformed derive.
|
||||
return EarlyBinder::bind(TraitRef::new(
|
||||
@@ -152,7 +152,7 @@ pub fn impl_trait<'db>(
|
||||
#[salsa::tracked(returns(ref))]
|
||||
pub fn predicates<'db>(db: &'db dyn HirDatabase, impl_: BuiltinDeriveImplId) -> GenericPredicates {
|
||||
let loc = impl_.loc(db);
|
||||
let generic_params = GenericParams::new(db, loc.adt.into());
|
||||
let generic_params = GenericParams::of(db, loc.adt.into());
|
||||
let interner = DbInterner::new_with(db, loc.module(db).krate(db));
|
||||
let adt_predicates = GenericPredicates::query(db, loc.adt.into());
|
||||
let trait_id = loc
|
||||
@@ -168,7 +168,7 @@ pub fn predicates<'db>(db: &'db dyn HirDatabase, impl_: BuiltinDeriveImplId) ->
|
||||
| BuiltinDeriveImplTrait::PartialOrd
|
||||
| BuiltinDeriveImplTrait::Eq
|
||||
| BuiltinDeriveImplTrait::PartialEq => {
|
||||
simple_trait_predicates(interner, loc, &generic_params, adt_predicates, trait_id)
|
||||
simple_trait_predicates(interner, loc, generic_params, adt_predicates, trait_id)
|
||||
}
|
||||
BuiltinDeriveImplTrait::Default => {
|
||||
if matches!(loc.adt, AdtId::EnumId(_)) {
|
||||
@@ -178,12 +178,12 @@ pub fn predicates<'db>(db: &'db dyn HirDatabase, impl_: BuiltinDeriveImplId) ->
|
||||
.store(),
|
||||
))
|
||||
} else {
|
||||
simple_trait_predicates(interner, loc, &generic_params, adt_predicates, trait_id)
|
||||
simple_trait_predicates(interner, loc, generic_params, adt_predicates, trait_id)
|
||||
}
|
||||
}
|
||||
BuiltinDeriveImplTrait::CoerceUnsized | BuiltinDeriveImplTrait::DispatchFromDyn => {
|
||||
let Some((pointee_param_idx, pointee_param_id, new_param_ty)) =
|
||||
coerce_pointee_params(interner, loc, &generic_params, trait_id)
|
||||
coerce_pointee_params(interner, loc, generic_params, trait_id)
|
||||
else {
|
||||
// Malformed derive.
|
||||
return GenericPredicates::from_explicit_own_predicates(StoredEarlyBinder::bind(
|
||||
|
||||
@@ -5,10 +5,11 @@
|
||||
|
||||
use base_db::Crate;
|
||||
use hir_def::{
|
||||
ConstId, EnumVariantId, GeneralConstId, HasModule, StaticId,
|
||||
ConstId, EnumVariantId, ExpressionStoreOwnerId, GeneralConstId, GenericDefId, HasModule,
|
||||
StaticId,
|
||||
attrs::AttrFlags,
|
||||
builtin_type::{BuiltinInt, BuiltinType, BuiltinUint},
|
||||
expr_store::Body,
|
||||
expr_store::{Body, ExpressionStore},
|
||||
hir::{Expr, ExprId, Literal},
|
||||
};
|
||||
use hir_expand::Lookup;
|
||||
@@ -235,6 +236,7 @@ pub fn try_const_usize<'db>(db: &'db dyn HirDatabase, c: Const<'db>) -> Option<u
|
||||
let ec = db.const_eval_static(id).ok()?;
|
||||
try_const_usize(db, ec)
|
||||
}
|
||||
GeneralConstId::AnonConstId(_) => None,
|
||||
},
|
||||
ConstKind::Value(val) => Some(u128::from_le_bytes(pad16(&val.value.inner().memory, false))),
|
||||
ConstKind::Error(_) => None,
|
||||
@@ -258,6 +260,7 @@ pub fn try_const_isize<'db>(db: &'db dyn HirDatabase, c: &Const<'db>) -> Option<
|
||||
let ec = db.const_eval_static(id).ok()?;
|
||||
try_const_isize(db, &ec)
|
||||
}
|
||||
GeneralConstId::AnonConstId(_) => None,
|
||||
},
|
||||
ConstKind::Value(val) => Some(i128::from_le_bytes(pad16(&val.value.inner().memory, true))),
|
||||
ConstKind::Error(_) => None,
|
||||
@@ -271,9 +274,9 @@ pub(crate) fn const_eval_discriminant_variant(
|
||||
) -> Result<i128, ConstEvalError> {
|
||||
let interner = DbInterner::new_no_crate(db);
|
||||
let def = variant_id.into();
|
||||
let body = db.body(def);
|
||||
let body = Body::of(db, def);
|
||||
let loc = variant_id.lookup(db);
|
||||
if matches!(body[body.body_expr], Expr::Missing) {
|
||||
if matches!(body[body.root_expr()], Expr::Missing) {
|
||||
let prev_idx = loc.index.checked_sub(1);
|
||||
let value = match prev_idx {
|
||||
Some(prev_idx) => {
|
||||
@@ -292,7 +295,7 @@ pub(crate) fn const_eval_discriminant_variant(
|
||||
let mir_body = db.monomorphized_mir_body(
|
||||
def,
|
||||
GenericArgs::empty(interner).store(),
|
||||
ParamEnvAndCrate { param_env: db.trait_environment_for_body(def), krate: def.krate(db) }
|
||||
ParamEnvAndCrate { param_env: db.trait_environment(def.into()), krate: def.krate(db) }
|
||||
.store(),
|
||||
)?;
|
||||
let c = interpret_mir(db, mir_body, false, None)?.0?;
|
||||
@@ -309,23 +312,23 @@ pub(crate) fn const_eval_discriminant_variant(
|
||||
// and make this function private. See the fixme comment on `InferenceContext::resolve_all`.
|
||||
pub(crate) fn eval_to_const<'db>(expr: ExprId, ctx: &mut InferenceContext<'_, 'db>) -> Const<'db> {
|
||||
let infer = ctx.fixme_resolve_all_clone();
|
||||
fn has_closure(body: &Body, expr: ExprId) -> bool {
|
||||
if matches!(body[expr], Expr::Closure { .. }) {
|
||||
fn has_closure(store: &ExpressionStore, expr: ExprId) -> bool {
|
||||
if matches!(store[expr], Expr::Closure { .. }) {
|
||||
return true;
|
||||
}
|
||||
let mut r = false;
|
||||
body.walk_child_exprs(expr, |idx| r |= has_closure(body, idx));
|
||||
store.walk_child_exprs(expr, |idx| r |= has_closure(store, idx));
|
||||
r
|
||||
}
|
||||
if has_closure(ctx.body, expr) {
|
||||
if has_closure(ctx.store, expr) {
|
||||
// Type checking clousres need an isolated body (See the above FIXME). Bail out early to prevent panic.
|
||||
return Const::error(ctx.interner());
|
||||
}
|
||||
if let Expr::Path(p) = &ctx.body[expr] {
|
||||
if let Expr::Path(p) = &ctx.store[expr] {
|
||||
let mut ctx = TyLoweringContext::new(
|
||||
ctx.db,
|
||||
&ctx.resolver,
|
||||
ctx.body,
|
||||
ctx.store,
|
||||
ctx.generic_def,
|
||||
LifetimeElisionKind::Infer,
|
||||
);
|
||||
@@ -333,7 +336,9 @@ fn has_closure(body: &Body, expr: ExprId) -> bool {
|
||||
return c;
|
||||
}
|
||||
}
|
||||
if let Ok(mir_body) = lower_body_to_mir(ctx.db, ctx.owner, ctx.body, &infer, expr)
|
||||
if let Some(body_owner) = ctx.owner.as_def_with_body()
|
||||
&& let Ok(mir_body) =
|
||||
lower_body_to_mir(ctx.db, body_owner, Body::of(ctx.db, body_owner), &infer, expr)
|
||||
&& let Ok((Ok(result), _)) = interpret_mir(ctx.db, Arc::new(mir_body), true, None)
|
||||
{
|
||||
return result;
|
||||
@@ -370,8 +375,12 @@ pub(crate) fn const_eval_query<'db>(
|
||||
let body = db.monomorphized_mir_body(
|
||||
def.into(),
|
||||
subst,
|
||||
ParamEnvAndCrate { param_env: db.trait_environment(def.into()), krate: def.krate(db) }
|
||||
.store(),
|
||||
ParamEnvAndCrate {
|
||||
param_env: db
|
||||
.trait_environment(ExpressionStoreOwnerId::from(GenericDefId::from(def))),
|
||||
krate: def.krate(db),
|
||||
}
|
||||
.store(),
|
||||
)?;
|
||||
let c = interpret_mir(db, body, false, trait_env.as_ref().map(|env| env.as_ref()))?.0?;
|
||||
Ok(c.store())
|
||||
@@ -407,7 +416,8 @@ pub(crate) fn const_eval_static_query<'db>(
|
||||
def.into(),
|
||||
GenericArgs::empty(interner).store(),
|
||||
ParamEnvAndCrate {
|
||||
param_env: db.trait_environment_for_body(def.into()),
|
||||
param_env: db
|
||||
.trait_environment(ExpressionStoreOwnerId::from(GenericDefId::from(def))),
|
||||
krate: def.krate(db),
|
||||
}
|
||||
.store(),
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use base_db::RootQueryDb;
|
||||
use hir_def::db::DefDatabase;
|
||||
use hir_def::signatures::ConstSignature;
|
||||
use hir_expand::EditionedFileId;
|
||||
use rustc_apfloat::{
|
||||
Float,
|
||||
@@ -131,7 +131,11 @@ fn eval_goal(db: &TestDB, file_id: EditionedFileId) -> Result<Const<'_>, ConstEv
|
||||
.declarations()
|
||||
.find_map(|x| match x {
|
||||
hir_def::ModuleDefId::ConstId(x) => {
|
||||
if db.const_signature(x).name.as_ref()?.display(db, file_id.edition(db)).to_string()
|
||||
if ConstSignature::of(db, x)
|
||||
.name
|
||||
.as_ref()?
|
||||
.display(db, file_id.edition(db))
|
||||
.to_string()
|
||||
== "GOAL"
|
||||
{
|
||||
Some(x)
|
||||
|
||||
@@ -5,9 +5,9 @@
|
||||
use either::Either;
|
||||
use hir_def::{
|
||||
AdtId, BuiltinDeriveImplId, CallableDefId, ConstId, ConstParamId, DefWithBodyId, EnumVariantId,
|
||||
FunctionId, GenericDefId, ImplId, LifetimeParamId, LocalFieldId, StaticId, TraitId,
|
||||
TypeAliasId, VariantId, builtin_derive::BuiltinDeriveImplMethod, db::DefDatabase, hir::ExprId,
|
||||
layout::TargetDataLayout,
|
||||
ExpressionStoreOwnerId, FunctionId, GenericDefId, ImplId, LifetimeParamId, LocalFieldId,
|
||||
StaticId, TraitId, TypeAliasId, VariantId, builtin_derive::BuiltinDeriveImplMethod,
|
||||
db::DefDatabase, hir::ExprId, layout::TargetDataLayout,
|
||||
};
|
||||
use la_arena::ArenaMap;
|
||||
use salsa::plumbing::AsId;
|
||||
@@ -178,13 +178,9 @@ fn callable_item_signature<'db>(
|
||||
def: CallableDefId,
|
||||
) -> EarlyBinder<'db, PolyFnSig<'db>>;
|
||||
|
||||
#[salsa::invoke(crate::lower::trait_environment_for_body_query)]
|
||||
#[salsa::transparent]
|
||||
fn trait_environment_for_body<'db>(&'db self, def: DefWithBodyId) -> ParamEnv<'db>;
|
||||
|
||||
#[salsa::invoke(crate::lower::trait_environment)]
|
||||
#[salsa::transparent]
|
||||
fn trait_environment<'db>(&'db self, def: GenericDefId) -> ParamEnv<'db>;
|
||||
fn trait_environment<'db>(&'db self, def: ExpressionStoreOwnerId) -> ParamEnv<'db>;
|
||||
|
||||
#[salsa::invoke(crate::lower::generic_defaults_with_diagnostics_query)]
|
||||
#[salsa::cycle(cycle_result = crate::lower::generic_defaults_with_diagnostics_cycle_result)]
|
||||
@@ -240,7 +236,7 @@ pub struct InternedOpaqueTyId {
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
|
||||
pub struct InternedClosure(pub DefWithBodyId, pub ExprId);
|
||||
pub struct InternedClosure(pub ExpressionStoreOwnerId, pub ExprId);
|
||||
|
||||
#[salsa_macros::interned(no_lifetime, debug, revisions = usize::MAX)]
|
||||
#[derive(PartialOrd, Ord)]
|
||||
@@ -249,7 +245,7 @@ pub struct InternedClosureId {
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
|
||||
pub struct InternedCoroutine(pub DefWithBodyId, pub ExprId);
|
||||
pub struct InternedCoroutine(pub ExpressionStoreOwnerId, pub ExprId);
|
||||
|
||||
#[salsa_macros::interned(no_lifetime, debug, revisions = usize::MAX)]
|
||||
#[derive(PartialOrd, Ord)]
|
||||
|
||||
@@ -17,8 +17,17 @@
|
||||
|
||||
use hir_def::{
|
||||
AdtId, ConstId, EnumId, EnumVariantId, FunctionId, HasModule, ItemContainerId, Lookup,
|
||||
ModuleDefId, ModuleId, StaticId, StructId, TraitId, TypeAliasId, UnionId, attrs::AttrFlags,
|
||||
db::DefDatabase, hir::Pat, item_tree::FieldsShape, signatures::StaticFlags, src::HasSource,
|
||||
ModuleDefId, ModuleId, StaticId, StructId, TraitId, TypeAliasId, UnionId,
|
||||
attrs::AttrFlags,
|
||||
db::DefDatabase,
|
||||
expr_store::Body,
|
||||
hir::Pat,
|
||||
item_tree::FieldsShape,
|
||||
signatures::{
|
||||
ConstSignature, EnumSignature, FunctionSignature, StaticFlags, StaticSignature,
|
||||
StructSignature, TraitSignature, TypeAliasSignature, UnionSignature,
|
||||
},
|
||||
src::HasSource,
|
||||
};
|
||||
use hir_expand::{
|
||||
HirFileId,
|
||||
@@ -178,7 +187,7 @@ fn validate_module(&mut self, module_id: ModuleId) {
|
||||
|
||||
fn validate_trait(&mut self, trait_id: TraitId) {
|
||||
// Check the trait name.
|
||||
let data = self.db.trait_signature(trait_id);
|
||||
let data = TraitSignature::of(self.db, trait_id);
|
||||
self.create_incorrect_case_diagnostic_for_item_name(
|
||||
trait_id,
|
||||
&data.name,
|
||||
@@ -197,7 +206,7 @@ fn validate_func(&mut self, func: FunctionId) {
|
||||
// Check the function name.
|
||||
// Skipped if function is an associated item of a trait implementation.
|
||||
if !self.is_trait_impl_container(container) {
|
||||
let data = self.db.function_signature(func);
|
||||
let data = FunctionSignature::of(self.db, func);
|
||||
|
||||
// Don't run the lint on extern "[not Rust]" fn items with the
|
||||
// #[no_mangle] attribute.
|
||||
@@ -223,7 +232,7 @@ fn validate_func(&mut self, func: FunctionId) {
|
||||
/// Check incorrect names for patterns inside the function body.
|
||||
/// This includes function parameters except for trait implementation associated functions.
|
||||
fn validate_func_body(&mut self, func: FunctionId) {
|
||||
let body = self.db.body(func.into());
|
||||
let body = Body::of(self.db, func.into());
|
||||
let edition = self.edition(func);
|
||||
let mut pats_replacements = body
|
||||
.pats()
|
||||
@@ -250,7 +259,7 @@ fn validate_func_body(&mut self, func: FunctionId) {
|
||||
return;
|
||||
}
|
||||
|
||||
let source_map = self.db.body_with_source_map(func.into()).1;
|
||||
let source_map = &Body::with_source_map(self.db, func.into()).1;
|
||||
for (id, replacement) in pats_replacements {
|
||||
let Ok(source_ptr) = source_map.pat_syntax(id) else {
|
||||
continue;
|
||||
@@ -292,7 +301,7 @@ fn edition(&self, id: impl HasModule) -> span::Edition {
|
||||
|
||||
fn validate_struct(&mut self, struct_id: StructId) {
|
||||
// Check the structure name.
|
||||
let data = self.db.struct_signature(struct_id);
|
||||
let data = StructSignature::of(self.db, struct_id);
|
||||
|
||||
// rustc implementation excuses repr(C) since C structs predominantly don't
|
||||
// use camel case.
|
||||
@@ -385,7 +394,7 @@ fn validate_struct_fields(&mut self, struct_id: StructId) {
|
||||
|
||||
fn validate_union(&mut self, union_id: UnionId) {
|
||||
// Check the union name.
|
||||
let data = self.db.union_signature(union_id);
|
||||
let data = UnionSignature::of(self.db, union_id);
|
||||
|
||||
// rustc implementation excuses repr(C) since C unions predominantly don't
|
||||
// use camel case.
|
||||
@@ -473,7 +482,7 @@ fn validate_union_fields(&mut self, union_id: UnionId) {
|
||||
|
||||
fn validate_enum(&mut self, enum_id: EnumId) {
|
||||
// Check the enum name.
|
||||
let data = self.db.enum_signature(enum_id);
|
||||
let data = EnumSignature::of(self.db, enum_id);
|
||||
|
||||
// rustc implementation excuses repr(C) since C structs predominantly don't
|
||||
// use camel case.
|
||||
@@ -644,7 +653,7 @@ fn validate_const(&mut self, const_id: ConstId) {
|
||||
return;
|
||||
}
|
||||
|
||||
let data = self.db.const_signature(const_id);
|
||||
let data = ConstSignature::of(self.db, const_id);
|
||||
let Some(name) = &data.name else {
|
||||
return;
|
||||
};
|
||||
@@ -657,7 +666,7 @@ fn validate_const(&mut self, const_id: ConstId) {
|
||||
}
|
||||
|
||||
fn validate_static(&mut self, static_id: StaticId) {
|
||||
let data = self.db.static_signature(static_id);
|
||||
let data = StaticSignature::of(self.db, static_id);
|
||||
if data.flags.contains(StaticFlags::EXTERN) {
|
||||
cov_mark::hit!(extern_static_incorrect_case_ignored);
|
||||
return;
|
||||
@@ -683,7 +692,7 @@ fn validate_type_alias(&mut self, type_alias_id: TypeAliasId) {
|
||||
}
|
||||
|
||||
// Check the type alias name.
|
||||
let data = self.db.type_alias_signature(type_alias_id);
|
||||
let data = TypeAliasSignature::of(self.db, type_alias_id);
|
||||
self.create_incorrect_case_diagnostic_for_item_name(
|
||||
type_alias_id,
|
||||
&data.name,
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
ast::{self, UnaryOp},
|
||||
};
|
||||
use tracing::debug;
|
||||
use triomphe::Arc;
|
||||
|
||||
use typed_arena::Arena;
|
||||
|
||||
use crate::{
|
||||
@@ -76,9 +76,9 @@ pub fn collect(
|
||||
validate_lints: bool,
|
||||
) -> Vec<BodyValidationDiagnostic> {
|
||||
let _p = tracing::info_span!("BodyValidationDiagnostic::collect").entered();
|
||||
let infer = InferenceResult::for_body(db, owner);
|
||||
let body = db.body(owner);
|
||||
let env = db.trait_environment_for_body(owner);
|
||||
let infer = InferenceResult::of(db, owner);
|
||||
let body = Body::of(db, owner);
|
||||
let env = db.trait_environment(owner.into());
|
||||
let interner = DbInterner::new_with(db, owner.krate(db));
|
||||
let infcx =
|
||||
interner.infer_ctxt().build(TypingMode::typeck_for_body(interner, owner.into()));
|
||||
@@ -98,7 +98,7 @@ pub fn collect(
|
||||
|
||||
struct ExprValidator<'db> {
|
||||
owner: DefWithBodyId,
|
||||
body: Arc<Body>,
|
||||
body: &'db Body,
|
||||
infer: &'db InferenceResult,
|
||||
env: ParamEnv<'db>,
|
||||
diagnostics: Vec<BodyValidationDiagnostic>,
|
||||
@@ -116,10 +116,10 @@ fn validate_body(&mut self) {
|
||||
let db = self.db();
|
||||
let mut filter_map_next_checker = None;
|
||||
// we'll pass &mut self while iterating over body.exprs, so they need to be disjoint
|
||||
let body = Arc::clone(&self.body);
|
||||
let body = self.body;
|
||||
|
||||
if matches!(self.owner, DefWithBodyId::FunctionId(_)) {
|
||||
self.check_for_trailing_return(body.body_expr, &body);
|
||||
self.check_for_trailing_return(body.root_expr(), body);
|
||||
}
|
||||
|
||||
for (id, expr) in body.exprs() {
|
||||
@@ -141,7 +141,7 @@ fn validate_body(&mut self) {
|
||||
self.validate_call(id, expr, &mut filter_map_next_checker);
|
||||
}
|
||||
Expr::Closure { body: body_expr, .. } => {
|
||||
self.check_for_trailing_return(*body_expr, &body);
|
||||
self.check_for_trailing_return(*body_expr, body);
|
||||
}
|
||||
Expr::If { .. } => {
|
||||
self.check_for_unnecessary_else(id, expr);
|
||||
@@ -240,7 +240,7 @@ fn validate_match(&mut self, match_expr: ExprId, scrutinee_expr: ExprId, arms: &
|
||||
.as_reference()
|
||||
.map(|(match_expr_ty, ..)| match_expr_ty == pat_ty)
|
||||
.unwrap_or(false))
|
||||
&& types_of_subpatterns_do_match(arm.pat, &self.body, self.infer)
|
||||
&& types_of_subpatterns_do_match(arm.pat, self.body, self.infer)
|
||||
{
|
||||
// If we had a NotUsefulMatchArm diagnostic, we could
|
||||
// check the usefulness of each pattern as we added it
|
||||
@@ -388,7 +388,7 @@ fn lower_pattern<'a>(
|
||||
pat: PatId,
|
||||
have_errors: &mut bool,
|
||||
) -> DeconstructedPat<'a, 'db> {
|
||||
let mut patcx = match_check::PatCtxt::new(self.db(), self.infer, &self.body);
|
||||
let mut patcx = match_check::PatCtxt::new(self.db(), self.infer, self.body);
|
||||
let pattern = patcx.lower_pattern(pat);
|
||||
let pattern = cx.lower_pat(&pattern);
|
||||
if !patcx.errors.is_empty() {
|
||||
@@ -451,7 +451,7 @@ fn check_for_unnecessary_else(&mut self, id: ExprId, expr: &Expr) {
|
||||
&& last_then_expr_ty.is_never()
|
||||
{
|
||||
// Only look at sources if the then branch diverges and we have an else branch.
|
||||
let source_map = self.db().body_with_source_map(self.owner).1;
|
||||
let source_map = &Body::with_source_map(self.db(), self.owner).1;
|
||||
let Ok(source_ptr) = source_map.expr_syntax(id) else {
|
||||
return;
|
||||
};
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
expr_store::{Body, path::Path},
|
||||
hir::PatId,
|
||||
item_tree::FieldsShape,
|
||||
signatures::{StructSignature, UnionSignature},
|
||||
};
|
||||
use hir_expand::name::Name;
|
||||
use rustc_type_ir::inherent::IntoKind;
|
||||
@@ -340,12 +341,12 @@ fn hir_fmt(&self, f: &mut HirFormatter<'_, 'db>) -> Result<(), HirDisplayError>
|
||||
VariantId::StructId(s) => write!(
|
||||
f,
|
||||
"{}",
|
||||
f.db.struct_signature(s).name.display(f.db, f.edition())
|
||||
StructSignature::of(f.db, s).name.display(f.db, f.edition())
|
||||
)?,
|
||||
VariantId::UnionId(u) => write!(
|
||||
f,
|
||||
"{}",
|
||||
f.db.union_signature(u).name.display(f.db, f.edition())
|
||||
UnionSignature::of(f.db, u).name.display(f.db, f.edition())
|
||||
)?,
|
||||
};
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
use hir_def::{
|
||||
EnumId, EnumVariantId, HasModule, LocalFieldId, ModuleId, VariantId, attrs::AttrFlags,
|
||||
signatures::VariantFields,
|
||||
};
|
||||
use intern::sym;
|
||||
use rustc_pattern_analysis::{
|
||||
@@ -363,7 +364,8 @@ fn ctor_sub_tys(
|
||||
let adt = adt_def.def_id().0;
|
||||
let variant = Self::variant_id_for_adt(self.db, ctor, adt).unwrap();
|
||||
|
||||
let visibilities = LazyCell::new(|| self.db.field_visibilities(variant));
|
||||
let visibilities =
|
||||
LazyCell::new(|| VariantFields::field_visibilities(self.db, variant));
|
||||
|
||||
self.list_variant_fields(*ty, variant)
|
||||
.map(move |(fid, ty)| {
|
||||
|
||||
@@ -5,11 +5,12 @@
|
||||
|
||||
use either::Either;
|
||||
use hir_def::{
|
||||
AdtId, CallableDefId, DefWithBodyId, FieldId, FunctionId, VariantId,
|
||||
expr_store::{Body, path::Path},
|
||||
AdtId, CallableDefId, DefWithBodyId, ExpressionStoreOwnerId, FieldId, FunctionId, GenericDefId,
|
||||
VariantId,
|
||||
expr_store::{Body, ExpressionStore, path::Path},
|
||||
hir::{AsmOperand, Expr, ExprId, ExprOrPatId, InlineAsmKind, Pat, PatId, Statement, UnaryOp},
|
||||
resolver::{HasResolver, ResolveValueResult, Resolver, ValueNs},
|
||||
signatures::StaticFlags,
|
||||
signatures::{FunctionSignature, StaticFlags, StaticSignature},
|
||||
type_ref::Rawness,
|
||||
};
|
||||
use rustc_type_ir::inherent::IntoKind;
|
||||
@@ -34,15 +35,15 @@ pub fn missing_unsafe(db: &dyn HirDatabase, def: DefWithBodyId) -> MissingUnsafe
|
||||
let _p = tracing::info_span!("missing_unsafe").entered();
|
||||
|
||||
let is_unsafe = match def {
|
||||
DefWithBodyId::FunctionId(it) => db.function_signature(it).is_unsafe(),
|
||||
DefWithBodyId::FunctionId(it) => FunctionSignature::of(db, it).is_unsafe(),
|
||||
DefWithBodyId::StaticId(_) | DefWithBodyId::ConstId(_) | DefWithBodyId::VariantId(_) => {
|
||||
false
|
||||
}
|
||||
};
|
||||
|
||||
let mut res = MissingUnsafeResult { fn_is_unsafe: is_unsafe, ..MissingUnsafeResult::default() };
|
||||
let body = db.body(def);
|
||||
let infer = InferenceResult::for_body(db, def);
|
||||
let body = Body::of(db, def);
|
||||
let infer = InferenceResult::of(db, def);
|
||||
let mut callback = |diag| match diag {
|
||||
UnsafeDiagnostic::UnsafeOperation { node, inside_unsafe_block, reason } => {
|
||||
if inside_unsafe_block == InsideUnsafeBlock::No {
|
||||
@@ -55,8 +56,8 @@ pub fn missing_unsafe(db: &dyn HirDatabase, def: DefWithBodyId) -> MissingUnsafe
|
||||
}
|
||||
}
|
||||
};
|
||||
let mut visitor = UnsafeVisitor::new(db, infer, &body, def, &mut callback);
|
||||
visitor.walk_expr(body.body_expr);
|
||||
let mut visitor = UnsafeVisitor::new(db, infer, body, def.into(), &mut callback);
|
||||
visitor.walk_expr(body.root_expr());
|
||||
|
||||
if !is_unsafe {
|
||||
// Unsafety in function parameter patterns (that can only be union destructuring)
|
||||
@@ -109,8 +110,8 @@ pub fn unsafe_operations_for_body(
|
||||
callback(node);
|
||||
}
|
||||
};
|
||||
let mut visitor = UnsafeVisitor::new(db, infer, body, def, &mut visitor_callback);
|
||||
visitor.walk_expr(body.body_expr);
|
||||
let mut visitor = UnsafeVisitor::new(db, infer, body, def.into(), &mut visitor_callback);
|
||||
visitor.walk_expr(body.root_expr());
|
||||
for ¶m in &body.params {
|
||||
visitor.walk_pat(param);
|
||||
}
|
||||
@@ -119,8 +120,8 @@ pub fn unsafe_operations_for_body(
|
||||
pub fn unsafe_operations(
|
||||
db: &dyn HirDatabase,
|
||||
infer: &InferenceResult,
|
||||
def: DefWithBodyId,
|
||||
body: &Body,
|
||||
def: ExpressionStoreOwnerId,
|
||||
body: &ExpressionStore,
|
||||
current: ExprId,
|
||||
callback: &mut dyn FnMut(ExprOrPatId, InsideUnsafeBlock),
|
||||
) {
|
||||
@@ -137,9 +138,9 @@ pub fn unsafe_operations(
|
||||
struct UnsafeVisitor<'db> {
|
||||
db: &'db dyn HirDatabase,
|
||||
infer: &'db InferenceResult,
|
||||
body: &'db Body,
|
||||
body: &'db ExpressionStore,
|
||||
resolver: Resolver<'db>,
|
||||
def: DefWithBodyId,
|
||||
def: ExpressionStoreOwnerId,
|
||||
inside_unsafe_block: InsideUnsafeBlock,
|
||||
inside_assignment: bool,
|
||||
inside_union_destructure: bool,
|
||||
@@ -156,13 +157,16 @@ impl<'db> UnsafeVisitor<'db> {
|
||||
fn new(
|
||||
db: &'db dyn HirDatabase,
|
||||
infer: &'db InferenceResult,
|
||||
body: &'db Body,
|
||||
def: DefWithBodyId,
|
||||
body: &'db ExpressionStore,
|
||||
def: ExpressionStoreOwnerId,
|
||||
unsafe_expr_cb: &'db mut dyn FnMut(UnsafeDiagnostic),
|
||||
) -> Self {
|
||||
let resolver = def.resolver(db);
|
||||
let def_target_features = match def {
|
||||
DefWithBodyId::FunctionId(func) => TargetFeatures::from_fn(db, func),
|
||||
ExpressionStoreOwnerId::Body(DefWithBodyId::FunctionId(func))
|
||||
| ExpressionStoreOwnerId::Signature(GenericDefId::FunctionId(func)) => {
|
||||
TargetFeatures::from_fn(db, func)
|
||||
}
|
||||
_ => TargetFeatures::default(),
|
||||
};
|
||||
let krate = resolver.krate();
|
||||
@@ -431,7 +435,7 @@ fn mark_unsafe_path(&mut self, node: ExprOrPatId, path: &Path) {
|
||||
let hygiene = self.body.expr_or_pat_path_hygiene(node);
|
||||
let value_or_partial = self.resolver.resolve_path_in_value_ns(self.db, path, hygiene);
|
||||
if let Some(ResolveValueResult::ValueNs(ValueNs::StaticId(id))) = value_or_partial {
|
||||
let static_data = self.db.static_signature(id);
|
||||
let static_data = StaticSignature::of(self.db, id);
|
||||
if static_data.flags.contains(StaticFlags::MUTABLE) {
|
||||
self.on_unsafe_op(node, UnsafetyReason::MutableStatic);
|
||||
} else if static_data.flags.contains(StaticFlags::EXTERN)
|
||||
|
||||
@@ -10,15 +10,18 @@
|
||||
use base_db::{Crate, FxIndexMap};
|
||||
use either::Either;
|
||||
use hir_def::{
|
||||
FindPathConfig, GenericDefId, GenericParamId, HasModule, LocalFieldId, Lookup, ModuleDefId,
|
||||
ModuleId, TraitId,
|
||||
ExpressionStoreOwnerId, FindPathConfig, GenericDefId, GenericParamId, HasModule, LocalFieldId,
|
||||
Lookup, ModuleDefId, ModuleId, TraitId,
|
||||
expr_store::{ExpressionStore, path::Path},
|
||||
find_path::{self, PrefixKind},
|
||||
hir::generics::{TypeOrConstParamData, TypeParamProvenance, WherePredicate},
|
||||
hir::generics::{GenericParams, TypeOrConstParamData, TypeParamProvenance, WherePredicate},
|
||||
item_scope::ItemInNs,
|
||||
item_tree::FieldsShape,
|
||||
lang_item::LangItems,
|
||||
signatures::VariantFields,
|
||||
signatures::{
|
||||
EnumSignature, FunctionSignature, StructSignature, TraitSignature, TypeAliasSignature,
|
||||
UnionSignature, VariantFields,
|
||||
},
|
||||
type_ref::{
|
||||
ConstRef, LifetimeRef, LifetimeRefId, TraitBoundModifier, TypeBound, TypeRef, TypeRefId,
|
||||
UseArgRef,
|
||||
@@ -671,7 +674,9 @@ fn write_projection<'db>(
|
||||
write!(
|
||||
f,
|
||||
">::{}",
|
||||
f.db.type_alias_signature(alias.def_id.expect_type_alias()).name.display(f.db, f.edition())
|
||||
TypeAliasSignature::of(f.db, alias.def_id.expect_type_alias())
|
||||
.name
|
||||
.display(f.db, f.edition())
|
||||
)?;
|
||||
let proj_params = &alias.args.as_slice()[trait_ref.args.len()..];
|
||||
hir_fmt_generics(f, proj_params, None, None)
|
||||
@@ -853,7 +858,7 @@ fn render_const_scalar_inner<'db>(
|
||||
}
|
||||
TyKind::Adt(adt, _) if b.len() == 2 * size_of::<usize>() => match adt.def_id().0 {
|
||||
hir_def::AdtId::StructId(s) => {
|
||||
let data = f.db.struct_signature(s);
|
||||
let data = StructSignature::of(f.db, s);
|
||||
write!(f, "&{}", data.name.display(f.db, f.edition()))?;
|
||||
Ok(())
|
||||
}
|
||||
@@ -911,14 +916,16 @@ fn render_const_scalar_inner<'db>(
|
||||
};
|
||||
match def {
|
||||
hir_def::AdtId::StructId(s) => {
|
||||
let data = f.db.struct_signature(s);
|
||||
let data = StructSignature::of(f.db, s);
|
||||
write!(f, "{}", data.name.display(f.db, f.edition()))?;
|
||||
let field_types = f.db.field_types(s.into());
|
||||
render_variant_after_name(
|
||||
s.fields(f.db),
|
||||
f,
|
||||
field_types,
|
||||
f.db.trait_environment(def.into()),
|
||||
f.db.trait_environment(ExpressionStoreOwnerId::from(GenericDefId::from(
|
||||
def,
|
||||
))),
|
||||
&layout,
|
||||
args,
|
||||
b,
|
||||
@@ -926,7 +933,7 @@ fn render_const_scalar_inner<'db>(
|
||||
)
|
||||
}
|
||||
hir_def::AdtId::UnionId(u) => {
|
||||
write!(f, "{}", f.db.union_signature(u).name.display(f.db, f.edition()))
|
||||
write!(f, "{}", UnionSignature::of(f.db, u).name.display(f.db, f.edition()))
|
||||
}
|
||||
hir_def::AdtId::EnumId(e) => {
|
||||
let Ok(target_data_layout) = f.db.target_data_layout(f.krate()) else {
|
||||
@@ -950,7 +957,9 @@ fn render_const_scalar_inner<'db>(
|
||||
var_id.fields(f.db),
|
||||
f,
|
||||
field_types,
|
||||
f.db.trait_environment(def.into()),
|
||||
f.db.trait_environment(ExpressionStoreOwnerId::from(GenericDefId::from(
|
||||
def,
|
||||
))),
|
||||
var_layout,
|
||||
args,
|
||||
b,
|
||||
@@ -1152,11 +1161,13 @@ fn hir_fmt(&self, f @ &mut HirFormatter { db, .. }: &mut HirFormatter<'_, 'db>)
|
||||
write!(f, "fn ")?;
|
||||
f.start_location_link(def.into());
|
||||
match def {
|
||||
CallableDefId::FunctionId(ff) => {
|
||||
write!(f, "{}", db.function_signature(ff).name.display(f.db, f.edition()))?
|
||||
}
|
||||
CallableDefId::FunctionId(ff) => write!(
|
||||
f,
|
||||
"{}",
|
||||
FunctionSignature::of(db, ff).name.display(f.db, f.edition())
|
||||
)?,
|
||||
CallableDefId::StructId(s) => {
|
||||
write!(f, "{}", db.struct_signature(s).name.display(f.db, f.edition()))?
|
||||
write!(f, "{}", StructSignature::of(db, s).name.display(f.db, f.edition()))?
|
||||
}
|
||||
CallableDefId::EnumVariantId(e) => {
|
||||
let loc = e.lookup(db);
|
||||
@@ -1235,9 +1246,11 @@ fn hir_fmt(&self, f @ &mut HirFormatter { db, .. }: &mut HirFormatter<'_, 'db>)
|
||||
match f.display_kind {
|
||||
DisplayKind::Diagnostics | DisplayKind::Test => {
|
||||
let name = match def_id {
|
||||
hir_def::AdtId::StructId(it) => db.struct_signature(it).name.clone(),
|
||||
hir_def::AdtId::UnionId(it) => db.union_signature(it).name.clone(),
|
||||
hir_def::AdtId::EnumId(it) => db.enum_signature(it).name.clone(),
|
||||
hir_def::AdtId::StructId(it) => {
|
||||
StructSignature::of(db, it).name.clone()
|
||||
}
|
||||
hir_def::AdtId::UnionId(it) => UnionSignature::of(db, it).name.clone(),
|
||||
hir_def::AdtId::EnumId(it) => EnumSignature::of(db, it).name.clone(),
|
||||
};
|
||||
write!(f, "{}", name.display(f.db, f.edition()))?;
|
||||
}
|
||||
@@ -1272,7 +1285,7 @@ fn hir_fmt(&self, f @ &mut HirFormatter { db, .. }: &mut HirFormatter<'_, 'db>)
|
||||
write_projection(f, &alias_ty, trait_bounds_need_parens)?
|
||||
}
|
||||
TyKind::Foreign(alias) => {
|
||||
let type_alias = db.type_alias_signature(alias.0);
|
||||
let type_alias = TypeAliasSignature::of(db, alias.0);
|
||||
f.start_location_link(alias.0.into());
|
||||
write!(f, "{}", type_alias.name.display(f.db, f.edition()))?;
|
||||
f.end_location_link();
|
||||
@@ -1336,8 +1349,8 @@ fn hir_fmt(&self, f @ &mut HirFormatter { db, .. }: &mut HirFormatter<'_, 'db>)
|
||||
}
|
||||
let sig = interner.signature_unclosure(substs.as_closure().sig(), Safety::Safe);
|
||||
let sig = sig.skip_binder();
|
||||
let InternedClosure(def, _) = db.lookup_intern_closure(id);
|
||||
let infer = InferenceResult::for_body(db, def);
|
||||
let InternedClosure(owner, _) = db.lookup_intern_closure(id);
|
||||
let infer = InferenceResult::of(db, owner);
|
||||
let (_, kind) = infer.closure_info(id);
|
||||
match f.closure_style {
|
||||
ClosureStyle::ImplFn => write!(f, "impl {kind:?}(")?,
|
||||
@@ -1526,7 +1539,7 @@ fn hir_fmt(&self, f @ &mut HirFormatter { db, .. }: &mut HirFormatter<'_, 'db>)
|
||||
let InternedCoroutine(owner, expr_id) = coroutine_id.0.loc(db);
|
||||
let CoroutineArgsParts { resume_ty, yield_ty, return_ty, .. } =
|
||||
subst.split_coroutine_args();
|
||||
let body = db.body(owner);
|
||||
let body = ExpressionStore::of(db, owner);
|
||||
let expr = &body[expr_id];
|
||||
match expr {
|
||||
hir_def::hir::Expr::Closure {
|
||||
@@ -1867,7 +1880,7 @@ fn write_bounds_like_dyn_trait<'db>(
|
||||
// existential) here, which is the only thing that's
|
||||
// possible in actual Rust, and hence don't print it
|
||||
f.start_location_link(trait_.into());
|
||||
write!(f, "{}", f.db.trait_signature(trait_).name.display(f.db, f.edition()))?;
|
||||
write!(f, "{}", TraitSignature::of(f.db, trait_).name.display(f.db, f.edition()))?;
|
||||
f.end_location_link();
|
||||
if is_fn_trait {
|
||||
if let [_self, params @ ..] = trait_ref.trait_ref.args.as_slice()
|
||||
@@ -1930,7 +1943,7 @@ fn write_bounds_like_dyn_trait<'db>(
|
||||
angle_open = true;
|
||||
}
|
||||
let assoc_ty_id = projection.def_id().expect_type_alias();
|
||||
let type_alias = f.db.type_alias_signature(assoc_ty_id);
|
||||
let type_alias = TypeAliasSignature::of(f.db, assoc_ty_id);
|
||||
f.start_location_link(assoc_ty_id.into());
|
||||
write!(f, "{}", type_alias.name.display(f.db, f.edition()))?;
|
||||
f.end_location_link();
|
||||
@@ -2021,7 +2034,7 @@ impl<'db> HirDisplay<'db> for TraitRef<'db> {
|
||||
fn hir_fmt(&self, f: &mut HirFormatter<'_, 'db>) -> Result {
|
||||
let trait_ = self.def_id.0;
|
||||
f.start_location_link(trait_.into());
|
||||
write!(f, "{}", f.db.trait_signature(trait_).name.display(f.db, f.edition()))?;
|
||||
write!(f, "{}", TraitSignature::of(f.db, trait_).name.display(f.db, f.edition()))?;
|
||||
f.end_location_link();
|
||||
let substs = self.args.as_slice();
|
||||
hir_fmt_generic_args(f, &substs[1..], None, Some(self.self_ty()))
|
||||
@@ -2128,7 +2141,7 @@ fn hir_fmt(&self, f: &mut HirFormatter<'_, 'db>, store: &ExpressionStore) -> Res
|
||||
LifetimeRef::Placeholder => write!(f, "'_"),
|
||||
LifetimeRef::Error => write!(f, "'{{error}}"),
|
||||
&LifetimeRef::Param(lifetime_param_id) => {
|
||||
let generic_params = f.db.generic_params(lifetime_param_id.parent);
|
||||
let generic_params = GenericParams::of(f.db, lifetime_param_id.parent);
|
||||
write!(
|
||||
f,
|
||||
"{}",
|
||||
@@ -2144,7 +2157,7 @@ fn hir_fmt(&self, f: &mut HirFormatter<'_, 'db>, store: &ExpressionStore) -> Res
|
||||
match &store[*self] {
|
||||
TypeRef::Never => write!(f, "!")?,
|
||||
TypeRef::TypeParam(param) => {
|
||||
let generic_params = f.db.generic_params(param.parent());
|
||||
let generic_params = GenericParams::of(f.db, param.parent());
|
||||
match generic_params[param.local_id()].name() {
|
||||
Some(name) => write!(f, "{}", name.display(f.db, f.edition()))?,
|
||||
None => {
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
//! Utilities for computing drop info about types.
|
||||
|
||||
use hir_def::{AdtId, signatures::StructFlags};
|
||||
use hir_def::{
|
||||
AdtId,
|
||||
signatures::{StructFlags, StructSignature},
|
||||
};
|
||||
use rustc_hash::FxHashSet;
|
||||
use rustc_type_ir::inherent::{AdtDef, IntoKind};
|
||||
use stdx::never;
|
||||
@@ -73,8 +76,7 @@ fn has_drop_glue_impl<'db>(
|
||||
}
|
||||
match adt_id {
|
||||
AdtId::StructId(id) => {
|
||||
if db
|
||||
.struct_signature(id)
|
||||
if StructSignature::of(db, id)
|
||||
.flags
|
||||
.intersects(StructFlags::IS_MANUALLY_DROP | StructFlags::IS_PHANTOM_DATA)
|
||||
{
|
||||
@@ -132,9 +134,9 @@ fn has_drop_glue_impl<'db>(
|
||||
TyKind::Slice(ty) => has_drop_glue_impl(infcx, ty, env, visited),
|
||||
TyKind::Closure(closure_id, subst) => {
|
||||
let owner = db.lookup_intern_closure(closure_id.0).0;
|
||||
let infer = InferenceResult::for_body(db, owner);
|
||||
let infer = InferenceResult::of(db, owner);
|
||||
let (captures, _) = infer.closure_info(closure_id.0);
|
||||
let env = db.trait_environment_for_body(owner);
|
||||
let env = db.trait_environment(owner);
|
||||
captures
|
||||
.iter()
|
||||
.map(|capture| has_drop_glue_impl(infcx, capture.ty(db, subst), env, visited))
|
||||
|
||||
@@ -4,8 +4,10 @@
|
||||
|
||||
use hir_def::{
|
||||
AssocItemId, ConstId, FunctionId, GenericDefId, HasModule, TraitId, TypeAliasId,
|
||||
TypeOrConstParamId, TypeParamId, hir::generics::LocalTypeOrConstParamId,
|
||||
nameres::crate_def_map, signatures::TraitFlags,
|
||||
TypeOrConstParamId, TypeParamId,
|
||||
hir::generics::{GenericParams, LocalTypeOrConstParamId},
|
||||
nameres::crate_def_map,
|
||||
signatures::{FunctionSignature, TraitFlags, TraitSignature},
|
||||
};
|
||||
use rustc_hash::FxHashSet;
|
||||
use rustc_type_ir::{
|
||||
@@ -298,7 +300,7 @@ fn dyn_compatibility_violation_for_assoc_item<F>(
|
||||
if def_map.is_unstable_feature_enabled(&intern::sym::generic_associated_type_extended) {
|
||||
ControlFlow::Continue(())
|
||||
} else {
|
||||
let generic_params = db.generic_params(item.into());
|
||||
let generic_params = GenericParams::of(db, item.into());
|
||||
if !generic_params.is_empty() {
|
||||
cb(DynCompatibilityViolation::GAT(it))
|
||||
} else {
|
||||
@@ -318,7 +320,7 @@ fn virtual_call_violations_for_method<F>(
|
||||
where
|
||||
F: FnMut(MethodViolationCode) -> ControlFlow<()>,
|
||||
{
|
||||
let func_data = db.function_signature(func);
|
||||
let func_data = FunctionSignature::of(db, func);
|
||||
if !func_data.has_self_param() {
|
||||
cb(MethodViolationCode::StaticMethod)?;
|
||||
}
|
||||
@@ -349,7 +351,7 @@ fn virtual_call_violations_for_method<F>(
|
||||
cb(mvc)?;
|
||||
}
|
||||
|
||||
let generic_params = db.generic_params(func.into());
|
||||
let generic_params = GenericParams::of(db, func.into());
|
||||
if generic_params.len_type_or_consts() > 0 {
|
||||
cb(MethodViolationCode::Generic)?;
|
||||
}
|
||||
@@ -371,7 +373,7 @@ fn virtual_call_violations_for_method<F>(
|
||||
trait_ref: pred_trait_ref,
|
||||
polarity: PredicatePolarity::Positive,
|
||||
}) = pred
|
||||
&& let trait_data = db.trait_signature(pred_trait_ref.def_id.0)
|
||||
&& let trait_data = TraitSignature::of(db, pred_trait_ref.def_id.0)
|
||||
&& trait_data.flags.contains(TraitFlags::AUTO)
|
||||
&& let rustc_type_ir::TyKind::Param(ParamTy { index: 0, .. }) =
|
||||
pred_trait_ref.self_ty().kind()
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use std::ops::ControlFlow;
|
||||
|
||||
use hir_def::db::DefDatabase;
|
||||
use hir_def::signatures::TraitSignature;
|
||||
use rustc_hash::{FxHashMap, FxHashSet};
|
||||
use syntax::ToSmolStr;
|
||||
use test_fixture::WithFixture;
|
||||
@@ -40,8 +40,7 @@ fn check_dyn_compatibility<'a>(
|
||||
.declarations()
|
||||
.filter_map(|def| {
|
||||
if let hir_def::ModuleDefId::TraitId(trait_id) = def {
|
||||
let name = db
|
||||
.trait_signature(trait_id)
|
||||
let name = TraitSignature::of(&db, trait_id)
|
||||
.name
|
||||
.display_no_db(file_id.edition(&db))
|
||||
.to_smolstr();
|
||||
|
||||
@@ -20,24 +20,23 @@
|
||||
},
|
||||
};
|
||||
use itertools::chain;
|
||||
use triomphe::Arc;
|
||||
|
||||
pub fn generics(db: &dyn DefDatabase, def: GenericDefId) -> Generics {
|
||||
pub fn generics(db: &dyn DefDatabase, def: GenericDefId) -> Generics<'_> {
|
||||
let parent_generics = parent_generic_def(db, def).map(|def| Box::new(generics(db, def)));
|
||||
let (params, store) = db.generic_params_and_store(def);
|
||||
let (params, store) = GenericParams::with_store(db, def);
|
||||
let has_trait_self_param = params.trait_self_param().is_some();
|
||||
Generics { def, params, parent_generics, has_trait_self_param, store }
|
||||
}
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Generics {
|
||||
pub struct Generics<'db> {
|
||||
def: GenericDefId,
|
||||
params: Arc<GenericParams>,
|
||||
store: Arc<ExpressionStore>,
|
||||
parent_generics: Option<Box<Generics>>,
|
||||
params: &'db GenericParams,
|
||||
store: &'db ExpressionStore,
|
||||
parent_generics: Option<Box<Generics<'db>>>,
|
||||
has_trait_self_param: bool,
|
||||
}
|
||||
|
||||
impl<T> ops::Index<T> for Generics
|
||||
impl<T> ops::Index<T> for Generics<'_>
|
||||
where
|
||||
GenericParams: ops::Index<T>,
|
||||
{
|
||||
@@ -47,13 +46,13 @@ fn index(&self, index: T) -> &Self::Output {
|
||||
}
|
||||
}
|
||||
|
||||
impl Generics {
|
||||
impl<'db> Generics<'db> {
|
||||
pub(crate) fn def(&self) -> GenericDefId {
|
||||
self.def
|
||||
}
|
||||
|
||||
pub(crate) fn store(&self) -> &ExpressionStore {
|
||||
&self.store
|
||||
self.store
|
||||
}
|
||||
|
||||
pub(crate) fn where_predicates(&self) -> impl Iterator<Item = &WherePredicate> {
|
||||
@@ -97,7 +96,7 @@ pub(crate) fn iter_parents_with_store(
|
||||
) -> impl Iterator<Item = ((GenericParamId, GenericParamDataRef<'_>), &ExpressionStore)> + '_
|
||||
{
|
||||
self.iter_parent()
|
||||
.zip(self.parent_generics().into_iter().flat_map(|it| std::iter::repeat(&*it.store)))
|
||||
.zip(self.parent_generics().into_iter().flat_map(|it| std::iter::repeat(it.store)))
|
||||
}
|
||||
|
||||
/// Iterate over the params without parent params.
|
||||
@@ -185,7 +184,7 @@ fn find_type_or_const_param(&self, param: TypeOrConstParamId) -> Option<usize> {
|
||||
if param.parent == self.def {
|
||||
let idx = param.local_id.into_raw().into_u32() as usize;
|
||||
debug_assert!(
|
||||
idx <= self.params.len_type_or_consts(),
|
||||
idx < self.params.len_type_or_consts(),
|
||||
"idx: {} len: {}",
|
||||
idx,
|
||||
self.params.len_type_or_consts()
|
||||
@@ -219,7 +218,7 @@ fn find_lifetime(&self, lifetime: LifetimeParamId) -> Option<usize> {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn parent_generics(&self) -> Option<&Generics> {
|
||||
pub(crate) fn parent_generics(&self) -> Option<&Generics<'db>> {
|
||||
self.parent_generics.as_deref()
|
||||
}
|
||||
}
|
||||
@@ -243,7 +242,7 @@ pub(crate) fn parent_generic_def(db: &dyn DefDatabase, def: GenericDefId) -> Opt
|
||||
}
|
||||
|
||||
fn from_toc_id<'a>(
|
||||
it: &'a Generics,
|
||||
it: &'a Generics<'a>,
|
||||
) -> impl Fn(
|
||||
(LocalTypeOrConstParamId, &'a TypeOrConstParamData),
|
||||
) -> (GenericParamId, GenericParamDataRef<'a>) {
|
||||
@@ -263,7 +262,7 @@ fn from_toc_id<'a>(
|
||||
}
|
||||
|
||||
fn from_lt_id<'a>(
|
||||
it: &'a Generics,
|
||||
it: &'a Generics<'a>,
|
||||
) -> impl Fn((LocalLifetimeParamId, &'a LifetimeParamData)) -> (GenericParamId, GenericParamDataRef<'a>)
|
||||
{
|
||||
move |(local_id, p): (_, _)| {
|
||||
|
||||
@@ -33,14 +33,15 @@
|
||||
use base_db::Crate;
|
||||
use either::Either;
|
||||
use hir_def::{
|
||||
AdtId, AssocItemId, ConstId, DefWithBodyId, FieldId, FunctionId, GenericDefId, GenericParamId,
|
||||
ItemContainerId, LocalFieldId, Lookup, TraitId, TupleFieldId, TupleId, TypeAliasId, VariantId,
|
||||
expr_store::{Body, ExpressionStore, HygieneId, path::Path},
|
||||
AdtId, AssocItemId, ConstId, ConstParamId, DefWithBodyId, ExpressionStoreOwnerId, FieldId,
|
||||
FunctionId, GenericDefId, GenericParamId, ItemContainerId, LocalFieldId, Lookup, TraitId,
|
||||
TupleFieldId, TupleId, TypeAliasId, TypeOrConstParamId, VariantId,
|
||||
expr_store::{Body, ExpressionStore, HygieneId, RootExprOrigin, path::Path},
|
||||
hir::{BindingAnnotation, BindingId, ExprId, ExprOrPatId, LabelId, PatId},
|
||||
lang_item::LangItems,
|
||||
layout::Integer,
|
||||
resolver::{HasResolver, ResolveValueResult, Resolver, TypeNs, ValueNs},
|
||||
signatures::{ConstSignature, EnumSignature, StaticSignature},
|
||||
signatures::{ConstSignature, EnumSignature, FunctionSignature, StaticSignature},
|
||||
type_ref::{ConstRef, LifetimeRefId, TypeRef, TypeRefId},
|
||||
};
|
||||
use hir_expand::{mod_path::ModPath, name::Name};
|
||||
@@ -104,19 +105,18 @@ pub fn infer_query_with_inspect<'db>(
|
||||
) -> InferenceResult {
|
||||
let _p = tracing::info_span!("infer_query").entered();
|
||||
let resolver = def.resolver(db);
|
||||
let body = db.body(def);
|
||||
let mut ctx = InferenceContext::new(db, def, &body, resolver);
|
||||
let body = Body::of(db, def);
|
||||
let mut ctx =
|
||||
InferenceContext::new(db, ExpressionStoreOwnerId::Body(def), &body.store, resolver);
|
||||
|
||||
if let Some(inspect) = inspect {
|
||||
ctx.table.infer_ctxt.attach_obligation_inspector(inspect);
|
||||
}
|
||||
|
||||
match def {
|
||||
DefWithBodyId::FunctionId(f) => {
|
||||
ctx.collect_fn(f);
|
||||
}
|
||||
DefWithBodyId::ConstId(c) => ctx.collect_const(c, &db.const_signature(c)),
|
||||
DefWithBodyId::StaticId(s) => ctx.collect_static(&db.static_signature(s)),
|
||||
DefWithBodyId::FunctionId(f) => ctx.collect_fn(f, body.self_param, &body.params),
|
||||
DefWithBodyId::ConstId(c) => ctx.collect_const(c, ConstSignature::of(db, c)),
|
||||
DefWithBodyId::StaticId(s) => ctx.collect_static(StaticSignature::of(db, s)),
|
||||
DefWithBodyId::VariantId(v) => {
|
||||
ctx.return_ty = match EnumSignature::variant_body_type(db, v.lookup(db).parent) {
|
||||
hir_def::layout::IntegerType::Pointer(signed) => match signed {
|
||||
@@ -143,10 +143,113 @@ pub fn infer_query_with_inspect<'db>(
|
||||
}
|
||||
}
|
||||
|
||||
ctx.infer_body();
|
||||
ctx.infer_body(body.root_expr());
|
||||
|
||||
ctx.infer_mut_body();
|
||||
ctx.infer_mut_body(body.root_expr());
|
||||
|
||||
infer_finalize(ctx)
|
||||
}
|
||||
|
||||
fn infer_cycle_result(db: &dyn HirDatabase, _: salsa::Id, _: DefWithBodyId) -> InferenceResult {
|
||||
InferenceResult {
|
||||
has_errors: true,
|
||||
..InferenceResult::new(Ty::new_error(DbInterner::new_no_crate(db), ErrorGuaranteed))
|
||||
}
|
||||
}
|
||||
|
||||
/// Infer types for all const expressions in an item's signature.
|
||||
///
|
||||
/// This handles const expressions that appear in type positions within a generic
|
||||
/// item's signature, such as array lengths (`[T; N]`) and const generic arguments
|
||||
/// (`Foo<{ expr }>`). Each root expression is inferred independently within
|
||||
/// a shared `InferenceContext`, accumulating results into a single `InferenceResult`.
|
||||
fn infer_signature_query(db: &dyn HirDatabase, def: GenericDefId) -> InferenceResult {
|
||||
let _p = tracing::info_span!("infer_signature_query").entered();
|
||||
let store = ExpressionStore::of(db, def.into());
|
||||
let mut roots = store.expr_roots_with_origins().peekable();
|
||||
let Some(_) = roots.peek() else {
|
||||
return InferenceResult::new(crate::next_solver::default_types(db).types.error);
|
||||
};
|
||||
|
||||
let resolver = def.resolver(db);
|
||||
let owner = ExpressionStoreOwnerId::Signature(def);
|
||||
|
||||
let mut ctx = InferenceContext::new(db, owner, store, resolver);
|
||||
|
||||
for (root_expr, origin) in roots {
|
||||
let expected = match origin {
|
||||
// Array lengths are always `usize`.
|
||||
RootExprOrigin::ArrayLength => Expectation::has_type(ctx.types.types.usize),
|
||||
// Const parameter default: look up the param's declared type.
|
||||
RootExprOrigin::ConstParam(local_id) => Expectation::has_type(db.const_param_ty_ns(
|
||||
ConstParamId::from_unchecked(TypeOrConstParamId { parent: def, local_id }),
|
||||
)),
|
||||
// Path const generic args: determining the expected type requires
|
||||
// path resolution.
|
||||
// FIXME
|
||||
RootExprOrigin::GenericArgsPath => Expectation::None,
|
||||
RootExprOrigin::BodyRoot => Expectation::None,
|
||||
};
|
||||
ctx.infer_expr(root_expr, &expected, ExprIsRead::Yes);
|
||||
}
|
||||
|
||||
infer_finalize(ctx)
|
||||
}
|
||||
|
||||
fn infer_variant_fields_query(db: &dyn HirDatabase, def: VariantId) -> InferenceResult {
|
||||
let _p = tracing::info_span!("infer_variant_fields_query").entered();
|
||||
let store = ExpressionStore::of(db, def.into());
|
||||
let mut roots = store.expr_roots_with_origins().peekable();
|
||||
let Some(_) = roots.peek() else {
|
||||
return InferenceResult::new(crate::next_solver::default_types(db).types.error);
|
||||
};
|
||||
|
||||
let resolver = def.resolver(db);
|
||||
let owner = ExpressionStoreOwnerId::VariantFields(def);
|
||||
|
||||
let mut ctx = InferenceContext::new(db, owner, store, resolver);
|
||||
|
||||
for (root_expr, origin) in roots {
|
||||
let expected = match origin {
|
||||
// Array lengths are always `usize`.
|
||||
RootExprOrigin::ArrayLength => Expectation::has_type(ctx.types.types.usize),
|
||||
// unreachable
|
||||
RootExprOrigin::ConstParam(_) => Expectation::None,
|
||||
// Path const generic args: determining the expected type requires
|
||||
// path resolution.
|
||||
// FIXME
|
||||
RootExprOrigin::GenericArgsPath => Expectation::None,
|
||||
RootExprOrigin::BodyRoot => Expectation::None,
|
||||
};
|
||||
ctx.infer_expr(root_expr, &expected, ExprIsRead::Yes);
|
||||
}
|
||||
|
||||
infer_finalize(ctx)
|
||||
}
|
||||
|
||||
fn infer_signature_cycle_result(
|
||||
db: &dyn HirDatabase,
|
||||
_: salsa::Id,
|
||||
_: GenericDefId,
|
||||
) -> InferenceResult {
|
||||
InferenceResult {
|
||||
has_errors: true,
|
||||
..InferenceResult::new(Ty::new_error(DbInterner::new_no_crate(db), ErrorGuaranteed))
|
||||
}
|
||||
}
|
||||
|
||||
fn infer_variant_fields_cycle_result(
|
||||
db: &dyn HirDatabase,
|
||||
_: salsa::Id,
|
||||
_: VariantId,
|
||||
) -> InferenceResult {
|
||||
InferenceResult {
|
||||
has_errors: true,
|
||||
..InferenceResult::new(Ty::new_error(DbInterner::new_no_crate(db), ErrorGuaranteed))
|
||||
}
|
||||
}
|
||||
|
||||
fn infer_finalize(mut ctx: InferenceContext<'_, '_>) -> InferenceResult {
|
||||
ctx.handle_opaque_type_uses();
|
||||
|
||||
ctx.type_inference_fallback();
|
||||
@@ -171,14 +274,6 @@ pub fn infer_query_with_inspect<'db>(
|
||||
|
||||
ctx.resolve_all()
|
||||
}
|
||||
|
||||
fn infer_cycle_result(db: &dyn HirDatabase, _: salsa::Id, _: DefWithBodyId) -> InferenceResult {
|
||||
InferenceResult {
|
||||
has_errors: true,
|
||||
..InferenceResult::new(Ty::new_error(DbInterner::new_no_crate(db), ErrorGuaranteed))
|
||||
}
|
||||
}
|
||||
|
||||
/// Binding modes inferred for patterns.
|
||||
/// <https://doc.rust-lang.org/reference/patterns.html#binding-modes>
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, Default)]
|
||||
@@ -552,12 +647,39 @@ pub struct InferenceResult {
|
||||
#[salsa::tracked]
|
||||
impl InferenceResult {
|
||||
#[salsa::tracked(returns(ref), cycle_result = infer_cycle_result)]
|
||||
pub fn for_body(db: &dyn HirDatabase, def: DefWithBodyId) -> InferenceResult {
|
||||
fn for_body(db: &dyn HirDatabase, def: DefWithBodyId) -> InferenceResult {
|
||||
infer_query(db, def)
|
||||
}
|
||||
|
||||
/// Infer types for all const expressions in an item's signature.
|
||||
///
|
||||
/// Returns an `InferenceResult` containing type information for array lengths,
|
||||
/// const generic arguments, and other const expressions appearing in type
|
||||
/// positions within the item's signature.
|
||||
#[salsa::tracked(returns(ref), cycle_result = infer_signature_cycle_result)]
|
||||
fn for_signature(db: &dyn HirDatabase, def: GenericDefId) -> InferenceResult {
|
||||
infer_signature_query(db, def)
|
||||
}
|
||||
|
||||
#[salsa::tracked(returns(ref), cycle_result = infer_variant_fields_cycle_result)]
|
||||
fn for_variant_fields(db: &dyn HirDatabase, def: VariantId) -> InferenceResult {
|
||||
infer_variant_fields_query(db, def)
|
||||
}
|
||||
}
|
||||
|
||||
impl InferenceResult {
|
||||
pub fn of(db: &dyn HirDatabase, def: impl Into<ExpressionStoreOwnerId>) -> &InferenceResult {
|
||||
match def.into() {
|
||||
ExpressionStoreOwnerId::Signature(generic_def_id) => {
|
||||
Self::for_signature(db, generic_def_id)
|
||||
}
|
||||
ExpressionStoreOwnerId::Body(def_with_body_id) => Self::for_body(db, def_with_body_id),
|
||||
ExpressionStoreOwnerId::VariantFields(variant_id) => {
|
||||
Self::for_variant_fields(db, variant_id)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn new(error_ty: Ty<'_>) -> Self {
|
||||
Self {
|
||||
method_resolutions: Default::default(),
|
||||
@@ -754,8 +876,8 @@ pub fn binding_ty<'db>(&self, id: BindingId) -> Ty<'db> {
|
||||
#[derive(Clone, Debug)]
|
||||
pub(crate) struct InferenceContext<'body, 'db> {
|
||||
pub(crate) db: &'db dyn HirDatabase,
|
||||
pub(crate) owner: DefWithBodyId,
|
||||
pub(crate) body: &'body Body,
|
||||
pub(crate) owner: ExpressionStoreOwnerId,
|
||||
pub(crate) store: &'body ExpressionStore,
|
||||
/// Generally you should not resolve things via this resolver. Instead create a TyLoweringContext
|
||||
/// and resolve the path via its methods. This will ensure proper error reporting.
|
||||
pub(crate) resolver: Resolver<'db>,
|
||||
@@ -855,11 +977,21 @@ fn find_continuable<'a, 'db>(
|
||||
impl<'body, 'db> InferenceContext<'body, 'db> {
|
||||
fn new(
|
||||
db: &'db dyn HirDatabase,
|
||||
owner: DefWithBodyId,
|
||||
body: &'body Body,
|
||||
owner: ExpressionStoreOwnerId,
|
||||
store: &'body ExpressionStore,
|
||||
resolver: Resolver<'db>,
|
||||
) -> Self {
|
||||
let trait_env = db.trait_environment_for_body(owner);
|
||||
let trait_env = match owner {
|
||||
ExpressionStoreOwnerId::Signature(generic_def_id) => {
|
||||
db.trait_environment(ExpressionStoreOwnerId::from(generic_def_id))
|
||||
}
|
||||
ExpressionStoreOwnerId::Body(def_with_body_id) => {
|
||||
db.trait_environment(ExpressionStoreOwnerId::Body(def_with_body_id))
|
||||
}
|
||||
ExpressionStoreOwnerId::VariantFields(variant_id) => {
|
||||
db.trait_environment(ExpressionStoreOwnerId::VariantFields(variant_id))
|
||||
}
|
||||
};
|
||||
let table = unify::InferenceTable::new(db, trait_env, resolver.krate(), Some(owner));
|
||||
let types = crate::next_solver::default_types(db);
|
||||
InferenceContext {
|
||||
@@ -878,13 +1010,8 @@ fn new(
|
||||
return_coercion: None,
|
||||
db,
|
||||
owner,
|
||||
generic_def: match owner {
|
||||
DefWithBodyId::FunctionId(it) => it.into(),
|
||||
DefWithBodyId::StaticId(it) => it.into(),
|
||||
DefWithBodyId::ConstId(it) => it.into(),
|
||||
DefWithBodyId::VariantId(it) => it.lookup(db).parent.into(),
|
||||
},
|
||||
body,
|
||||
generic_def: owner.generic_def(db),
|
||||
store,
|
||||
traits_in_scope: resolver.traits_in_scope(db),
|
||||
resolver,
|
||||
diverges: Diverges::Maybe,
|
||||
@@ -908,7 +1035,9 @@ fn krate(&self) -> Crate {
|
||||
fn target_features(&self) -> (&TargetFeatures<'db>, TargetFeatureIsSafeInTarget) {
|
||||
let (target_features, target_feature_is_safe) = self.target_features.get_or_init(|| {
|
||||
let target_features = match self.owner {
|
||||
DefWithBodyId::FunctionId(id) => TargetFeatures::from_fn(self.db, id),
|
||||
ExpressionStoreOwnerId::Body(DefWithBodyId::FunctionId(id)) => {
|
||||
TargetFeatures::from_fn(self.db, id)
|
||||
}
|
||||
_ => TargetFeatures::default(),
|
||||
};
|
||||
let target_feature_is_safe = match &self.krate().workspace_data(self.db).target {
|
||||
@@ -1102,12 +1231,12 @@ fn collect_static(&mut self, data: &StaticSignature) {
|
||||
self.return_ty = return_ty;
|
||||
}
|
||||
|
||||
fn collect_fn(&mut self, func: FunctionId) {
|
||||
let data = self.db.function_signature(func);
|
||||
fn collect_fn(&mut self, func: FunctionId, self_param: Option<BindingId>, params: &[PatId]) {
|
||||
let data = FunctionSignature::of(self.db, func);
|
||||
let mut param_tys = self.with_ty_lowering(
|
||||
&data.store,
|
||||
InferenceTyDiagnosticSource::Signature,
|
||||
LifetimeElisionKind::for_fn_params(&data),
|
||||
LifetimeElisionKind::for_fn_params(data),
|
||||
|ctx| data.params.iter().map(|&type_ref| ctx.lower_ty(type_ref)).collect::<Vec<_>>(),
|
||||
);
|
||||
|
||||
@@ -1130,13 +1259,13 @@ fn collect_fn(&mut self, func: FunctionId) {
|
||||
param_tys.push(va_list_ty);
|
||||
}
|
||||
let mut param_tys = param_tys.into_iter().chain(iter::repeat(self.table.next_ty_var()));
|
||||
if let Some(self_param) = self.body.self_param
|
||||
if let Some(self_param) = self_param
|
||||
&& let Some(ty) = param_tys.next()
|
||||
{
|
||||
let ty = self.process_user_written_ty(ty);
|
||||
self.write_binding_ty(self_param, ty);
|
||||
}
|
||||
for (ty, pat) in param_tys.zip(&*self.body.params) {
|
||||
for (ty, pat) in param_tys.zip(params) {
|
||||
let ty = self.process_user_written_ty(ty);
|
||||
|
||||
self.infer_top_pat(*pat, ty, None);
|
||||
@@ -1170,12 +1299,12 @@ pub(crate) fn infcx(&self) -> &InferCtxt<'db> {
|
||||
&self.table.infer_ctxt
|
||||
}
|
||||
|
||||
fn infer_body(&mut self) {
|
||||
fn infer_body(&mut self, body_expr: ExprId) {
|
||||
match self.return_coercion {
|
||||
Some(_) => self.infer_return(self.body.body_expr),
|
||||
Some(_) => self.infer_return(body_expr),
|
||||
None => {
|
||||
_ = self.infer_expr_coerce(
|
||||
self.body.body_expr,
|
||||
body_expr,
|
||||
&Expectation::has_type(self.return_ty),
|
||||
ExprIsRead::Yes,
|
||||
)
|
||||
@@ -1282,7 +1411,7 @@ fn with_body_ty_lowering<R>(
|
||||
f: impl FnOnce(&mut TyLoweringContext<'db, '_>) -> R,
|
||||
) -> R {
|
||||
self.with_ty_lowering(
|
||||
self.body,
|
||||
self.store,
|
||||
InferenceTyDiagnosticSource::Body,
|
||||
LifetimeElisionKind::Infer,
|
||||
f,
|
||||
@@ -1324,7 +1453,7 @@ fn make_ty(
|
||||
pub(crate) fn make_body_ty(&mut self, type_ref: TypeRefId) -> Ty<'db> {
|
||||
self.make_ty(
|
||||
type_ref,
|
||||
self.body,
|
||||
self.store,
|
||||
InferenceTyDiagnosticSource::Body,
|
||||
LifetimeElisionKind::Infer,
|
||||
)
|
||||
@@ -1332,7 +1461,7 @@ pub(crate) fn make_body_ty(&mut self, type_ref: TypeRefId) -> Ty<'db> {
|
||||
|
||||
pub(crate) fn make_body_const(&mut self, const_ref: ConstRef, ty: Ty<'db>) -> Const<'db> {
|
||||
let const_ = self.with_ty_lowering(
|
||||
self.body,
|
||||
self.store,
|
||||
InferenceTyDiagnosticSource::Body,
|
||||
LifetimeElisionKind::Infer,
|
||||
|ctx| ctx.lower_const(const_ref, ty),
|
||||
@@ -1342,7 +1471,7 @@ pub(crate) fn make_body_const(&mut self, const_ref: ConstRef, ty: Ty<'db>) -> Co
|
||||
|
||||
pub(crate) fn make_path_as_body_const(&mut self, path: &Path, ty: Ty<'db>) -> Const<'db> {
|
||||
let const_ = self.with_ty_lowering(
|
||||
self.body,
|
||||
self.store,
|
||||
InferenceTyDiagnosticSource::Body,
|
||||
LifetimeElisionKind::Infer,
|
||||
|ctx| ctx.lower_path_as_const(path, ty),
|
||||
@@ -1356,7 +1485,7 @@ fn err_ty(&self) -> Ty<'db> {
|
||||
|
||||
pub(crate) fn make_body_lifetime(&mut self, lifetime_ref: LifetimeRefId) -> Region<'db> {
|
||||
let lt = self.with_ty_lowering(
|
||||
self.body,
|
||||
self.store,
|
||||
InferenceTyDiagnosticSource::Body,
|
||||
LifetimeElisionKind::Infer,
|
||||
|ctx| ctx.lower_lifetime(lifetime_ref),
|
||||
@@ -1571,7 +1700,7 @@ fn resolve_variant(
|
||||
let mut ctx = TyLoweringContext::new(
|
||||
self.db,
|
||||
&self.resolver,
|
||||
&self.body.store,
|
||||
self.store,
|
||||
&self.diagnostics,
|
||||
InferenceTyDiagnosticSource::Body,
|
||||
self.generic_def,
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
//! Type cast logic. Basically coercion + additional casts.
|
||||
|
||||
use hir_def::{AdtId, hir::ExprId, signatures::TraitFlags};
|
||||
use hir_def::{
|
||||
AdtId,
|
||||
hir::ExprId,
|
||||
signatures::{TraitFlags, TraitSignature},
|
||||
};
|
||||
use rustc_ast_ir::Mutability;
|
||||
use rustc_hash::FxHashSet;
|
||||
use rustc_type_ir::{
|
||||
@@ -383,8 +387,7 @@ fn check_ptr_ptr_cast(
|
||||
.chain(
|
||||
elaborate::supertrait_def_ids(ctx.interner(), src_principal)
|
||||
.filter(|trait_| {
|
||||
ctx.db
|
||||
.trait_signature(trait_.0)
|
||||
TraitSignature::of(ctx.db, trait_.0)
|
||||
.flags
|
||||
.contains(TraitFlags::AUTO)
|
||||
}),
|
||||
|
||||
@@ -4,14 +4,15 @@
|
||||
|
||||
use base_db::Crate;
|
||||
use hir_def::{
|
||||
DefWithBodyId, FieldId, HasModule, VariantId,
|
||||
expr_store::path::Path,
|
||||
ExpressionStoreOwnerId, FieldId, HasModule, VariantId,
|
||||
expr_store::{Body, ExpressionStore, path::Path},
|
||||
hir::{
|
||||
Array, AsmOperand, BinaryOp, BindingId, CaptureBy, Expr, ExprId, ExprOrPatId, Pat, PatId,
|
||||
RecordSpread, Statement, UnaryOp,
|
||||
},
|
||||
item_tree::FieldsShape,
|
||||
resolver::ValueNs,
|
||||
signatures::VariantFields,
|
||||
};
|
||||
use rustc_ast_ir::Mutability;
|
||||
use rustc_hash::{FxHashMap, FxHashSet};
|
||||
@@ -179,9 +180,26 @@ pub fn kind(&self) -> CaptureKind {
|
||||
}
|
||||
|
||||
/// Converts the place to a name that can be inserted into source code.
|
||||
pub fn place_to_name(&self, owner: DefWithBodyId, db: &dyn HirDatabase) -> String {
|
||||
let body = db.body(owner);
|
||||
let mut result = body[self.place.local].name.as_str().to_owned();
|
||||
pub fn place_to_name(&self, owner: ExpressionStoreOwnerId, db: &dyn HirDatabase) -> String {
|
||||
let krate = owner.krate(db);
|
||||
let edition = krate.data(db).edition;
|
||||
let mut result = match owner {
|
||||
ExpressionStoreOwnerId::Signature(generic_def_id) => {
|
||||
ExpressionStore::of(db, generic_def_id.into())[self.place.local]
|
||||
.name
|
||||
.display(db, edition)
|
||||
.to_string()
|
||||
}
|
||||
ExpressionStoreOwnerId::Body(def_with_body_id) => Body::of(db, def_with_body_id)
|
||||
[self.place.local]
|
||||
.name
|
||||
.display(db, edition)
|
||||
.to_string(),
|
||||
ExpressionStoreOwnerId::VariantFields(variant_id) => {
|
||||
let fields = VariantFields::of(db, variant_id);
|
||||
fields.store[self.place.local].name.display(db, edition).to_string()
|
||||
}
|
||||
};
|
||||
for proj in &self.place.projections {
|
||||
match proj {
|
||||
HirPlaceProjection::Deref => {}
|
||||
@@ -213,11 +231,30 @@ pub fn place_to_name(&self, owner: DefWithBodyId, db: &dyn HirDatabase) -> Strin
|
||||
result
|
||||
}
|
||||
|
||||
pub fn display_place_source_code(&self, owner: DefWithBodyId, db: &dyn HirDatabase) -> String {
|
||||
let body = db.body(owner);
|
||||
pub fn display_place_source_code(
|
||||
&self,
|
||||
owner: ExpressionStoreOwnerId,
|
||||
db: &dyn HirDatabase,
|
||||
) -> String {
|
||||
let krate = owner.krate(db);
|
||||
let edition = krate.data(db).edition;
|
||||
let mut result = body[self.place.local].name.display(db, edition).to_string();
|
||||
let mut result = match owner {
|
||||
ExpressionStoreOwnerId::Signature(generic_def_id) => {
|
||||
ExpressionStore::of(db, generic_def_id.into())[self.place.local]
|
||||
.name
|
||||
.display(db, edition)
|
||||
.to_string()
|
||||
}
|
||||
ExpressionStoreOwnerId::Body(def_with_body_id) => Body::of(db, def_with_body_id)
|
||||
[self.place.local]
|
||||
.name
|
||||
.display(db, edition)
|
||||
.to_string(),
|
||||
ExpressionStoreOwnerId::VariantFields(variant_id) => {
|
||||
let fields = VariantFields::of(db, variant_id);
|
||||
fields.store[self.place.local].name.display(db, edition).to_string()
|
||||
}
|
||||
};
|
||||
for proj in &self.place.projections {
|
||||
match proj {
|
||||
// In source code autoderef kicks in.
|
||||
@@ -258,11 +295,26 @@ pub fn display_place_source_code(&self, owner: DefWithBodyId, db: &dyn HirDataba
|
||||
result
|
||||
}
|
||||
|
||||
pub fn display_place(&self, owner: DefWithBodyId, db: &dyn HirDatabase) -> String {
|
||||
let body = db.body(owner);
|
||||
pub fn display_place(&self, owner: ExpressionStoreOwnerId, db: &dyn HirDatabase) -> String {
|
||||
let krate = owner.krate(db);
|
||||
let edition = krate.data(db).edition;
|
||||
let mut result = body[self.place.local].name.display(db, edition).to_string();
|
||||
let mut result = match owner {
|
||||
ExpressionStoreOwnerId::Signature(generic_def_id) => {
|
||||
ExpressionStore::of(db, generic_def_id.into())[self.place.local]
|
||||
.name
|
||||
.display(db, edition)
|
||||
.to_string()
|
||||
}
|
||||
ExpressionStoreOwnerId::Body(def_with_body_id) => Body::of(db, def_with_body_id)
|
||||
[self.place.local]
|
||||
.name
|
||||
.display(db, edition)
|
||||
.to_string(),
|
||||
ExpressionStoreOwnerId::VariantFields(variant_id) => {
|
||||
let fields = VariantFields::of(db, variant_id);
|
||||
fields.store[self.place.local].name.display(db, edition).to_string()
|
||||
}
|
||||
};
|
||||
let mut field_need_paren = false;
|
||||
for proj in &self.place.projections {
|
||||
match proj {
|
||||
@@ -346,7 +398,7 @@ fn path_place(&mut self, path: &Path, id: ExprOrPatId) -> Option<HirPlace> {
|
||||
if path.type_anchor().is_some() {
|
||||
return None;
|
||||
}
|
||||
let hygiene = self.body.expr_or_pat_path_hygiene(id);
|
||||
let hygiene = self.store.expr_or_pat_path_hygiene(id);
|
||||
self.resolver.resolve_path_in_value_ns_fully(self.db, path, hygiene).and_then(|result| {
|
||||
match result {
|
||||
ValueNs::LocalBinding(binding) => {
|
||||
@@ -365,7 +417,7 @@ fn path_place(&mut self, path: &Path, id: ExprOrPatId) -> Option<HirPlace> {
|
||||
/// Changes `current_capture_span_stack` to contain the stack of spans for this expr.
|
||||
fn place_of_expr_without_adjust(&mut self, tgt_expr: ExprId) -> Option<HirPlace> {
|
||||
self.current_capture_span_stack.clear();
|
||||
match &self.body[tgt_expr] {
|
||||
match &self.store[tgt_expr] {
|
||||
Expr::Path(p) => {
|
||||
let resolver_guard =
|
||||
self.resolver.update_to_inner_scope(self.db, self.owner, tgt_expr);
|
||||
@@ -416,7 +468,7 @@ fn truncate_capture_spans(&self, capture: &mut CapturedItemWithoutTy, mut trunca
|
||||
let mut actual_truncate_to = 0;
|
||||
for &span in &*span_stack {
|
||||
actual_truncate_to += 1;
|
||||
if !span.is_ref_span(self.body) {
|
||||
if !span.is_ref_span(self.store) {
|
||||
remained -= 1;
|
||||
if remained == 0 {
|
||||
break;
|
||||
@@ -424,7 +476,7 @@ fn truncate_capture_spans(&self, capture: &mut CapturedItemWithoutTy, mut trunca
|
||||
}
|
||||
}
|
||||
if actual_truncate_to < span_stack.len()
|
||||
&& span_stack[actual_truncate_to].is_ref_span(self.body)
|
||||
&& span_stack[actual_truncate_to].is_ref_span(self.store)
|
||||
{
|
||||
// Include the ref operator if there is one, we will fix it later (in `strip_captures_ref_span()`) if it's incorrect.
|
||||
actual_truncate_to += 1;
|
||||
@@ -533,7 +585,7 @@ fn walk_expr(&mut self, tgt_expr: ExprId) {
|
||||
}
|
||||
|
||||
fn walk_expr_without_adjust(&mut self, tgt_expr: ExprId) {
|
||||
match &self.body[tgt_expr] {
|
||||
match &self.store[tgt_expr] {
|
||||
Expr::OffsetOf(_) => (),
|
||||
Expr::InlineAsm(e) => e.operands.iter().for_each(|(_, op)| match op {
|
||||
AsmOperand::In { expr, .. }
|
||||
@@ -733,7 +785,7 @@ fn walk_expr_without_adjust(&mut self, tgt_expr: ExprId) {
|
||||
self.consume_with_pat(rhs_place, target);
|
||||
self.inside_assignment = false;
|
||||
}
|
||||
None => self.body.walk_pats(target, &mut |pat| match &self.body[pat] {
|
||||
None => self.store.walk_pats(target, &mut |pat| match &self.store[pat] {
|
||||
Pat::Path(path) => self.mutate_path_pat(path, pat),
|
||||
&Pat::Expr(expr) => {
|
||||
let place = self.place_of_expr(expr);
|
||||
@@ -775,7 +827,7 @@ fn walk_pat_inner(
|
||||
update_result: &mut impl FnMut(CaptureKind),
|
||||
mut for_mut: BorrowKind,
|
||||
) {
|
||||
match &self.body[p] {
|
||||
match &self.store[p] {
|
||||
Pat::Ref { .. }
|
||||
| Pat::Box { .. }
|
||||
| Pat::Missing
|
||||
@@ -819,13 +871,13 @@ fn walk_pat_inner(
|
||||
if self.result.pat_adjustments.get(&p).is_some_and(|it| !it.is_empty()) {
|
||||
for_mut = BorrowKind::Mut { kind: MutBorrowKind::ClosureCapture };
|
||||
}
|
||||
self.body.walk_pats_shallow(p, |p| self.walk_pat_inner(p, update_result, for_mut));
|
||||
self.store.walk_pats_shallow(p, |p| self.walk_pat_inner(p, update_result, for_mut));
|
||||
}
|
||||
|
||||
fn is_upvar(&self, place: &HirPlace) -> bool {
|
||||
if let Some(c) = self.current_closure {
|
||||
let InternedClosure(_, root) = self.db.lookup_intern_closure(c);
|
||||
return self.body.is_binding_upvar(place.local, root);
|
||||
return self.store.is_binding_upvar(place.local, root);
|
||||
}
|
||||
false
|
||||
}
|
||||
@@ -858,7 +910,7 @@ fn restrict_precision_for_unsafe(&mut self) {
|
||||
if ty.is_raw_ptr() || ty.is_union() {
|
||||
capture.kind = CaptureKind::ByRef(BorrowKind::Shared);
|
||||
self.truncate_capture_spans(capture, 0);
|
||||
capture.place.projections.truncate(0);
|
||||
capture.place.projections.clear();
|
||||
continue;
|
||||
}
|
||||
for (i, p) in capture.place.projections.iter().enumerate() {
|
||||
@@ -866,7 +918,7 @@ fn restrict_precision_for_unsafe(&mut self) {
|
||||
&self.table.infer_ctxt,
|
||||
self.table.param_env,
|
||||
ty,
|
||||
self.owner.module(self.db).krate(self.db),
|
||||
self.owner.krate(self.db),
|
||||
);
|
||||
if ty.is_raw_ptr() || ty.is_union() {
|
||||
capture.kind = CaptureKind::ByRef(BorrowKind::Shared);
|
||||
@@ -938,7 +990,7 @@ fn consume_with_pat(&mut self, mut place: HirPlace, tgt_pat: PatId) {
|
||||
self.current_capture_span_stack
|
||||
.extend((0..adjustments_count).map(|_| MirSpan::PatId(tgt_pat)));
|
||||
'reset_span_stack: {
|
||||
match &self.body[tgt_pat] {
|
||||
match &self.store[tgt_pat] {
|
||||
Pat::Missing | Pat::Wild => (),
|
||||
Pat::Tuple { args, ellipsis } => {
|
||||
let (al, ar) = args.split_at(ellipsis.map_or(args.len(), |it| it as usize));
|
||||
@@ -1089,7 +1141,7 @@ fn closure_kind(&self) -> FnTrait {
|
||||
fn analyze_closure(&mut self, closure: InternedClosureId) -> FnTrait {
|
||||
let InternedClosure(_, root) = self.db.lookup_intern_closure(closure);
|
||||
self.current_closure = Some(closure);
|
||||
let Expr::Closure { body, capture_by, .. } = &self.body[root] else {
|
||||
let Expr::Closure { body, capture_by, .. } = &self.store[root] else {
|
||||
unreachable!("Closure expression id is always closure");
|
||||
};
|
||||
self.consume_expr(*body);
|
||||
@@ -1133,7 +1185,7 @@ fn strip_captures_ref_span(&mut self) {
|
||||
for capture in &mut captures {
|
||||
if matches!(capture.kind, CaptureKind::ByValue) {
|
||||
for span_stack in &mut capture.span_stacks {
|
||||
if span_stack[span_stack.len() - 1].is_ref_span(self.body) {
|
||||
if span_stack[span_stack.len() - 1].is_ref_span(self.store) {
|
||||
span_stack.truncate(span_stack.len() - 1);
|
||||
}
|
||||
}
|
||||
@@ -1149,7 +1201,7 @@ pub(crate) fn infer_closures(&mut self) {
|
||||
let kind = self.analyze_closure(closure);
|
||||
|
||||
for (derefed_callee, callee_ty, params, expr) in exprs {
|
||||
if let &Expr::Call { callee, .. } = &self.body[expr] {
|
||||
if let &Expr::Call { callee, .. } = &self.store[expr] {
|
||||
let mut adjustments =
|
||||
self.result.expr_adjustments.remove(&callee).unwrap_or_default().into_vec();
|
||||
self.write_fn_trait_method_resolution(
|
||||
|
||||
@@ -1718,6 +1718,9 @@ fn fold_region(&mut self, r: Region<'db>) -> Region<'db> {
|
||||
|
||||
fn is_capturing_closure(db: &dyn HirDatabase, closure: InternedClosureId) -> bool {
|
||||
let InternedClosure(owner, expr) = closure.loc(db);
|
||||
upvars_mentioned(db, owner)
|
||||
let Some(body_owner) = owner.as_def_with_body() else {
|
||||
return false;
|
||||
};
|
||||
upvars_mentioned(db, body_owner)
|
||||
.is_some_and(|upvars| upvars.get(&expr).is_some_and(|upvars| !upvars.is_empty()))
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
InlineAsmKind, LabelId, Literal, Pat, PatId, RecordSpread, Statement, UnaryOp,
|
||||
},
|
||||
resolver::ValueNs,
|
||||
signatures::{FunctionSignature, VariantFields},
|
||||
};
|
||||
use hir_def::{FunctionId, hir::ClosureKind};
|
||||
use hir_expand::name::Name;
|
||||
@@ -155,7 +156,7 @@ pub(super) fn expr_guaranteed_to_constitute_read_for_never(
|
||||
/// it is matching against. This is used to determine whether we should
|
||||
/// perform `NeverToAny` coercions.
|
||||
fn pat_guaranteed_to_constitute_read_for_never(&self, pat: PatId) -> bool {
|
||||
match &self.body[pat] {
|
||||
match &self.store[pat] {
|
||||
// Does not constitute a read.
|
||||
Pat::Wild => false,
|
||||
|
||||
@@ -197,25 +198,25 @@ fn pat_guaranteed_to_constitute_read_for_never(&self, pat: PatId) -> bool {
|
||||
// FIXME(tschottdorf): this is problematic as the HIR is being scraped, but
|
||||
// ref bindings are be implicit after #42640 (default match binding modes). See issue #44848.
|
||||
fn contains_explicit_ref_binding(&self, pat: PatId) -> bool {
|
||||
if let Pat::Bind { id, .. } = self.body[pat]
|
||||
&& matches!(self.body[id].mode, BindingAnnotation::Ref | BindingAnnotation::RefMut)
|
||||
if let Pat::Bind { id, .. } = self.store[pat]
|
||||
&& matches!(self.store[id].mode, BindingAnnotation::Ref | BindingAnnotation::RefMut)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
let mut result = false;
|
||||
self.body.walk_pats_shallow(pat, |pat| result |= self.contains_explicit_ref_binding(pat));
|
||||
self.store.walk_pats_shallow(pat, |pat| result |= self.contains_explicit_ref_binding(pat));
|
||||
result
|
||||
}
|
||||
|
||||
fn is_syntactic_place_expr(&self, expr: ExprId) -> bool {
|
||||
match &self.body[expr] {
|
||||
match &self.store[expr] {
|
||||
// Lang item paths cannot currently be local variables or statics.
|
||||
Expr::Path(Path::LangItem(_, _)) => false,
|
||||
Expr::Path(Path::Normal(path)) => path.type_anchor.is_none(),
|
||||
Expr::Path(path) => self
|
||||
.resolver
|
||||
.resolve_path_in_value_ns_fully(self.db, path, self.body.expr_path_hygiene(expr))
|
||||
.resolve_path_in_value_ns_fully(self.db, path, self.store.expr_path_hygiene(expr))
|
||||
.is_none_or(|res| matches!(res, ValueNs::LocalBinding(_) | ValueNs::StaticId(_))),
|
||||
Expr::Underscore => true,
|
||||
Expr::UnaryOp { op: UnaryOp::Deref, .. } => true,
|
||||
@@ -311,7 +312,7 @@ fn infer_expr_inner(
|
||||
) -> Ty<'db> {
|
||||
self.db.unwind_if_revision_cancelled();
|
||||
|
||||
let expr = &self.body[tgt_expr];
|
||||
let expr = &self.store[tgt_expr];
|
||||
tracing::trace!(?expr);
|
||||
let ty = match expr {
|
||||
Expr::Missing => self.err_ty(),
|
||||
@@ -608,7 +609,7 @@ fn infer_expr_inner(
|
||||
Some(def) => {
|
||||
let field_types = self.db.field_types(def);
|
||||
let variant_data = def.fields(self.db);
|
||||
let visibilities = self.db.field_visibilities(def);
|
||||
let visibilities = VariantFields::field_visibilities(self.db, def);
|
||||
for field in fields.iter() {
|
||||
let field_def = {
|
||||
match variant_data.field(&field.name) {
|
||||
@@ -717,7 +718,7 @@ fn infer_expr_inner(
|
||||
// instantiations in RHS can be coerced to it. Note that this
|
||||
// cannot happen in destructuring assignments because of how
|
||||
// they are desugared.
|
||||
let lhs_ty = match &self.body[target] {
|
||||
let lhs_ty = match &self.store[target] {
|
||||
// LHS of assignment doesn't constitute reads.
|
||||
&Pat::Expr(expr) => {
|
||||
Some(self.infer_expr(expr, &Expectation::none(), ExprIsRead::No))
|
||||
@@ -728,7 +729,7 @@ fn infer_expr_inner(
|
||||
let resolution = self.resolver.resolve_path_in_value_ns_fully(
|
||||
self.db,
|
||||
path,
|
||||
self.body.pat_path_hygiene(target),
|
||||
self.store.pat_path_hygiene(target),
|
||||
);
|
||||
self.resolver.reset_to_guard(resolver_guard);
|
||||
|
||||
@@ -1351,7 +1352,7 @@ fn infer_expr_array(&mut self, array: &Array, expected: &Expectation<'db>) -> Ty
|
||||
ExprIsRead::Yes,
|
||||
);
|
||||
let usize = self.types.types.usize;
|
||||
let len = match self.body[repeat] {
|
||||
let len = match self.store[repeat] {
|
||||
Expr::Underscore => {
|
||||
self.write_expr_ty(repeat, usize);
|
||||
self.table.next_const_var()
|
||||
@@ -1491,7 +1492,7 @@ fn infer_block(
|
||||
} else {
|
||||
ExprIsRead::No
|
||||
};
|
||||
let ty = if contains_explicit_ref_binding(this.body, *pat) {
|
||||
let ty = if contains_explicit_ref_binding(this.store, *pat) {
|
||||
this.infer_expr(
|
||||
*expr,
|
||||
&Expectation::has_type(decl_ty),
|
||||
@@ -1624,7 +1625,8 @@ fn lookup_field(
|
||||
},
|
||||
_ => return None,
|
||||
};
|
||||
let is_visible = self.db.field_visibilities(field_id.parent)[field_id.local_id]
|
||||
let is_visible = VariantFields::field_visibilities(self.db, field_id.parent)
|
||||
[field_id.local_id]
|
||||
.is_visible_from(self.db, self.resolver.module());
|
||||
if !is_visible {
|
||||
if private_field.is_none() {
|
||||
@@ -2117,7 +2119,7 @@ pub(in super::super) fn check_call_arguments(
|
||||
// the return value of an argument-position async block to an argument-position
|
||||
// closure wrapped in a block.
|
||||
// See <https://github.com/rust-lang/rust/issues/112225>.
|
||||
let is_closure = if let Expr::Closure { closure_kind, .. } = self.body[*arg] {
|
||||
let is_closure = if let Expr::Closure { closure_kind, .. } = self.store[*arg] {
|
||||
!matches!(closure_kind, ClosureKind::Coroutine(_))
|
||||
} else {
|
||||
false
|
||||
@@ -2194,7 +2196,7 @@ fn check_legacy_const_generics(&mut self, callee: Ty<'db>, args: &[ExprId]) -> B
|
||||
_ => return Default::default(),
|
||||
};
|
||||
|
||||
let data = self.db.function_signature(func);
|
||||
let data = FunctionSignature::of(self.db, func);
|
||||
let Some(legacy_const_generics_indices) = data.legacy_const_generics_indices(self.db, func)
|
||||
else {
|
||||
return Default::default();
|
||||
|
||||
@@ -14,8 +14,8 @@
|
||||
};
|
||||
|
||||
impl<'db> InferenceContext<'_, 'db> {
|
||||
pub(crate) fn infer_mut_body(&mut self) {
|
||||
self.infer_mut_expr(self.body.body_expr, Mutability::Not);
|
||||
pub(crate) fn infer_mut_body(&mut self, body_expr: ExprId) {
|
||||
self.infer_mut_expr(body_expr, Mutability::Not);
|
||||
}
|
||||
|
||||
fn infer_mut_expr(&mut self, tgt_expr: ExprId, mut mutability: Mutability) {
|
||||
@@ -52,7 +52,7 @@ fn infer_mut_expr(&mut self, tgt_expr: ExprId, mut mutability: Mutability) {
|
||||
}
|
||||
|
||||
fn infer_mut_expr_without_adjust(&mut self, tgt_expr: ExprId, mutability: Mutability) {
|
||||
match &self.body[tgt_expr] {
|
||||
match &self.store[tgt_expr] {
|
||||
Expr::Missing => (),
|
||||
Expr::InlineAsm(e) => {
|
||||
e.operands.iter().for_each(|(_, op)| match op {
|
||||
@@ -173,7 +173,7 @@ fn infer_mut_expr_without_adjust(&mut self, tgt_expr: ExprId, mutability: Mutabi
|
||||
self.infer_mut_expr(*rhs, Mutability::Not);
|
||||
}
|
||||
&Expr::Assignment { target, value } => {
|
||||
self.body.walk_pats(target, &mut |pat| match self.body[pat] {
|
||||
self.store.walk_pats(target, &mut |pat| match self.store[pat] {
|
||||
Pat::Expr(expr) => self.infer_mut_expr(expr, Mutability::Mut),
|
||||
Pat::ConstBlock(block) => self.infer_mut_expr(block, Mutability::Not),
|
||||
_ => {}
|
||||
@@ -220,8 +220,8 @@ fn pat_iter_bound_mutability(&self, mut pat: impl Iterator<Item = PatId>) -> Mut
|
||||
/// `let (ref x0, ref x1) = *it;` we should use `Deref`.
|
||||
fn pat_bound_mutability(&self, pat: PatId) -> Mutability {
|
||||
let mut r = Mutability::Not;
|
||||
self.body.walk_bindings_in_pat(pat, |b| {
|
||||
if self.body[b].mode == BindingAnnotation::RefMut {
|
||||
self.store.walk_bindings_in_pat(pat, |b| {
|
||||
if self.store[b].mode == BindingAnnotation::RefMut {
|
||||
r = Mutability::Mut;
|
||||
}
|
||||
});
|
||||
|
||||
@@ -3,9 +3,10 @@
|
||||
use std::{cmp, iter};
|
||||
|
||||
use hir_def::{
|
||||
HasModule,
|
||||
expr_store::{Body, path::Path},
|
||||
HasModule as _,
|
||||
expr_store::{ExpressionStore, path::Path},
|
||||
hir::{Binding, BindingAnnotation, BindingId, Expr, ExprId, Literal, Pat, PatId},
|
||||
signatures::VariantFields,
|
||||
};
|
||||
use hir_expand::name::Name;
|
||||
use rustc_ast_ir::Mutability;
|
||||
@@ -60,7 +61,7 @@ pub(super) fn infer_tuple_struct_pat_like(
|
||||
Some(def) => {
|
||||
let field_types = self.db.field_types(def);
|
||||
let variant_data = def.fields(self.db);
|
||||
let visibilities = self.db.field_visibilities(def);
|
||||
let visibilities = VariantFields::field_visibilities(self.db, def);
|
||||
|
||||
let (pre, post) = match ellipsis {
|
||||
Some(idx) => subs.split_at(idx as usize),
|
||||
@@ -129,7 +130,7 @@ pub(super) fn infer_record_pat_like(
|
||||
Some(def) => {
|
||||
let field_types = self.db.field_types(def);
|
||||
let variant_data = def.fields(self.db);
|
||||
let visibilities = self.db.field_visibilities(def);
|
||||
let visibilities = VariantFields::field_visibilities(self.db, def);
|
||||
|
||||
let substs = ty.as_adt().map(TupleExt::tail);
|
||||
|
||||
@@ -260,14 +261,14 @@ fn infer_pat(
|
||||
) -> Ty<'db> {
|
||||
let mut expected = self.table.structurally_resolve_type(expected);
|
||||
|
||||
if matches!(&self.body[pat], Pat::Ref { .. }) || self.inside_assignment {
|
||||
if matches!(&self.store[pat], Pat::Ref { .. }) || self.inside_assignment {
|
||||
cov_mark::hit!(match_ergonomics_ref);
|
||||
// When you encounter a `&pat` pattern, reset to Move.
|
||||
// This is so that `w` is by value: `let (_, &w) = &(1, &2);`
|
||||
// Destructuring assignments also reset the binding mode and
|
||||
// don't do match ergonomics.
|
||||
default_bm = BindingMode::Move;
|
||||
} else if self.is_non_ref_pat(self.body, pat) {
|
||||
} else if self.is_non_ref_pat(self.store, pat) {
|
||||
let mut pat_adjustments = Vec::new();
|
||||
while let TyKind::Ref(_lifetime, inner, mutability) = expected.kind() {
|
||||
pat_adjustments.push(expected.store());
|
||||
@@ -289,7 +290,7 @@ fn infer_pat(
|
||||
let default_bm = default_bm;
|
||||
let expected = expected;
|
||||
|
||||
let ty = match &self.body[pat] {
|
||||
let ty = match &self.store[pat] {
|
||||
Pat::Tuple { args, ellipsis } => {
|
||||
self.infer_tuple_pat_like(pat, expected, default_bm, *ellipsis, args, decl)
|
||||
}
|
||||
@@ -485,7 +486,7 @@ fn infer_bind_pat(
|
||||
expected: Ty<'db>,
|
||||
decl: Option<DeclContext>,
|
||||
) -> Ty<'db> {
|
||||
let Binding { mode, .. } = self.body[binding];
|
||||
let Binding { mode, .. } = self.store[binding];
|
||||
let mode = if mode == BindingAnnotation::Unannotated {
|
||||
default_bm
|
||||
} else {
|
||||
@@ -569,7 +570,7 @@ fn infer_slice_pat(
|
||||
|
||||
fn infer_lit_pat(&mut self, expr: ExprId, expected: Ty<'db>) -> Ty<'db> {
|
||||
// Like slice patterns, byte string patterns can denote both `&[u8; N]` and `&[u8]`.
|
||||
if let Expr::Literal(Literal::ByteString(_)) = self.body[expr]
|
||||
if let Expr::Literal(Literal::ByteString(_)) = self.store[expr]
|
||||
&& let TyKind::Ref(_, inner, _) = expected.kind()
|
||||
{
|
||||
let inner = self.table.try_structurally_resolve_type(inner);
|
||||
@@ -590,14 +591,14 @@ fn infer_lit_pat(&mut self, expr: ExprId, expected: Ty<'db>) -> Ty<'db> {
|
||||
self.infer_expr(expr, &Expectation::has_type(expected), ExprIsRead::Yes)
|
||||
}
|
||||
|
||||
fn is_non_ref_pat(&mut self, body: &hir_def::expr_store::Body, pat: PatId) -> bool {
|
||||
match &body[pat] {
|
||||
fn is_non_ref_pat(&mut self, store: &hir_def::expr_store::ExpressionStore, pat: PatId) -> bool {
|
||||
match &store[pat] {
|
||||
Pat::Tuple { .. }
|
||||
| Pat::TupleStruct { .. }
|
||||
| Pat::Record { .. }
|
||||
| Pat::Range { .. }
|
||||
| Pat::Slice { .. } => true,
|
||||
Pat::Or(pats) => pats.iter().all(|p| self.is_non_ref_pat(body, *p)),
|
||||
Pat::Or(pats) => pats.iter().all(|p| self.is_non_ref_pat(store, *p)),
|
||||
Pat::Path(path) => {
|
||||
// A const is a reference pattern, but other value ns things aren't (see #16131).
|
||||
let resolved = self.resolve_value_path_inner(path, pat.into(), true);
|
||||
@@ -605,7 +606,7 @@ fn is_non_ref_pat(&mut self, body: &hir_def::expr_store::Body, pat: PatId) -> bo
|
||||
}
|
||||
Pat::ConstBlock(..) => false,
|
||||
Pat::Lit(expr) => !matches!(
|
||||
body[*expr],
|
||||
store[*expr],
|
||||
Expr::Literal(Literal::String(..) | Literal::CString(..) | Literal::ByteString(..))
|
||||
),
|
||||
Pat::Wild
|
||||
@@ -670,10 +671,10 @@ fn pat_is_irrefutable(&self, decl_ctxt: Option<DeclContext>) -> bool {
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn contains_explicit_ref_binding(body: &Body, pat_id: PatId) -> bool {
|
||||
pub(super) fn contains_explicit_ref_binding(store: &ExpressionStore, pat_id: PatId) -> bool {
|
||||
let mut res = false;
|
||||
body.walk_pats(pat_id, &mut |pat| {
|
||||
res |= matches!(body[pat], Pat::Bind { id, .. } if matches!(body[id].mode, BindingAnnotation::Ref | BindingAnnotation::RefMut));
|
||||
store.walk_pats(pat_id, &mut |pat| {
|
||||
res |= matches!(store[pat], Pat::Bind { id, .. } if matches!(store[id].mode, BindingAnnotation::Ref | BindingAnnotation::RefMut));
|
||||
});
|
||||
res
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
AdtId, AssocItemId, GenericDefId, ItemContainerId, Lookup,
|
||||
expr_store::path::{Path, PathSegment},
|
||||
resolver::{ResolveValueResult, TypeNs, ValueNs},
|
||||
signatures::{ConstSignature, FunctionSignature},
|
||||
};
|
||||
use hir_expand::name::Name;
|
||||
use rustc_type_ir::inherent::{SliceLike, Ty as _};
|
||||
@@ -136,7 +137,7 @@ pub(super) fn resolve_value_path_inner(
|
||||
let mut ctx = TyLoweringContext::new(
|
||||
self.db,
|
||||
&self.resolver,
|
||||
self.body,
|
||||
self.store,
|
||||
&self.diagnostics,
|
||||
InferenceTyDiagnosticSource::Body,
|
||||
self.generic_def,
|
||||
@@ -159,7 +160,7 @@ pub(super) fn resolve_value_path_inner(
|
||||
let ty = self.table.process_user_written_ty(ty);
|
||||
self.resolve_ty_assoc_item(ty, last.name, id).map(|(it, substs)| (it, Some(substs)))?
|
||||
} else {
|
||||
let hygiene = self.body.expr_or_pat_path_hygiene(id);
|
||||
let hygiene = self.store.expr_or_pat_path_hygiene(id);
|
||||
// FIXME: report error, unresolved first path segment
|
||||
let value_or_partial = path_ctx.resolve_path_in_value_ns(hygiene)?;
|
||||
|
||||
@@ -263,7 +264,7 @@ fn resolve_trait_assoc_item(
|
||||
trait_.trait_items(self.db).items.iter().map(|(_name, id)| *id).find_map(|item| {
|
||||
match item {
|
||||
AssocItemId::FunctionId(func) => {
|
||||
if segment.name == &self.db.function_signature(func).name {
|
||||
if segment.name == &FunctionSignature::of(self.db, func).name {
|
||||
Some(CandidateId::FunctionId(func))
|
||||
} else {
|
||||
None
|
||||
@@ -271,7 +272,7 @@ fn resolve_trait_assoc_item(
|
||||
}
|
||||
|
||||
AssocItemId::ConstId(konst) => {
|
||||
if self.db.const_signature(konst).name.as_ref() == Some(segment.name) {
|
||||
if ConstSignature::of(self.db, konst).name.as_ref() == Some(segment.name) {
|
||||
Some(CandidateId::ConstId(konst))
|
||||
} else {
|
||||
None
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
use std::fmt;
|
||||
|
||||
use base_db::Crate;
|
||||
use hir_def::{AdtId, DefWithBodyId, GenericParamId};
|
||||
use hir_def::{AdtId, ExpressionStoreOwnerId, GenericParamId};
|
||||
use hir_expand::name::Name;
|
||||
use intern::sym;
|
||||
use rustc_hash::FxHashSet;
|
||||
@@ -147,7 +147,7 @@ pub(crate) fn new(
|
||||
db: &'db dyn HirDatabase,
|
||||
trait_env: ParamEnv<'db>,
|
||||
krate: Crate,
|
||||
owner: Option<DefWithBodyId>,
|
||||
owner: Option<ExpressionStoreOwnerId>,
|
||||
) -> Self {
|
||||
let interner = DbInterner::new_with(db, krate);
|
||||
let typing_mode = match owner {
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
//! Type inhabitedness logic.
|
||||
use std::ops::ControlFlow::{self, Break, Continue};
|
||||
|
||||
use hir_def::{AdtId, EnumVariantId, ModuleId, VariantId, visibility::Visibility};
|
||||
use hir_def::{
|
||||
AdtId, EnumVariantId, ModuleId, VariantId, signatures::VariantFields, visibility::Visibility,
|
||||
};
|
||||
use rustc_hash::FxHashSet;
|
||||
use rustc_type_ir::{
|
||||
TypeSuperVisitable, TypeVisitable, TypeVisitor,
|
||||
@@ -151,7 +153,11 @@ fn visit_variant(
|
||||
|
||||
let is_enum = matches!(variant, VariantId::EnumVariantId(..));
|
||||
let field_tys = self.db().field_types(variant);
|
||||
let field_vis = if is_enum { None } else { Some(self.db().field_visibilities(variant)) };
|
||||
let field_vis = if is_enum {
|
||||
None
|
||||
} else {
|
||||
Some(VariantFields::field_visibilities(self.db(), variant))
|
||||
};
|
||||
|
||||
for (fid, _) in fields.iter() {
|
||||
self.visit_field(field_vis.as_ref().map(|it| it[fid]), &field_tys[fid].get(), subst)?;
|
||||
|
||||
@@ -1,13 +1,17 @@
|
||||
//! Functions to detect special lang items
|
||||
|
||||
use hir_def::{AdtId, TraitId, lang_item::LangItems, signatures::StructFlags};
|
||||
use hir_def::{
|
||||
AdtId, TraitId,
|
||||
lang_item::LangItems,
|
||||
signatures::{StructFlags, StructSignature},
|
||||
};
|
||||
use intern::{Symbol, sym};
|
||||
|
||||
use crate::db::HirDatabase;
|
||||
|
||||
pub fn is_box(db: &dyn HirDatabase, adt: AdtId) -> bool {
|
||||
let AdtId::StructId(id) = adt else { return false };
|
||||
db.struct_signature(id).flags.contains(StructFlags::IS_BOX)
|
||||
StructSignature::of(db, id).flags.contains(StructFlags::IS_BOX)
|
||||
}
|
||||
|
||||
pub fn lang_items_for_bin_op(
|
||||
|
||||
@@ -333,7 +333,7 @@ pub fn layout_of_ty_query(
|
||||
}
|
||||
TyKind::Closure(id, args) => {
|
||||
let def = db.lookup_intern_closure(id.0);
|
||||
let infer = InferenceResult::for_body(db, def.0);
|
||||
let infer = InferenceResult::of(db, def.0);
|
||||
let (captures, _) = infer.closure_info(id.0);
|
||||
let fields = captures
|
||||
.iter()
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
use hir_def::{
|
||||
AdtId, VariantId,
|
||||
attrs::AttrFlags,
|
||||
signatures::{StructFlags, VariantFields},
|
||||
signatures::{StructFlags, StructSignature, VariantFields},
|
||||
};
|
||||
use rustc_abi::{Integer, ReprOptions, TargetDataLayout};
|
||||
use rustc_index::IndexVec;
|
||||
@@ -41,7 +41,7 @@ pub fn layout_of_adt_query(
|
||||
};
|
||||
let (variants, repr, is_special_no_niche) = match def {
|
||||
AdtId::StructId(s) => {
|
||||
let sig = db.struct_signature(s);
|
||||
let sig = StructSignature::of(db, s);
|
||||
let mut r = SmallVec::<[_; 1]>::new();
|
||||
r.push(handle_variant(s.into(), s.fields(db))?);
|
||||
(
|
||||
|
||||
@@ -1,6 +1,12 @@
|
||||
use base_db::target::TargetData;
|
||||
use either::Either;
|
||||
use hir_def::{HasModule, db::DefDatabase};
|
||||
use hir_def::{
|
||||
DefWithBodyId, ExpressionStoreOwnerId, GenericDefId, HasModule,
|
||||
expr_store::Body,
|
||||
signatures::{
|
||||
EnumSignature, FunctionSignature, StructSignature, TypeAliasSignature, UnionSignature,
|
||||
},
|
||||
};
|
||||
use project_model::{Sysroot, toolchain_info::QueryConfig};
|
||||
use rustc_hash::FxHashMap;
|
||||
use rustc_type_ir::inherent::GenericArgs as _;
|
||||
@@ -49,18 +55,15 @@ fn eval_goal(
|
||||
let adt_or_type_alias_id = scope.declarations().find_map(|x| match x {
|
||||
hir_def::ModuleDefId::AdtId(x) => {
|
||||
let name = match x {
|
||||
hir_def::AdtId::StructId(x) => db
|
||||
.struct_signature(x)
|
||||
hir_def::AdtId::StructId(x) => StructSignature::of(&db, x)
|
||||
.name
|
||||
.display_no_db(file_id.edition(&db))
|
||||
.to_smolstr(),
|
||||
hir_def::AdtId::UnionId(x) => db
|
||||
.union_signature(x)
|
||||
hir_def::AdtId::UnionId(x) => UnionSignature::of(&db, x)
|
||||
.name
|
||||
.display_no_db(file_id.edition(&db))
|
||||
.to_smolstr(),
|
||||
hir_def::AdtId::EnumId(x) => db
|
||||
.enum_signature(x)
|
||||
hir_def::AdtId::EnumId(x) => EnumSignature::of(&db, x)
|
||||
.name
|
||||
.display_no_db(file_id.edition(&db))
|
||||
.to_smolstr(),
|
||||
@@ -68,8 +71,7 @@ fn eval_goal(
|
||||
(name == "Goal").then_some(Either::Left(x))
|
||||
}
|
||||
hir_def::ModuleDefId::TypeAliasId(x) => {
|
||||
let name = db
|
||||
.type_alias_signature(x)
|
||||
let name = TypeAliasSignature::of(&db, x)
|
||||
.name
|
||||
.display_no_db(file_id.edition(&db))
|
||||
.to_smolstr();
|
||||
@@ -90,10 +92,13 @@ fn eval_goal(
|
||||
),
|
||||
Either::Right(ty_id) => db.ty(ty_id.into()).instantiate_identity(),
|
||||
};
|
||||
let param_env = db.trait_environment(match adt_or_type_alias_id {
|
||||
Either::Left(adt) => hir_def::GenericDefId::AdtId(adt),
|
||||
Either::Right(ty) => hir_def::GenericDefId::TypeAliasId(ty),
|
||||
});
|
||||
let param_env = db.trait_environment(
|
||||
match adt_or_type_alias_id {
|
||||
Either::Left(adt) => hir_def::GenericDefId::AdtId(adt),
|
||||
Either::Right(ty) => hir_def::GenericDefId::TypeAliasId(ty),
|
||||
}
|
||||
.into(),
|
||||
);
|
||||
let krate = match adt_or_type_alias_id {
|
||||
Either::Left(it) => it.krate(&db),
|
||||
Either::Right(it) => it.krate(&db),
|
||||
@@ -123,8 +128,7 @@ fn eval_expr(
|
||||
.declarations()
|
||||
.find_map(|x| match x {
|
||||
hir_def::ModuleDefId::FunctionId(x) => {
|
||||
let name = db
|
||||
.function_signature(x)
|
||||
let name = FunctionSignature::of(&db, x)
|
||||
.name
|
||||
.display_no_db(file_id.edition(&db))
|
||||
.to_smolstr();
|
||||
@@ -133,15 +137,16 @@ fn eval_expr(
|
||||
_ => None,
|
||||
})
|
||||
.unwrap();
|
||||
let hir_body = db.body(function_id.into());
|
||||
let hir_body = Body::of(&db, function_id.into());
|
||||
let b = hir_body
|
||||
.bindings()
|
||||
.find(|x| x.1.name.display_no_db(file_id.edition(&db)).to_smolstr() == "goal")
|
||||
.unwrap()
|
||||
.0;
|
||||
let infer = InferenceResult::for_body(&db, function_id.into());
|
||||
let infer = InferenceResult::of(&db, DefWithBodyId::from(function_id));
|
||||
let goal_ty = infer.type_of_binding[b].clone();
|
||||
let param_env = db.trait_environment(function_id.into());
|
||||
let param_env =
|
||||
db.trait_environment(ExpressionStoreOwnerId::from(GenericDefId::from(function_id)));
|
||||
let krate = function_id.krate(&db);
|
||||
db.layout_of_ty(goal_ty, ParamEnvAndCrate { param_env, krate }.store())
|
||||
})
|
||||
@@ -379,6 +384,11 @@ impl Tr for S {
|
||||
|
||||
#[test]
|
||||
fn simd_types() {
|
||||
let size = 16;
|
||||
#[cfg(not(target_arch = "s390x"))]
|
||||
let align = 16;
|
||||
#[cfg(target_arch = "s390x")]
|
||||
let align = 8;
|
||||
check_size_and_align(
|
||||
r#"
|
||||
#[repr(simd)]
|
||||
@@ -386,8 +396,8 @@ fn simd_types() {
|
||||
struct Goal(SimdType);
|
||||
"#,
|
||||
"",
|
||||
16,
|
||||
16,
|
||||
size,
|
||||
align,
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -61,8 +61,8 @@
|
||||
use std::{hash::Hash, ops::ControlFlow};
|
||||
|
||||
use hir_def::{
|
||||
CallableDefId, GenericDefId, TypeAliasId, TypeOrConstParamId, TypeParamId,
|
||||
hir::generics::GenericParams, resolver::TypeNs, type_ref::Rawness,
|
||||
CallableDefId, ExpressionStoreOwnerId, GenericDefId, TypeAliasId, TypeOrConstParamId,
|
||||
TypeParamId, hir::generics::GenericParams, resolver::TypeNs, type_ref::Rawness,
|
||||
};
|
||||
use hir_expand::name::Name;
|
||||
use indexmap::{IndexMap, map::Entry};
|
||||
@@ -507,7 +507,7 @@ pub fn associated_type_shorthand_candidates(
|
||||
let mut dedup_map = FxHashSet::default();
|
||||
let param_ty = Ty::new_param(interner, param, param_idx(db, param.into()).unwrap() as u32);
|
||||
// We use the ParamEnv and not the predicates because the ParamEnv elaborates bounds.
|
||||
let param_env = db.trait_environment(def);
|
||||
let param_env = db.trait_environment(ExpressionStoreOwnerId::from(def));
|
||||
for clause in param_env.clauses {
|
||||
let ClauseKind::Trait(trait_clause) = clause.kind().skip_binder() else { continue };
|
||||
if trait_clause.self_ty() != param_ty {
|
||||
|
||||
@@ -13,10 +13,10 @@
|
||||
use arrayvec::ArrayVec;
|
||||
use either::Either;
|
||||
use hir_def::{
|
||||
AdtId, AssocItemId, CallableDefId, ConstId, ConstParamId, DefWithBodyId, EnumId, EnumVariantId,
|
||||
FunctionId, GeneralConstId, GenericDefId, GenericParamId, HasModule, ImplId, ItemContainerId,
|
||||
LifetimeParamId, LocalFieldId, Lookup, StaticId, StructId, TraitId, TypeAliasId,
|
||||
TypeOrConstParamId, TypeParamId, UnionId, VariantId,
|
||||
AdtId, AssocItemId, CallableDefId, ConstId, ConstParamId, EnumId, EnumVariantId,
|
||||
ExpressionStoreOwnerId, FunctionId, GeneralConstId, GenericDefId, GenericParamId, HasModule,
|
||||
ImplId, ItemContainerId, LifetimeParamId, LocalFieldId, Lookup, StaticId, StructId, TraitId,
|
||||
TypeAliasId, TypeOrConstParamId, TypeParamId, UnionId, VariantId,
|
||||
builtin_type::BuiltinType,
|
||||
expr_store::{ExpressionStore, HygieneId, path::Path},
|
||||
hir::generics::{
|
||||
@@ -26,7 +26,10 @@
|
||||
item_tree::FieldsShape,
|
||||
lang_item::LangItems,
|
||||
resolver::{HasResolver, LifetimeNs, Resolver, TypeNs, ValueNs},
|
||||
signatures::{FunctionSignature, TraitFlags, TypeAliasFlags},
|
||||
signatures::{
|
||||
ConstSignature, FunctionSignature, ImplSignature, StaticSignature, StructSignature,
|
||||
TraitFlags, TraitSignature, TypeAliasFlags, TypeAliasSignature,
|
||||
},
|
||||
type_ref::{
|
||||
ConstRef, FnType, LifetimeRefId, PathId, TraitBoundModifier, TraitRef as HirTraitRef,
|
||||
TypeBound, TypeRef, TypeRefId,
|
||||
@@ -178,7 +181,7 @@ pub struct TyLoweringContext<'db, 'a> {
|
||||
resolver: &'a Resolver<'db>,
|
||||
store: &'a ExpressionStore,
|
||||
def: GenericDefId,
|
||||
generics: OnceCell<Generics>,
|
||||
generics: OnceCell<Generics<'db>>,
|
||||
in_binders: DebruijnIndex,
|
||||
impl_trait_mode: ImplTraitLoweringState,
|
||||
/// Tracks types with explicit `?Sized` bounds.
|
||||
@@ -279,11 +282,12 @@ pub fn lower_ty(&mut self, type_ref: TypeRefId) -> Ty<'db> {
|
||||
}
|
||||
|
||||
pub(crate) fn lower_const(&mut self, const_ref: ConstRef, const_type: Ty<'db>) -> Const<'db> {
|
||||
let const_ref = &self.store[const_ref.expr];
|
||||
match const_ref {
|
||||
hir_def::hir::Expr::Path(path) => {
|
||||
self.path_to_const(path).unwrap_or_else(|| unknown_const(const_type))
|
||||
}
|
||||
let expr_id = const_ref.expr;
|
||||
let expr = &self.store[expr_id];
|
||||
match expr {
|
||||
hir_def::hir::Expr::Path(path) => self
|
||||
.path_to_const(path)
|
||||
.unwrap_or_else(|| Const::new(self.interner, ConstKind::Error(ErrorGuaranteed))),
|
||||
hir_def::hir::Expr::Literal(literal) => {
|
||||
intern_const_ref(self.db, literal, const_type, self.resolver.krate())
|
||||
}
|
||||
@@ -300,20 +304,74 @@ pub(crate) fn lower_const(&mut self, const_ref: ConstRef, const_type: Ty<'db>) -
|
||||
self.resolver.krate(),
|
||||
)
|
||||
} else {
|
||||
unknown_const(const_type)
|
||||
Const::new(self.interner, ConstKind::Error(ErrorGuaranteed))
|
||||
}
|
||||
}
|
||||
// For unsigned integers, chars, bools, etc., negation is not meaningful
|
||||
_ => unknown_const(const_type),
|
||||
_ => Const::new(self.interner, ConstKind::Error(ErrorGuaranteed)),
|
||||
}
|
||||
} else {
|
||||
unknown_const(const_type)
|
||||
// Complex negation expression (e.g. `-N` where N is a const param)
|
||||
self.lower_const_as_unevaluated(expr_id, const_type)
|
||||
}
|
||||
}
|
||||
_ => unknown_const(const_type),
|
||||
hir_def::hir::Expr::Underscore => {
|
||||
Const::new(self.interner, ConstKind::Error(ErrorGuaranteed))
|
||||
}
|
||||
// Any other complex expression becomes an unevaluated anonymous const.
|
||||
_ => self.lower_const_as_unevaluated(expr_id, const_type),
|
||||
}
|
||||
}
|
||||
|
||||
/// Lower a complex const expression to an `UnevaluatedConst` backed by an `AnonConstId`.
|
||||
///
|
||||
/// The `expected_ty_ref` is `None` for array lengths (implicitly `usize`) or
|
||||
/// `Some(type_ref_id)` for const generic arguments where the expected type comes
|
||||
/// from the const parameter declaration.
|
||||
fn lower_const_as_unevaluated(
|
||||
&mut self,
|
||||
_expr: hir_def::hir::ExprId,
|
||||
_expected_ty: Ty<'db>,
|
||||
) -> Const<'db> {
|
||||
// /// Build the identity generic args for the current generic context.
|
||||
// ///
|
||||
// /// This maps each generic parameter to itself (as a `ParamTy`, `ParamConst`,
|
||||
// /// or `EarlyParamRegion`), which is the correct substitution when creating
|
||||
// /// an `UnevaluatedConst` during type lowering — the anon const inherits the
|
||||
// /// parent's generics and they haven't been substituted yet.
|
||||
// fn current_generic_args(&self) -> GenericArgs<'db> {
|
||||
// let generics = self.generics();
|
||||
// let interner = self.interner;
|
||||
// GenericArgs::new_from_iter(
|
||||
// interner,
|
||||
// generics.iter_id().enumerate().map(|(index, id)| match id {
|
||||
// GenericParamId::TypeParamId(id) => {
|
||||
// GenericArg::from(Ty::new_param(interner, id, index as u32))
|
||||
// }
|
||||
// GenericParamId::ConstParamId(id) => GenericArg::from(Const::new_param(
|
||||
// interner,
|
||||
// ParamConst { id, index: index as u32 },
|
||||
// )),
|
||||
// GenericParamId::LifetimeParamId(id) => GenericArg::from(Region::new_early_param(
|
||||
// interner,
|
||||
// EarlyParamRegion { id, index: index as u32 },
|
||||
// )),
|
||||
// }),
|
||||
// )
|
||||
// }
|
||||
// let loc = AnonConstLoc { owner: self.def, expr };
|
||||
// let id = loc.intern(self.db);
|
||||
// let args = self.current_generic_args();
|
||||
// Const::new(
|
||||
// self.interner,
|
||||
// ConstKind::Unevaluated(UnevaluatedConst::new(
|
||||
// GeneralConstId::AnonConstId(id).into(),
|
||||
// args,
|
||||
// )),
|
||||
// )
|
||||
Const::new(self.interner, ConstKind::Error(ErrorGuaranteed))
|
||||
}
|
||||
|
||||
pub(crate) fn path_to_const(&mut self, path: &Path) -> Option<Const<'db>> {
|
||||
match self.resolver.resolve_path_in_value_ns_fully(self.db, path, HygieneId::ROOT) {
|
||||
Some(ValueNs::GenericParam(p)) => {
|
||||
@@ -349,7 +407,7 @@ pub(crate) fn lower_path_as_const(&mut self, path: &Path, const_type: Ty<'db>) -
|
||||
self.path_to_const(path).unwrap_or_else(|| unknown_const(const_type))
|
||||
}
|
||||
|
||||
fn generics(&self) -> &Generics {
|
||||
fn generics(&self) -> &Generics<'db> {
|
||||
self.generics.get_or_init(|| generics(self.db, self.def))
|
||||
}
|
||||
|
||||
@@ -727,7 +785,8 @@ fn lower_dyn_trait(&mut self, bounds: &[TypeBound]) -> Ty<'db> {
|
||||
match b.kind().skip_binder() {
|
||||
rustc_type_ir::ClauseKind::Trait(t) => {
|
||||
let id = t.def_id();
|
||||
let is_auto = db.trait_signature(id.0).flags.contains(TraitFlags::AUTO);
|
||||
let is_auto =
|
||||
TraitSignature::of(db, id.0).flags.contains(TraitFlags::AUTO);
|
||||
if is_auto {
|
||||
auto_traits.push(t.def_id().0);
|
||||
} else {
|
||||
@@ -1111,7 +1170,7 @@ pub(crate) fn impl_trait_with_diagnostics_query<'db>(
|
||||
db: &'db dyn HirDatabase,
|
||||
impl_id: ImplId,
|
||||
) -> Option<(StoredEarlyBinder<(TraitId, StoredGenericArgs)>, Diagnostics)> {
|
||||
let impl_data = db.impl_signature(impl_id);
|
||||
let impl_data = ImplSignature::of(db, impl_id);
|
||||
let resolver = impl_id.resolver(db);
|
||||
let mut ctx = TyLoweringContext::new(
|
||||
db,
|
||||
@@ -1196,7 +1255,7 @@ pub(crate) fn return_type_impl_traits(
|
||||
def: hir_def::FunctionId,
|
||||
) -> Option<Box<StoredEarlyBinder<ImplTraits>>> {
|
||||
// FIXME unify with fn_sig_for_fn instead of doing lowering twice, maybe
|
||||
let data = db.function_signature(def);
|
||||
let data = FunctionSignature::of(db, def);
|
||||
let resolver = def.resolver(db);
|
||||
let mut ctx_ret = TyLoweringContext::new(
|
||||
db,
|
||||
@@ -1224,7 +1283,7 @@ pub(crate) fn type_alias_impl_traits(
|
||||
db: &dyn HirDatabase,
|
||||
def: hir_def::TypeAliasId,
|
||||
) -> Option<Box<StoredEarlyBinder<ImplTraits>>> {
|
||||
let data = db.type_alias_signature(def);
|
||||
let data = TypeAliasSignature::of(db, def);
|
||||
let resolver = def.resolver(db);
|
||||
let mut ctx = TyLoweringContext::new(
|
||||
db,
|
||||
@@ -1314,7 +1373,7 @@ fn type_for_fn(db: &dyn HirDatabase, def: FunctionId) -> StoredEarlyBinder<Store
|
||||
/// Build the declared type of a const.
|
||||
fn type_for_const(db: &dyn HirDatabase, def: ConstId) -> StoredEarlyBinder<StoredTy> {
|
||||
let resolver = def.resolver(db);
|
||||
let data = db.const_signature(def);
|
||||
let data = ConstSignature::of(db, def);
|
||||
let parent = def.loc(db).container;
|
||||
let mut ctx = TyLoweringContext::new(
|
||||
db,
|
||||
@@ -1330,7 +1389,7 @@ fn type_for_const(db: &dyn HirDatabase, def: ConstId) -> StoredEarlyBinder<Store
|
||||
/// Build the declared type of a static.
|
||||
fn type_for_static(db: &dyn HirDatabase, def: StaticId) -> StoredEarlyBinder<StoredTy> {
|
||||
let resolver = def.resolver(db);
|
||||
let data = db.static_signature(def);
|
||||
let data = StaticSignature::of(db, def);
|
||||
let mut ctx = TyLoweringContext::new(
|
||||
db,
|
||||
&resolver,
|
||||
@@ -1347,7 +1406,7 @@ fn type_for_struct_constructor(
|
||||
db: &dyn HirDatabase,
|
||||
def: StructId,
|
||||
) -> Option<StoredEarlyBinder<StoredTy>> {
|
||||
let struct_data = db.struct_signature(def);
|
||||
let struct_data = StructSignature::of(db, def);
|
||||
match struct_data.shape {
|
||||
FieldsShape::Record => None,
|
||||
FieldsShape::Unit => Some(type_for_adt(db, def.into())),
|
||||
@@ -1422,7 +1481,7 @@ pub(crate) fn type_for_type_alias_with_diagnostics_query<'db>(
|
||||
db: &'db dyn HirDatabase,
|
||||
t: TypeAliasId,
|
||||
) -> (StoredEarlyBinder<StoredTy>, Diagnostics) {
|
||||
let type_alias_data = db.type_alias_signature(t);
|
||||
let type_alias_data = TypeAliasSignature::of(db, t);
|
||||
let mut diags = None;
|
||||
let resolver = t.resolver(db);
|
||||
let interner = DbInterner::new_no_crate(db);
|
||||
@@ -1485,7 +1544,7 @@ pub(crate) fn impl_self_ty_with_diagnostics_query<'db>(
|
||||
) -> (StoredEarlyBinder<StoredTy>, Diagnostics) {
|
||||
let resolver = impl_id.resolver(db);
|
||||
|
||||
let impl_data = db.impl_signature(impl_id);
|
||||
let impl_data = ImplSignature::of(db, impl_id);
|
||||
let mut ctx = TyLoweringContext::new(
|
||||
db,
|
||||
&resolver,
|
||||
@@ -1531,14 +1590,14 @@ pub(crate) fn const_param_ty_with_diagnostics_query<'db>(
|
||||
_: (),
|
||||
def: ConstParamId,
|
||||
) -> (StoredTy, Diagnostics) {
|
||||
let (parent_data, store) = db.generic_params_and_store(def.parent());
|
||||
let (parent_data, store) = GenericParams::with_store(db, def.parent());
|
||||
let data = &parent_data[def.local_id()];
|
||||
let resolver = def.parent().resolver(db);
|
||||
let interner = DbInterner::new_no_crate(db);
|
||||
let mut ctx = TyLoweringContext::new(
|
||||
db,
|
||||
&resolver,
|
||||
&store,
|
||||
store,
|
||||
def.parent(),
|
||||
LifetimeElisionKind::AnonymousReportError,
|
||||
);
|
||||
@@ -1629,7 +1688,7 @@ fn supertraits_info(db: &dyn HirDatabase, trait_: TraitId) -> SupertraitsInfo {
|
||||
));
|
||||
|
||||
let resolver = trait_.resolver(db);
|
||||
let signature = db.trait_signature(trait_);
|
||||
let signature = TraitSignature::of(db, trait_);
|
||||
for pred in signature.generic_params.where_predicates() {
|
||||
let (WherePredicate::TypeBound { target, bound }
|
||||
| WherePredicate::ForLifetime { lifetimes: _, target, bound }) = pred
|
||||
@@ -1900,7 +1959,7 @@ pub fn type_alias_bounds_with_diagnostics_query<'db>(
|
||||
db: &'db dyn HirDatabase,
|
||||
type_alias: TypeAliasId,
|
||||
) -> (TypeAliasBounds<StoredEarlyBinder<StoredClauses>>, Diagnostics) {
|
||||
let type_alias_data = db.type_alias_signature(type_alias);
|
||||
let type_alias_data = TypeAliasSignature::of(db, type_alias);
|
||||
let resolver = hir_def::resolver::HasResolver::resolver(type_alias, db);
|
||||
let mut ctx = TyLoweringContext::new(
|
||||
db,
|
||||
@@ -2079,16 +2138,6 @@ pub fn explicit_implied_predicates(&self) -> EarlyBinder<'_, &[Clause<'_>]> {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn trait_environment_for_body_query(
|
||||
db: &dyn HirDatabase,
|
||||
def: DefWithBodyId,
|
||||
) -> ParamEnv<'_> {
|
||||
let Some(def) = def.as_generic_def_id(db) else {
|
||||
return ParamEnv::empty();
|
||||
};
|
||||
db.trait_environment(def)
|
||||
}
|
||||
|
||||
pub(crate) fn param_env_from_predicates<'db>(
|
||||
interner: DbInterner<'db>,
|
||||
predicates: &'db GenericPredicates,
|
||||
@@ -2103,7 +2152,12 @@ pub(crate) fn param_env_from_predicates<'db>(
|
||||
ParamEnv { clauses }
|
||||
}
|
||||
|
||||
pub(crate) fn trait_environment<'db>(db: &'db dyn HirDatabase, def: GenericDefId) -> ParamEnv<'db> {
|
||||
pub(crate) fn trait_environment<'db>(
|
||||
db: &'db dyn HirDatabase,
|
||||
def: ExpressionStoreOwnerId,
|
||||
) -> ParamEnv<'db> {
|
||||
let def = def.generic_def(db);
|
||||
|
||||
return ParamEnv { clauses: trait_environment_query(db, def).as_ref() };
|
||||
|
||||
#[salsa::tracked(returns(ref))]
|
||||
@@ -2303,7 +2357,7 @@ fn implicit_trait_predicate<'db>(
|
||||
fn push_const_arg_has_type_predicates<'db>(
|
||||
db: &'db dyn HirDatabase,
|
||||
predicates: &mut Vec<Clause<'db>>,
|
||||
generics: &Generics,
|
||||
generics: &Generics<'db>,
|
||||
) {
|
||||
let interner = DbInterner::new_no_crate(db);
|
||||
let const_params_offset = generics.len_parent() + generics.len_lifetimes_self();
|
||||
@@ -2356,10 +2410,11 @@ pub(crate) fn generic_defaults_with_diagnostics_query(
|
||||
}
|
||||
let resolver = def.resolver(db);
|
||||
|
||||
let store_for_self = generic_params.store();
|
||||
let mut ctx = TyLoweringContext::new(
|
||||
db,
|
||||
&resolver,
|
||||
generic_params.store(),
|
||||
store_for_self,
|
||||
def,
|
||||
LifetimeElisionKind::AnonymousReportError,
|
||||
)
|
||||
@@ -2377,6 +2432,7 @@ pub(crate) fn generic_defaults_with_diagnostics_query(
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
ctx.diagnostics.clear(); // Don't include diagnostics from the parent.
|
||||
ctx.store = store_for_self;
|
||||
defaults.extend(generic_params.iter_self().map(|(_id, p)| {
|
||||
let (result, has_default) = handle_generic_param(&mut ctx, idx, p);
|
||||
has_any_default |= has_default;
|
||||
@@ -2447,7 +2503,7 @@ pub(crate) fn callable_item_signature_query<'db>(
|
||||
}
|
||||
|
||||
fn fn_sig_for_fn(db: &dyn HirDatabase, def: FunctionId) -> StoredEarlyBinder<StoredPolyFnSig> {
|
||||
let data = db.function_signature(def);
|
||||
let data = FunctionSignature::of(db, def);
|
||||
let resolver = def.resolver(db);
|
||||
let interner = DbInterner::new_no_crate(db);
|
||||
let mut ctx_params = TyLoweringContext::new(
|
||||
@@ -2455,7 +2511,7 @@ fn fn_sig_for_fn(db: &dyn HirDatabase, def: FunctionId) -> StoredEarlyBinder<Sto
|
||||
&resolver,
|
||||
&data.store,
|
||||
def.into(),
|
||||
LifetimeElisionKind::for_fn_params(&data),
|
||||
LifetimeElisionKind::for_fn_params(data),
|
||||
);
|
||||
let params = data.params.iter().map(|&tr| ctx_params.lower_ty(tr));
|
||||
|
||||
@@ -2533,7 +2589,7 @@ pub(crate) fn associated_ty_item_bounds<'db>(
|
||||
db: &'db dyn HirDatabase,
|
||||
type_alias: TypeAliasId,
|
||||
) -> EarlyBinder<'db, BoundExistentialPredicates<'db>> {
|
||||
let type_alias_data = db.type_alias_signature(type_alias);
|
||||
let type_alias_data = TypeAliasSignature::of(db, type_alias);
|
||||
let resolver = hir_def::resolver::HasResolver::resolver(type_alias, db);
|
||||
let interner = DbInterner::new_no_crate(db);
|
||||
let mut ctx = TyLoweringContext::new(
|
||||
@@ -2555,7 +2611,7 @@ pub(crate) fn associated_ty_item_bounds<'db>(
|
||||
.map_bound(|c| match c {
|
||||
rustc_type_ir::ClauseKind::Trait(t) => {
|
||||
let id = t.def_id();
|
||||
let is_auto = db.trait_signature(id.0).flags.contains(TraitFlags::AUTO);
|
||||
let is_auto = TraitSignature::of(db, id.0).flags.contains(TraitFlags::AUTO);
|
||||
if is_auto {
|
||||
Some(ExistentialPredicate::AutoTrait(t.def_id()))
|
||||
} else {
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
GenericParamDataRef, TypeOrConstParamData, TypeParamData, TypeParamProvenance,
|
||||
},
|
||||
resolver::{ResolveValueResult, TypeNs, ValueNs},
|
||||
signatures::TraitFlags,
|
||||
signatures::{TraitFlags, TraitSignature},
|
||||
type_ref::{TypeRef, TypeRefId},
|
||||
};
|
||||
use rustc_type_ir::{
|
||||
@@ -625,10 +625,7 @@ pub(crate) fn substs_from_path_segment(
|
||||
GenericDefId::TraitId(trait_) => {
|
||||
// RTN is prohibited anyways if we got here.
|
||||
let is_rtn = args.parenthesized == GenericArgsParentheses::ReturnTypeNotation;
|
||||
let is_fn_trait = self
|
||||
.ctx
|
||||
.db
|
||||
.trait_signature(trait_)
|
||||
let is_fn_trait = TraitSignature::of(self.ctx.db, trait_)
|
||||
.flags
|
||||
.contains(TraitFlags::RUSTC_PAREN_SUGAR);
|
||||
is_rtn || !is_fn_trait
|
||||
@@ -1024,7 +1021,7 @@ fn inferred_kind(
|
||||
fn check_generic_args_len<'db>(
|
||||
args_and_bindings: Option<&HirGenericArgs>,
|
||||
def: GenericDefId,
|
||||
def_generics: &Generics,
|
||||
def_generics: &Generics<'db>,
|
||||
infer_args: bool,
|
||||
lifetime_elision: &LifetimeElisionKind<'db>,
|
||||
lowering_assoc_type_generics: bool,
|
||||
|
||||
@@ -17,11 +17,12 @@
|
||||
ImplId, ItemContainerId, ModuleId, TraitId,
|
||||
attrs::AttrFlags,
|
||||
builtin_derive::BuiltinDeriveImplMethod,
|
||||
expr_store::path::GenericArgs as HirGenericArgs,
|
||||
hir::ExprId,
|
||||
expr_store::{Body, path::GenericArgs as HirGenericArgs},
|
||||
hir::{ExprId, generics::GenericParams},
|
||||
lang_item::LangItems,
|
||||
nameres::{DefMap, block_def_map, crate_def_map},
|
||||
resolver::Resolver,
|
||||
signatures::{ConstSignature, FunctionSignature},
|
||||
};
|
||||
use intern::{Symbol, sym};
|
||||
use rustc_hash::{FxHashMap, FxHashSet};
|
||||
@@ -366,7 +367,7 @@ pub fn lookup_impl_const<'db>(
|
||||
};
|
||||
let trait_ref = TraitRef::new_from_args(interner, trait_id.into(), subs);
|
||||
|
||||
let const_signature = db.const_signature(const_id);
|
||||
let const_signature = ConstSignature::of(db, const_id);
|
||||
let name = match const_signature.name.as_ref() {
|
||||
Some(name) => name,
|
||||
None => return (const_id, subs),
|
||||
@@ -396,7 +397,7 @@ pub fn is_dyn_method<'db>(
|
||||
let ItemContainerId::TraitId(trait_id) = func.loc(db).container else {
|
||||
return None;
|
||||
};
|
||||
let trait_params = db.generic_params(trait_id.into()).len();
|
||||
let trait_params = GenericParams::of(db, trait_id.into()).len();
|
||||
let fn_params = fn_subst.len() - trait_params;
|
||||
let trait_ref = TraitRef::new_from_args(
|
||||
interner,
|
||||
@@ -432,14 +433,14 @@ pub(crate) fn lookup_impl_method_query<'db>(
|
||||
let ItemContainerId::TraitId(trait_id) = func.loc(db).container else {
|
||||
return (Either::Left(func), fn_subst);
|
||||
};
|
||||
let trait_params = db.generic_params(trait_id.into()).len();
|
||||
let trait_params = GenericParams::of(db, trait_id.into()).len();
|
||||
let trait_ref = TraitRef::new_from_args(
|
||||
interner,
|
||||
trait_id.into(),
|
||||
GenericArgs::new_from_slice(&fn_subst[..trait_params]),
|
||||
);
|
||||
|
||||
let name = &db.function_signature(func).name;
|
||||
let name = &FunctionSignature::of(db, func).name;
|
||||
let Some((impl_fn, impl_subst)) =
|
||||
lookup_impl_assoc_item_for_trait_ref(&infcx, trait_ref, env.param_env, name).and_then(
|
||||
|(assoc, impl_args)| {
|
||||
@@ -623,7 +624,7 @@ fn collect(
|
||||
// To better support custom derives, collect impls in all unnamed const items.
|
||||
// const _: () = { ... };
|
||||
for konst in module_data.scope.unnamed_consts() {
|
||||
let body = db.body(konst.into());
|
||||
let body = Body::of(db, konst.into());
|
||||
for (_, block_def_map) in body.blocks(db) {
|
||||
collect(db, block_def_map, map);
|
||||
}
|
||||
@@ -766,7 +767,7 @@ fn collect(
|
||||
// To better support custom derives, collect impls in all unnamed const items.
|
||||
// const _: () = { ... };
|
||||
for konst in module_data.scope.unnamed_consts() {
|
||||
let body = db.body(konst.into());
|
||||
let body = Body::of(db, konst.into());
|
||||
for (_, block_def_map) in body.blocks(db) {
|
||||
collect(db, block_def_map, lang_items, map);
|
||||
}
|
||||
|
||||
@@ -456,7 +456,7 @@ fn report_missing_lifetime(&mut self, _def: GenericDefId, _expected_count: u32)
|
||||
|
||||
substs_from_args_and_bindings(
|
||||
self.db(),
|
||||
self.ctx.body,
|
||||
self.ctx.store,
|
||||
generic_args,
|
||||
self.candidate.into(),
|
||||
true,
|
||||
|
||||
@@ -5,7 +5,8 @@
|
||||
|
||||
use hir_def::{
|
||||
AssocItemId, FunctionId, GenericParamId, ImplId, ItemContainerId, TraitId,
|
||||
signatures::TraitFlags,
|
||||
hir::generics::GenericParams,
|
||||
signatures::{FunctionSignature, TraitFlags, TraitSignature},
|
||||
};
|
||||
use hir_expand::name::Name;
|
||||
use rustc_ast_ir::Mutability;
|
||||
@@ -1605,7 +1606,8 @@ fn consider_probe(
|
||||
// Some trait methods are excluded for arrays before 2021.
|
||||
// (`array.into_iter()` wants a slice iterator for compatibility.)
|
||||
if self_ty.is_array() && !self.ctx.edition.at_least_2021() {
|
||||
let trait_signature = self.db().trait_signature(poly_trait_ref.def_id().0);
|
||||
let trait_signature =
|
||||
TraitSignature::of(self.db(), poly_trait_ref.def_id().0);
|
||||
if trait_signature
|
||||
.flags
|
||||
.contains(TraitFlags::SKIP_ARRAY_DURING_METHOD_DISPATCH)
|
||||
@@ -1619,7 +1621,8 @@ fn consider_probe(
|
||||
if self_ty.boxed_ty().is_some_and(Ty::is_slice)
|
||||
&& !self.ctx.edition.at_least_2024()
|
||||
{
|
||||
let trait_signature = self.db().trait_signature(poly_trait_ref.def_id().0);
|
||||
let trait_signature =
|
||||
TraitSignature::of(self.db(), poly_trait_ref.def_id().0);
|
||||
if trait_signature
|
||||
.flags
|
||||
.contains(TraitFlags::SKIP_BOXED_SLICE_DURING_METHOD_DISPATCH)
|
||||
@@ -1963,7 +1966,7 @@ fn has_applicable_self(&self, item: CandidateId) -> bool {
|
||||
// associated value (i.e., methods, constants).
|
||||
match item {
|
||||
CandidateId::FunctionId(id) if self.mode == Mode::MethodCall => {
|
||||
self.db().function_signature(id).has_self_param()
|
||||
FunctionSignature::of(self.db(), id).has_self_param()
|
||||
}
|
||||
_ => true,
|
||||
}
|
||||
@@ -2008,7 +2011,7 @@ fn xform_method_sig(&self, method: FunctionId, args: &[GenericArg<'db>]) -> FnSi
|
||||
// we are given do not include type/lifetime parameters for the
|
||||
// method yet. So create fresh variables here for those too,
|
||||
// if there are any.
|
||||
let generics = self.db().generic_params(method.into());
|
||||
let generics = GenericParams::of(self.db(), method.into());
|
||||
|
||||
let xform_fn_sig = if generics.is_empty() {
|
||||
fn_sig.instantiate(self.interner(), args)
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
use either::Either;
|
||||
use hir_def::{
|
||||
DefWithBodyId, FieldId, StaticId, TupleFieldId, UnionId, VariantId,
|
||||
expr_store::Body,
|
||||
expr_store::ExpressionStore,
|
||||
hir::{BindingAnnotation, BindingId, Expr, ExprId, Ordering, PatId},
|
||||
};
|
||||
use la_arena::{Arena, ArenaMap, Idx, RawIdx};
|
||||
@@ -1210,12 +1210,12 @@ pub enum MirSpan {
|
||||
}
|
||||
|
||||
impl MirSpan {
|
||||
pub fn is_ref_span(&self, body: &Body) -> bool {
|
||||
pub fn is_ref_span(&self, store: &ExpressionStore) -> bool {
|
||||
match *self {
|
||||
MirSpan::ExprId(expr) => matches!(body[expr], Expr::Ref { .. }),
|
||||
MirSpan::ExprId(expr) => matches!(store[expr], Expr::Ref { .. }),
|
||||
// FIXME: Figure out if this is correct wrt. match ergonomics.
|
||||
MirSpan::BindingId(binding) => {
|
||||
matches!(body[binding].mode, BindingAnnotation::Ref | BindingAnnotation::RefMut)
|
||||
matches!(store[binding].mode, BindingAnnotation::Ref | BindingAnnotation::RefMut)
|
||||
}
|
||||
MirSpan::PatId(_) | MirSpan::SelfParam | MirSpan::Unknown => false,
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
use std::iter;
|
||||
|
||||
use hir_def::{DefWithBodyId, HasModule};
|
||||
use hir_def::{DefWithBodyId, ExpressionStoreOwnerId, HasModule};
|
||||
use la_arena::ArenaMap;
|
||||
use rustc_hash::FxHashMap;
|
||||
use rustc_type_ir::inherent::GenericArgs as _;
|
||||
@@ -99,7 +99,7 @@ pub fn borrowck_query(
|
||||
let _p = tracing::info_span!("borrowck_query").entered();
|
||||
let module = def.module(db);
|
||||
let interner = DbInterner::new_with(db, module.krate(db));
|
||||
let env = db.trait_environment_for_body(def);
|
||||
let env = db.trait_environment(ExpressionStoreOwnerId::from(def));
|
||||
let mut res = vec![];
|
||||
// This calculates opaques defining scope which is a bit costly therefore is put outside `all_mir_bodies()`.
|
||||
let typing_mode = TypingMode::borrowck(interner, def.into());
|
||||
@@ -121,11 +121,11 @@ fn make_fetch_closure_field<'db>(
|
||||
db: &'db dyn HirDatabase,
|
||||
) -> impl FnOnce(InternedClosureId, GenericArgs<'db>, usize) -> Ty<'db> + use<'db> {
|
||||
|c: InternedClosureId, subst: GenericArgs<'db>, f: usize| {
|
||||
let InternedClosure(def, _) = db.lookup_intern_closure(c);
|
||||
let infer = InferenceResult::for_body(db, def);
|
||||
let InternedClosure(owner, _) = db.lookup_intern_closure(c);
|
||||
let interner = DbInterner::new_no_crate(db);
|
||||
let infer = InferenceResult::of(db, owner);
|
||||
let (captures, _) = infer.closure_info(c);
|
||||
let parent_subst = subst.as_closure().parent_args();
|
||||
let interner = DbInterner::new_no_crate(db);
|
||||
captures.get(f).expect("broken closure field").ty.get().instantiate(interner, parent_subst)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,14 +5,17 @@
|
||||
use base_db::{Crate, target::TargetLoadError};
|
||||
use either::Either;
|
||||
use hir_def::{
|
||||
AdtId, DefWithBodyId, EnumVariantId, FunctionId, GeneralConstId, HasModule, ItemContainerId,
|
||||
Lookup, StaticId, VariantId,
|
||||
expr_store::HygieneId,
|
||||
AdtId, DefWithBodyId, EnumVariantId, ExpressionStoreOwnerId, FunctionId, GeneralConstId,
|
||||
HasModule, ItemContainerId, Lookup, StaticId, VariantId,
|
||||
expr_store::{Body, HygieneId},
|
||||
item_tree::FieldsShape,
|
||||
lang_item::LangItems,
|
||||
layout::{TagEncoding, Variants},
|
||||
resolver::{HasResolver, TypeNs, ValueNs},
|
||||
signatures::{StaticFlags, StructFlags},
|
||||
signatures::{
|
||||
EnumSignature, FunctionSignature, StaticFlags, StaticSignature, StructFlags,
|
||||
StructSignature, TraitSignature,
|
||||
},
|
||||
};
|
||||
use hir_expand::{InFile, mod_path::path, name::Name};
|
||||
use intern::sym;
|
||||
@@ -386,7 +389,7 @@ pub fn pretty_print(
|
||||
for (func, span, def) in stack.iter().take(30).rev() {
|
||||
match func {
|
||||
Either::Left(func) => {
|
||||
let function_name = db.function_signature(*func);
|
||||
let function_name = FunctionSignature::of(db, *func);
|
||||
writeln!(
|
||||
f,
|
||||
"In function {} ({:?})",
|
||||
@@ -398,7 +401,7 @@ pub fn pretty_print(
|
||||
writeln!(f, "In {closure:?}")?;
|
||||
}
|
||||
}
|
||||
let source_map = db.body_with_source_map(*def).1;
|
||||
let source_map = &Body::with_source_map(db, *def).1;
|
||||
let span: InFile<SyntaxNodePtr> = match span {
|
||||
MirSpan::ExprId(e) => match source_map.expr_syntax(*e) {
|
||||
Ok(s) => s.map(|it| it.into()),
|
||||
@@ -441,7 +444,7 @@ pub fn pretty_print(
|
||||
)?;
|
||||
}
|
||||
MirEvalError::MirLowerError(func, err) => {
|
||||
let function_name = db.function_signature(*func);
|
||||
let function_name = FunctionSignature::of(db, *func);
|
||||
let self_ = match func.lookup(db).container {
|
||||
ItemContainerId::ImplId(impl_id) => Some({
|
||||
db.impl_self_ty(impl_id)
|
||||
@@ -450,7 +453,10 @@ pub fn pretty_print(
|
||||
.to_string()
|
||||
}),
|
||||
ItemContainerId::TraitId(it) => Some(
|
||||
db.trait_signature(it).name.display(db, display_target.edition).to_string(),
|
||||
TraitSignature::of(db, it)
|
||||
.name
|
||||
.display(db, display_target.edition)
|
||||
.to_string(),
|
||||
),
|
||||
_ => None,
|
||||
};
|
||||
@@ -660,7 +666,7 @@ pub fn new(
|
||||
db,
|
||||
random_state: oorandom::Rand64::new(0),
|
||||
param_env: trait_env.unwrap_or_else(|| ParamEnvAndCrate {
|
||||
param_env: db.trait_environment_for_body(owner),
|
||||
param_env: db.trait_environment(ExpressionStoreOwnerId::from(owner)),
|
||||
krate: crate_id,
|
||||
}),
|
||||
crate_id,
|
||||
@@ -730,8 +736,8 @@ fn projected_ty(&self, ty: Ty<'db>, proj: PlaceElem) -> Ty<'db> {
|
||||
self.param_env.param_env,
|
||||
ty,
|
||||
|c, subst, f| {
|
||||
let InternedClosure(def, _) = self.db.lookup_intern_closure(c);
|
||||
let infer = InferenceResult::for_body(self.db, def);
|
||||
let InternedClosure(owner, _) = self.db.lookup_intern_closure(c);
|
||||
let infer = InferenceResult::of(self.db, owner);
|
||||
let (captures, _) = infer.closure_info(c);
|
||||
let parent_subst = subst.as_closure().parent_args();
|
||||
captures
|
||||
@@ -893,8 +899,8 @@ fn operand_ty(&self, o: &Operand, locals: &Locals) -> Result<'db, Ty<'db>> {
|
||||
OperandKind::Copy(p) | OperandKind::Move(p) => self.place_ty(p, locals)?,
|
||||
OperandKind::Constant { konst: _, ty } => ty.as_ref(),
|
||||
&OperandKind::Static(s) => {
|
||||
let ty = InferenceResult::for_body(self.db, s.into())
|
||||
.expr_ty(self.db.body(s.into()).body_expr);
|
||||
let ty = InferenceResult::of(self.db, DefWithBodyId::from(s))
|
||||
.expr_ty(Body::of(self.db, s.into()).root_expr());
|
||||
Ty::new_ref(
|
||||
self.interner(),
|
||||
Region::new_static(self.interner()),
|
||||
@@ -1954,6 +1960,9 @@ fn allocate_const_in_heap(
|
||||
MirEvalError::ConstEvalError(name, Box::new(e))
|
||||
})?
|
||||
}
|
||||
GeneralConstId::AnonConstId(_) => {
|
||||
not_supported!("anonymous const evaluation")
|
||||
}
|
||||
};
|
||||
if let ConstKind::Value(value) = result_owner.kind() {
|
||||
break 'b value;
|
||||
@@ -2818,15 +2827,15 @@ fn eval_static(&mut self, st: StaticId, locals: &Locals) -> Result<'db, Address>
|
||||
if let Some(o) = self.static_locations.get(&st) {
|
||||
return Ok(*o);
|
||||
};
|
||||
let static_data = self.db.static_signature(st);
|
||||
let static_data = StaticSignature::of(self.db, st);
|
||||
let result = if !static_data.flags.contains(StaticFlags::EXTERN) {
|
||||
let konst = self.db.const_eval_static(st).map_err(|e| {
|
||||
MirEvalError::ConstEvalError(static_data.name.as_str().to_owned(), Box::new(e))
|
||||
})?;
|
||||
self.allocate_const_in_heap(locals, konst)?
|
||||
} else {
|
||||
let ty = InferenceResult::for_body(self.db, st.into())
|
||||
.expr_ty(self.db.body(st.into()).body_expr);
|
||||
let ty = InferenceResult::of(self.db, DefWithBodyId::from(st))
|
||||
.expr_ty(Body::of(self.db, st.into()).root_expr());
|
||||
let Some((size, align)) = self.size_align_of(ty, locals)? else {
|
||||
not_supported!("unsized extern static");
|
||||
};
|
||||
@@ -2849,7 +2858,7 @@ fn const_eval_discriminant(&self, variant: EnumVariantId) -> Result<'db, i128> {
|
||||
let edition = self.crate_id.data(self.db).edition;
|
||||
let name = format!(
|
||||
"{}::{}",
|
||||
self.db.enum_signature(loc.parent).name.display(db, edition),
|
||||
EnumSignature::of(self.db, loc.parent).name.display(db, edition),
|
||||
loc.parent
|
||||
.enum_variants(self.db)
|
||||
.variant_name_by_id(variant)
|
||||
@@ -2909,7 +2918,7 @@ fn run_drop_glue_deep(
|
||||
let id = adt_def.def_id().0;
|
||||
match id {
|
||||
AdtId::StructId(s) => {
|
||||
let data = self.db.struct_signature(s);
|
||||
let data = StructSignature::of(self.db, s);
|
||||
if data.flags.contains(StructFlags::IS_MANUALLY_DROP) {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ pub(super) fn detect_and_exec_special_function(
|
||||
return Ok(false);
|
||||
}
|
||||
|
||||
let function_data = self.db.function_signature(def);
|
||||
let function_data = FunctionSignature::of(self.db, def);
|
||||
let attrs = AttrFlags::query(self.db, def.into());
|
||||
let is_intrinsic = FunctionSignature::is_intrinsic(self.db, def);
|
||||
|
||||
@@ -152,8 +152,8 @@ fn exec_clone(
|
||||
not_supported!("wrong arg count for clone");
|
||||
};
|
||||
let addr = Address::from_bytes(arg.get(self)?)?;
|
||||
let InternedClosure(closure_owner, _) = self.db.lookup_intern_closure(id.0);
|
||||
let infer = InferenceResult::for_body(self.db, closure_owner);
|
||||
let InternedClosure(owner, _) = self.db.lookup_intern_closure(id.0);
|
||||
let infer = InferenceResult::of(self.db, owner);
|
||||
let (captures, _) = infer.closure_info(id.0);
|
||||
let layout = self.layout(self_ty)?;
|
||||
let db = self.db;
|
||||
@@ -840,7 +840,7 @@ fn exec_intrinsic(
|
||||
// cases.
|
||||
let [lhs, rhs] = args else {
|
||||
return Err(MirEvalError::InternalError(
|
||||
"wrapping_add args are not provided".into(),
|
||||
"ptr_guaranteed_cmp args are not provided".into(),
|
||||
));
|
||||
};
|
||||
let ans = lhs.get(self)? == rhs.get(self)?;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use hir_def::{HasModule, db::DefDatabase};
|
||||
use hir_def::{GenericDefId, HasModule, signatures::FunctionSignature};
|
||||
use hir_expand::EditionedFileId;
|
||||
use span::Edition;
|
||||
use syntax::{TextRange, TextSize};
|
||||
@@ -25,7 +25,7 @@ fn eval_main(db: &TestDB, file_id: EditionedFileId) -> Result<(String, String),
|
||||
.declarations()
|
||||
.find_map(|x| match x {
|
||||
hir_def::ModuleDefId::FunctionId(x) => {
|
||||
if db.function_signature(x).name.display(db, Edition::CURRENT).to_string()
|
||||
if FunctionSignature::of(db, x).name.display(db, Edition::CURRENT).to_string()
|
||||
== "main"
|
||||
{
|
||||
Some(x)
|
||||
@@ -41,7 +41,7 @@ fn eval_main(db: &TestDB, file_id: EditionedFileId) -> Result<(String, String),
|
||||
func_id.into(),
|
||||
GenericArgs::empty(interner).store(),
|
||||
crate::ParamEnvAndCrate {
|
||||
param_env: db.trait_environment(func_id.into()),
|
||||
param_env: db.trait_environment(GenericDefId::from(func_id).into()),
|
||||
krate: func_id.krate(db),
|
||||
}
|
||||
.store(),
|
||||
|
||||
@@ -4,16 +4,17 @@
|
||||
|
||||
use base_db::Crate;
|
||||
use hir_def::{
|
||||
AdtId, DefWithBodyId, EnumVariantId, GeneralConstId, GenericParamId, HasModule,
|
||||
ItemContainerId, LocalFieldId, Lookup, TraitId, TupleId,
|
||||
AdtId, DefWithBodyId, EnumVariantId, ExpressionStoreOwnerId, GeneralConstId, GenericParamId,
|
||||
HasModule, ItemContainerId, LocalFieldId, Lookup, TraitId, TupleId,
|
||||
expr_store::{Body, ExpressionStore, HygieneId, path::Path},
|
||||
hir::{
|
||||
ArithOp, Array, BinaryOp, BindingAnnotation, BindingId, ExprId, LabelId, Literal, MatchArm,
|
||||
Pat, PatId, RecordFieldPat, RecordLitField, RecordSpread,
|
||||
Pat, PatId, RecordFieldPat, RecordLitField, RecordSpread, generics::GenericParams,
|
||||
},
|
||||
item_tree::FieldsShape,
|
||||
lang_item::LangItems,
|
||||
resolver::{HasResolver, ResolveValueResult, Resolver, ValueNs},
|
||||
signatures::{ConstSignature, EnumSignature, FunctionSignature, StaticSignature},
|
||||
};
|
||||
use hir_expand::name::Name;
|
||||
use la_arena::ArenaMap;
|
||||
@@ -185,7 +186,7 @@ pub fn pretty_print(
|
||||
}
|
||||
}
|
||||
MirLowerError::MissingFunctionDefinition(owner, it) => {
|
||||
let body = db.body(*owner);
|
||||
let body = Body::of(db, *owner);
|
||||
writeln!(
|
||||
f,
|
||||
"Missing function definition for {}",
|
||||
@@ -202,13 +203,13 @@ pub fn pretty_print(
|
||||
MirLowerError::GenericArgNotProvided(id, subst) => {
|
||||
let param_name = match *id {
|
||||
GenericParamId::TypeParamId(id) => {
|
||||
db.generic_params(id.parent())[id.local_id()].name().cloned()
|
||||
GenericParams::of(db, id.parent())[id.local_id()].name().cloned()
|
||||
}
|
||||
GenericParamId::ConstParamId(id) => {
|
||||
db.generic_params(id.parent())[id.local_id()].name().cloned()
|
||||
GenericParams::of(db, id.parent())[id.local_id()].name().cloned()
|
||||
}
|
||||
GenericParamId::LifetimeParamId(id) => {
|
||||
Some(db.generic_params(id.parent)[id.local_id].name.clone())
|
||||
Some(GenericParams::of(db, id.parent)[id.local_id].name.clone())
|
||||
}
|
||||
};
|
||||
writeln!(
|
||||
@@ -307,7 +308,7 @@ fn new(
|
||||
closures: vec![],
|
||||
};
|
||||
let resolver = owner.resolver(db);
|
||||
let env = db.trait_environment_for_body(owner);
|
||||
let env = db.trait_environment(ExpressionStoreOwnerId::from(owner));
|
||||
let interner = DbInterner::new_with(db, resolver.krate());
|
||||
// FIXME(next-solver): Is `non_body_analysis()` correct here? Don't we want to reveal opaque types defined by this body?
|
||||
let infcx = interner.infer_ctxt().build(TypingMode::non_body_analysis());
|
||||
@@ -472,7 +473,7 @@ fn lower_expr_to_place_without_adjust(
|
||||
if let DefWithBodyId::FunctionId(f) = self.owner {
|
||||
let assoc = f.lookup(self.db);
|
||||
if let ItemContainerId::TraitId(t) = assoc.container {
|
||||
let name = &self.db.function_signature(f).name;
|
||||
let name = &FunctionSignature::of(self.db, f).name;
|
||||
return Err(MirLowerError::TraitFunctionDefinition(t, name.clone()));
|
||||
}
|
||||
}
|
||||
@@ -1546,6 +1547,9 @@ fn lower_const_to_operand(
|
||||
MirLowerError::ConstEvalError(name.into(), Box::new(e))
|
||||
})?
|
||||
}
|
||||
GeneralConstId::AnonConstId(_) => {
|
||||
return Err(MirLowerError::IncompleteExpr);
|
||||
}
|
||||
}
|
||||
};
|
||||
let ty = self
|
||||
@@ -1553,6 +1557,7 @@ fn lower_const_to_operand(
|
||||
.value_ty(match const_id {
|
||||
GeneralConstId::ConstId(id) => id.into(),
|
||||
GeneralConstId::StaticId(id) => id.into(),
|
||||
GeneralConstId::AnonConstId(_) => unreachable!("handled above"),
|
||||
})
|
||||
.unwrap()
|
||||
.instantiate(self.interner(), subst);
|
||||
@@ -1989,7 +1994,7 @@ fn const_eval_discriminant(&self, variant: EnumVariantId) -> Result<'db, i128> {
|
||||
let loc = variant.lookup(db);
|
||||
let name = format!(
|
||||
"{}::{}",
|
||||
self.db.enum_signature(loc.parent).name.display(db, edition),
|
||||
EnumSignature::of(db, loc.parent).name.display(db, edition),
|
||||
loc.parent
|
||||
.enum_variants(self.db)
|
||||
.variant_name_by_id(variant)
|
||||
@@ -2106,8 +2111,10 @@ pub fn mir_body_for_closure_query<'db>(
|
||||
closure: InternedClosureId,
|
||||
) -> Result<'db, Arc<MirBody>> {
|
||||
let InternedClosure(owner, expr) = db.lookup_intern_closure(closure);
|
||||
let body = db.body(owner);
|
||||
let infer = InferenceResult::for_body(db, owner);
|
||||
let body_owner =
|
||||
owner.as_def_with_body().expect("MIR lowering should only happen for body-owned closures");
|
||||
let body = Body::of(db, body_owner);
|
||||
let infer = InferenceResult::of(db, body_owner);
|
||||
let Expr::Closure { args, body: root, .. } = &body[expr] else {
|
||||
implementation_error!("closure expression is not closure");
|
||||
};
|
||||
@@ -2115,7 +2122,7 @@ pub fn mir_body_for_closure_query<'db>(
|
||||
implementation_error!("closure expression is not closure");
|
||||
};
|
||||
let (captures, kind) = infer.closure_info(closure);
|
||||
let mut ctx = MirLowerCtx::new(db, owner, &body.store, infer);
|
||||
let mut ctx = MirLowerCtx::new(db, body_owner, &body.store, infer);
|
||||
// 0 is return local
|
||||
ctx.result.locals.alloc(Local { ty: infer.expr_ty(*root).store() });
|
||||
let closure_local = ctx.result.locals.alloc(Local {
|
||||
@@ -2138,7 +2145,7 @@ pub fn mir_body_for_closure_query<'db>(
|
||||
});
|
||||
ctx.result.param_locals.push(closure_local);
|
||||
let sig = ctx.interner().signature_unclosure(substs.as_closure().sig(), Safety::Safe);
|
||||
let resolver_guard = ctx.resolver.update_to_inner_scope(db, owner, expr);
|
||||
let resolver_guard = ctx.resolver.update_to_inner_scope(db, body_owner, expr);
|
||||
let current = ctx.lower_params_and_bindings(
|
||||
args.iter().zip(sig.skip_binder().inputs().iter()).map(|(it, y)| (*it, *y)),
|
||||
None,
|
||||
@@ -2222,13 +2229,12 @@ pub fn mir_body_query<'db>(
|
||||
let edition = krate.data(db).edition;
|
||||
let detail = match def {
|
||||
DefWithBodyId::FunctionId(it) => {
|
||||
db.function_signature(it).name.display(db, edition).to_string()
|
||||
FunctionSignature::of(db, it).name.display(db, edition).to_string()
|
||||
}
|
||||
DefWithBodyId::StaticId(it) => {
|
||||
db.static_signature(it).name.display(db, edition).to_string()
|
||||
StaticSignature::of(db, it).name.display(db, edition).to_string()
|
||||
}
|
||||
DefWithBodyId::ConstId(it) => db
|
||||
.const_signature(it)
|
||||
DefWithBodyId::ConstId(it) => ConstSignature::of(db, it)
|
||||
.name
|
||||
.clone()
|
||||
.unwrap_or_else(Name::missing)
|
||||
@@ -2243,9 +2249,9 @@ pub fn mir_body_query<'db>(
|
||||
}
|
||||
};
|
||||
let _p = tracing::info_span!("mir_body_query", ?detail).entered();
|
||||
let body = db.body(def);
|
||||
let infer = InferenceResult::for_body(db, def);
|
||||
let mut result = lower_body_to_mir(db, def, &body, infer, body.body_expr)?;
|
||||
let body = Body::of(db, def);
|
||||
let infer = InferenceResult::of(db, def);
|
||||
let mut result = lower_body_to_mir(db, def, body, infer, body.root_expr())?;
|
||||
result.shrink_to_fit();
|
||||
Ok(Arc::new(result))
|
||||
}
|
||||
@@ -2269,7 +2275,7 @@ pub fn lower_body_to_mir<'db>(
|
||||
// but this is currently also used for `X` in `[(); X]` which live in the same expression store
|
||||
root_expr: ExprId,
|
||||
) -> Result<'db, MirBody> {
|
||||
let is_root = root_expr == body.body_expr;
|
||||
let is_root = root_expr == body.root_expr();
|
||||
// Extract params and self_param only when lowering the body's root expression for a function.
|
||||
if is_root && let DefWithBodyId::FunctionId(fid) = owner {
|
||||
let callable_sig =
|
||||
|
||||
@@ -6,7 +6,11 @@
|
||||
};
|
||||
|
||||
use either::Either;
|
||||
use hir_def::{expr_store::Body, hir::BindingId};
|
||||
use hir_def::{
|
||||
expr_store::Body,
|
||||
hir::BindingId,
|
||||
signatures::{ConstSignature, EnumSignature, FunctionSignature, StaticSignature},
|
||||
};
|
||||
use hir_expand::{Lookup, name::Name};
|
||||
use la_arena::ArenaMap;
|
||||
|
||||
@@ -38,19 +42,19 @@ macro_rules! wln {
|
||||
|
||||
impl MirBody {
|
||||
pub fn pretty_print(&self, db: &dyn HirDatabase, display_target: DisplayTarget) -> String {
|
||||
let hir_body = db.body(self.owner);
|
||||
let mut ctx = MirPrettyCtx::new(self, &hir_body, db, display_target);
|
||||
let hir_body = Body::of(db, self.owner);
|
||||
let mut ctx = MirPrettyCtx::new(self, hir_body, db, display_target);
|
||||
ctx.for_body(|this| match ctx.body.owner {
|
||||
hir_def::DefWithBodyId::FunctionId(id) => {
|
||||
let data = db.function_signature(id);
|
||||
let data = FunctionSignature::of(db, id);
|
||||
w!(this, "fn {}() ", data.name.display(db, this.display_target.edition));
|
||||
}
|
||||
hir_def::DefWithBodyId::StaticId(id) => {
|
||||
let data = db.static_signature(id);
|
||||
let data = StaticSignature::of(db, id);
|
||||
w!(this, "static {}: _ = ", data.name.display(db, this.display_target.edition));
|
||||
}
|
||||
hir_def::DefWithBodyId::ConstId(id) => {
|
||||
let data = db.const_signature(id);
|
||||
let data = ConstSignature::of(db, id);
|
||||
w!(
|
||||
this,
|
||||
"const {}: _ = ",
|
||||
@@ -66,7 +70,7 @@ pub fn pretty_print(&self, db: &dyn HirDatabase, display_target: DisplayTarget)
|
||||
w!(
|
||||
this,
|
||||
"enum {}::{} = ",
|
||||
db.enum_signature(loc.parent).name.display(db, edition),
|
||||
EnumSignature::of(db, loc.parent).name.display(db, edition),
|
||||
loc.parent
|
||||
.enum_variants(db)
|
||||
.variant_name_by_id(id)
|
||||
|
||||
@@ -1,9 +1,13 @@
|
||||
//! Definition of `SolverDefId`
|
||||
|
||||
use hir_def::{
|
||||
AdtId, AttrDefId, BuiltinDeriveImplId, CallableDefId, ConstId, DefWithBodyId, EnumId,
|
||||
EnumVariantId, FunctionId, GeneralConstId, GenericDefId, ImplId, StaticId, StructId, TraitId,
|
||||
TypeAliasId, UnionId,
|
||||
AdtId, AnonConstId, AttrDefId, BuiltinDeriveImplId, CallableDefId, ConstId, DefWithBodyId,
|
||||
EnumId, EnumVariantId, ExpressionStoreOwnerId, FunctionId, GeneralConstId, GenericDefId,
|
||||
ImplId, StaticId, StructId, TraitId, TypeAliasId, UnionId, VariantId,
|
||||
signatures::{
|
||||
ConstSignature, EnumSignature, FunctionSignature, StaticSignature, StructSignature,
|
||||
TraitSignature, TypeAliasSignature, UnionSignature,
|
||||
},
|
||||
};
|
||||
use rustc_type_ir::inherent;
|
||||
use stdx::impl_from;
|
||||
@@ -12,13 +16,13 @@
|
||||
|
||||
use super::DbInterner;
|
||||
|
||||
#[derive(Debug, PartialOrd, Ord, Clone, Copy, PartialEq, Eq, Hash, salsa::Supertype)]
|
||||
#[derive(Debug, PartialOrd, Ord, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
pub enum Ctor {
|
||||
Struct(StructId),
|
||||
Enum(EnumVariantId),
|
||||
}
|
||||
|
||||
#[derive(PartialOrd, Ord, Clone, Copy, PartialEq, Eq, Hash, salsa::Supertype)]
|
||||
#[derive(PartialOrd, Ord, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
pub enum SolverDefId {
|
||||
AdtId(AdtId),
|
||||
ConstId(ConstId),
|
||||
@@ -26,13 +30,13 @@ pub enum SolverDefId {
|
||||
ImplId(ImplId),
|
||||
BuiltinDeriveImplId(BuiltinDeriveImplId),
|
||||
StaticId(StaticId),
|
||||
AnonConstId(AnonConstId),
|
||||
TraitId(TraitId),
|
||||
TypeAliasId(TypeAliasId),
|
||||
InternedClosureId(InternedClosureId),
|
||||
InternedCoroutineId(InternedCoroutineId),
|
||||
InternedOpaqueTyId(InternedOpaqueTyId),
|
||||
EnumVariantId(EnumVariantId),
|
||||
// FIXME(next-solver): Do we need the separation of `Ctor`? It duplicates some variants.
|
||||
Ctor(Ctor),
|
||||
}
|
||||
|
||||
@@ -42,32 +46,33 @@ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
let db = interner.db;
|
||||
match *self {
|
||||
SolverDefId::AdtId(AdtId::StructId(id)) => {
|
||||
f.debug_tuple("AdtId").field(&db.struct_signature(id).name.as_str()).finish()
|
||||
f.debug_tuple("AdtId").field(&StructSignature::of(db, id).name.as_str()).finish()
|
||||
}
|
||||
SolverDefId::AdtId(AdtId::EnumId(id)) => {
|
||||
f.debug_tuple("AdtId").field(&db.enum_signature(id).name.as_str()).finish()
|
||||
f.debug_tuple("AdtId").field(&EnumSignature::of(db, id).name.as_str()).finish()
|
||||
}
|
||||
SolverDefId::AdtId(AdtId::UnionId(id)) => {
|
||||
f.debug_tuple("AdtId").field(&db.union_signature(id).name.as_str()).finish()
|
||||
f.debug_tuple("AdtId").field(&UnionSignature::of(db, id).name.as_str()).finish()
|
||||
}
|
||||
SolverDefId::ConstId(id) => f
|
||||
.debug_tuple("ConstId")
|
||||
.field(&db.const_signature(id).name.as_ref().map_or("_", |name| name.as_str()))
|
||||
.field(&ConstSignature::of(db, id).name.as_ref().map_or("_", |name| name.as_str()))
|
||||
.finish(),
|
||||
SolverDefId::FunctionId(id) => f
|
||||
.debug_tuple("FunctionId")
|
||||
.field(&FunctionSignature::of(db, id).name.as_str())
|
||||
.finish(),
|
||||
SolverDefId::FunctionId(id) => {
|
||||
f.debug_tuple("FunctionId").field(&db.function_signature(id).name.as_str()).finish()
|
||||
}
|
||||
SolverDefId::ImplId(id) => f.debug_tuple("ImplId").field(&id).finish(),
|
||||
SolverDefId::BuiltinDeriveImplId(id) => f.debug_tuple("ImplId").field(&id).finish(),
|
||||
SolverDefId::StaticId(id) => {
|
||||
f.debug_tuple("StaticId").field(&db.static_signature(id).name.as_str()).finish()
|
||||
f.debug_tuple("StaticId").field(&StaticSignature::of(db, id).name.as_str()).finish()
|
||||
}
|
||||
SolverDefId::TraitId(id) => {
|
||||
f.debug_tuple("TraitId").field(&db.trait_signature(id).name.as_str()).finish()
|
||||
f.debug_tuple("TraitId").field(&TraitSignature::of(db, id).name.as_str()).finish()
|
||||
}
|
||||
SolverDefId::TypeAliasId(id) => f
|
||||
.debug_tuple("TypeAliasId")
|
||||
.field(&db.type_alias_signature(id).name.as_str())
|
||||
.field(&TypeAliasSignature::of(db, id).name.as_str())
|
||||
.finish(),
|
||||
SolverDefId::InternedClosureId(id) => {
|
||||
f.debug_tuple("InternedClosureId").field(&id).finish()
|
||||
@@ -83,20 +88,21 @@ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
f.debug_tuple("EnumVariantId")
|
||||
.field(&format_args!(
|
||||
"\"{}::{}\"",
|
||||
db.enum_signature(parent_enum).name.as_str(),
|
||||
EnumSignature::of(db, parent_enum).name.as_str(),
|
||||
parent_enum.enum_variants(db).variant_name_by_id(id).unwrap().as_str()
|
||||
))
|
||||
.finish()
|
||||
}
|
||||
SolverDefId::AnonConstId(id) => f.debug_tuple("AnonConstId").field(&id).finish(),
|
||||
SolverDefId::Ctor(Ctor::Struct(id)) => {
|
||||
f.debug_tuple("Ctor").field(&db.struct_signature(id).name.as_str()).finish()
|
||||
f.debug_tuple("Ctor").field(&StructSignature::of(db, id).name.as_str()).finish()
|
||||
}
|
||||
SolverDefId::Ctor(Ctor::Enum(id)) => {
|
||||
let parent_enum = id.loc(db).parent;
|
||||
f.debug_tuple("Ctor")
|
||||
.field(&format_args!(
|
||||
"\"{}::{}\"",
|
||||
db.enum_signature(parent_enum).name.as_str(),
|
||||
EnumSignature::of(db, parent_enum).name.as_str(),
|
||||
parent_enum.enum_variants(db).variant_name_by_id(id).unwrap().as_str()
|
||||
))
|
||||
.finish()
|
||||
@@ -112,6 +118,7 @@ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
ImplId,
|
||||
BuiltinDeriveImplId,
|
||||
StaticId,
|
||||
AnonConstId,
|
||||
TraitId,
|
||||
TypeAliasId,
|
||||
InternedClosureId,
|
||||
@@ -142,6 +149,7 @@ fn from(value: GeneralConstId) -> Self {
|
||||
match value {
|
||||
GeneralConstId::ConstId(const_id) => SolverDefId::ConstId(const_id),
|
||||
GeneralConstId::StaticId(static_id) => SolverDefId::StaticId(static_id),
|
||||
GeneralConstId::AnonConstId(anon_const_id) => SolverDefId::AnonConstId(anon_const_id),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -158,6 +166,28 @@ fn from(value: DefWithBodyId) -> Self {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<VariantId> for SolverDefId {
|
||||
#[inline]
|
||||
fn from(value: VariantId) -> Self {
|
||||
match value {
|
||||
VariantId::EnumVariantId(id) => id.into(),
|
||||
VariantId::StructId(id) => id.into(),
|
||||
VariantId::UnionId(id) => id.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<ExpressionStoreOwnerId> for SolverDefId {
|
||||
#[inline]
|
||||
fn from(value: ExpressionStoreOwnerId) -> Self {
|
||||
match value {
|
||||
ExpressionStoreOwnerId::Body(body_id) => body_id.into(),
|
||||
ExpressionStoreOwnerId::Signature(sig_id) => sig_id.into(),
|
||||
ExpressionStoreOwnerId::VariantFields(variant_id) => variant_id.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<SolverDefId> for AttrDefId {
|
||||
type Error = ();
|
||||
#[inline]
|
||||
@@ -176,7 +206,8 @@ fn try_from(value: SolverDefId) -> Result<Self, Self::Error> {
|
||||
SolverDefId::BuiltinDeriveImplId(_)
|
||||
| SolverDefId::InternedClosureId(_)
|
||||
| SolverDefId::InternedCoroutineId(_)
|
||||
| SolverDefId::InternedOpaqueTyId(_) => Err(()),
|
||||
| SolverDefId::InternedOpaqueTyId(_)
|
||||
| SolverDefId::AnonConstId(_) => Err(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -199,6 +230,7 @@ fn try_from(value: SolverDefId) -> Result<Self, Self::Error> {
|
||||
| SolverDefId::InternedClosureId(_)
|
||||
| SolverDefId::InternedCoroutineId(_)
|
||||
| SolverDefId::Ctor(Ctor::Struct(_))
|
||||
| SolverDefId::AnonConstId(_)
|
||||
| SolverDefId::AdtId(_) => return Err(()),
|
||||
};
|
||||
Ok(id)
|
||||
@@ -222,6 +254,7 @@ fn try_from(value: SolverDefId) -> Result<Self, Self::Error> {
|
||||
| SolverDefId::InternedOpaqueTyId(_)
|
||||
| SolverDefId::EnumVariantId(_)
|
||||
| SolverDefId::BuiltinDeriveImplId(_)
|
||||
| SolverDefId::AnonConstId(_)
|
||||
| SolverDefId::Ctor(_) => return Err(()),
|
||||
})
|
||||
}
|
||||
@@ -343,6 +376,7 @@ fn from(value: GeneralConstIdWrapper) -> SolverDefId {
|
||||
match value.0 {
|
||||
GeneralConstId::ConstId(id) => SolverDefId::ConstId(id),
|
||||
GeneralConstId::StaticId(id) => SolverDefId::StaticId(id),
|
||||
GeneralConstId::AnonConstId(id) => SolverDefId::AnonConstId(id),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -353,6 +387,7 @@ fn try_from(value: SolverDefId) -> Result<Self, Self::Error> {
|
||||
match value {
|
||||
SolverDefId::ConstId(it) => Ok(Self(it.into())),
|
||||
SolverDefId::StaticId(it) => Ok(Self(it.into())),
|
||||
SolverDefId::AnonConstId(it) => Ok(Self(it.into())),
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -617,6 +617,7 @@ pub fn to_debuggable_error(&self, infcx: &InferCtxt<'db>) -> FulfillmentError<'d
|
||||
}
|
||||
|
||||
mod wf {
|
||||
use hir_def::signatures::ImplSignature;
|
||||
use hir_def::{GeneralConstId, ItemContainerId};
|
||||
use rustc_type_ir::inherent::{
|
||||
AdtDef, BoundExistentialPredicates, GenericArgs as _, IntoKind, SliceLike, Term as _,
|
||||
@@ -1054,7 +1055,7 @@ fn visit_const(&mut self, c: Const<'db>) -> Self::Result {
|
||||
if let GeneralConstId::ConstId(uv_def) = uv.def.0
|
||||
&& let ItemContainerId::ImplId(impl_) =
|
||||
uv_def.loc(self.interner().db).container
|
||||
&& self.interner().db.impl_signature(impl_).target_trait.is_none()
|
||||
&& ImplSignature::of(self.interner().db, impl_).target_trait.is_none()
|
||||
{
|
||||
return; // Subtree is handled by above function
|
||||
} else {
|
||||
|
||||
@@ -55,7 +55,7 @@ pub(crate) fn generics(interner: DbInterner<'_>, def: SolverDefId) -> Generics {
|
||||
let (parent, own_params) = match (def.try_into(), def) {
|
||||
(Ok(def), _) => (
|
||||
parent_generic_def(db, def),
|
||||
own_params_for_generic_params(def, &db.generic_params(def)),
|
||||
own_params_for_generic_params(def, GenericParams::of(db, def)),
|
||||
),
|
||||
(_, SolverDefId::InternedOpaqueTyId(id)) => {
|
||||
match db.lookup_intern_impl_trait_id(id) {
|
||||
|
||||
@@ -10,11 +10,15 @@
|
||||
|
||||
use base_db::Crate;
|
||||
use hir_def::{
|
||||
AdtId, CallableDefId, DefWithBodyId, EnumVariantId, HasModule, ItemContainerId, StructId,
|
||||
UnionId, VariantId,
|
||||
AdtId, CallableDefId, DefWithBodyId, EnumVariantId, ExpressionStoreOwnerId, HasModule,
|
||||
ItemContainerId, StructId, UnionId, VariantId,
|
||||
attrs::AttrFlags,
|
||||
expr_store::{Body, ExpressionStore},
|
||||
lang_item::LangItems,
|
||||
signatures::{FieldData, FnFlags, ImplFlags, StructFlags, TraitFlags},
|
||||
signatures::{
|
||||
EnumSignature, FieldData, FnFlags, FunctionSignature, ImplFlags, ImplSignature,
|
||||
StructFlags, StructSignature, TraitFlags, TraitSignature, UnionSignature,
|
||||
},
|
||||
};
|
||||
use la_arena::Idx;
|
||||
use rustc_abi::{ReprFlags, ReprOptions};
|
||||
@@ -548,7 +552,7 @@ pub fn new<'db>(def_id: AdtId, interner: DbInterner<'db>) -> Self {
|
||||
let db = interner.db();
|
||||
let (flags, variants, repr) = match def_id {
|
||||
AdtId::StructId(struct_id) => {
|
||||
let data = db.struct_signature(struct_id);
|
||||
let data = StructSignature::of(db, struct_id);
|
||||
|
||||
let flags = AdtFlags {
|
||||
is_enum: false,
|
||||
@@ -775,15 +779,15 @@ impl fmt::Debug for AdtDef {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
crate::with_attached_db(|db| match self.inner().id {
|
||||
AdtId::StructId(struct_id) => {
|
||||
let data = db.struct_signature(struct_id);
|
||||
let data = StructSignature::of(db, struct_id);
|
||||
f.write_str(data.name.as_str())
|
||||
}
|
||||
AdtId::UnionId(union_id) => {
|
||||
let data = db.union_signature(union_id);
|
||||
let data = UnionSignature::of(db, union_id);
|
||||
f.write_str(data.name.as_str())
|
||||
}
|
||||
AdtId::EnumId(enum_id) => {
|
||||
let data = db.enum_signature(enum_id);
|
||||
let data = EnumSignature::of(db, enum_id);
|
||||
f.write_str(data.name.as_str())
|
||||
}
|
||||
})
|
||||
@@ -1193,7 +1197,8 @@ fn variances_of(self, def_id: Self::DefId) -> Self::VariancesOf {
|
||||
| SolverDefId::ImplId(_)
|
||||
| SolverDefId::BuiltinDeriveImplId(_)
|
||||
| SolverDefId::InternedClosureId(_)
|
||||
| SolverDefId::InternedCoroutineId(_) => {
|
||||
| SolverDefId::InternedCoroutineId(_)
|
||||
| SolverDefId::AnonConstId(_) => {
|
||||
return VariancesOf::empty(self);
|
||||
}
|
||||
};
|
||||
@@ -1230,7 +1235,7 @@ fn alias_ty_kind(self, alias: rustc_type_ir::AliasTy<Self>) -> AliasTyKind {
|
||||
SolverDefId::InternedOpaqueTyId(_) => AliasTyKind::Opaque,
|
||||
SolverDefId::TypeAliasId(type_alias) => match type_alias.loc(self.db).container {
|
||||
ItemContainerId::ImplId(impl_)
|
||||
if self.db.impl_signature(impl_).target_trait.is_none() =>
|
||||
if ImplSignature::of(self.db, impl_).target_trait.is_none() =>
|
||||
{
|
||||
AliasTyKind::Inherent
|
||||
}
|
||||
@@ -1249,7 +1254,7 @@ fn alias_term_kind(
|
||||
SolverDefId::InternedOpaqueTyId(_) => AliasTermKind::OpaqueTy,
|
||||
SolverDefId::TypeAliasId(type_alias) => match type_alias.loc(self.db).container {
|
||||
ItemContainerId::ImplId(impl_)
|
||||
if self.db.impl_signature(impl_).target_trait.is_none() =>
|
||||
if ImplSignature::of(self.db, impl_).target_trait.is_none() =>
|
||||
{
|
||||
AliasTermKind::InherentTy
|
||||
}
|
||||
@@ -1260,7 +1265,9 @@ fn alias_term_kind(
|
||||
},
|
||||
// rustc creates an `AnonConst` for consts, and evaluates them with CTFE (normalizing projections
|
||||
// via selection, similar to ours `find_matching_impl()`, and not with the trait solver), so mimic it.
|
||||
SolverDefId::ConstId(_) => AliasTermKind::UnevaluatedConst,
|
||||
SolverDefId::ConstId(_) | SolverDefId::AnonConstId(_) => {
|
||||
AliasTermKind::UnevaluatedConst
|
||||
}
|
||||
_ => unimplemented!("Unexpected alias: {:?}", alias.def_id),
|
||||
}
|
||||
}
|
||||
@@ -1308,22 +1315,10 @@ fn parent(self, def_id: Self::DefId) -> Self::DefId {
|
||||
SolverDefId::TypeAliasId(it) => it.lookup(self.db()).container,
|
||||
SolverDefId::ConstId(it) => it.lookup(self.db()).container,
|
||||
SolverDefId::InternedClosureId(it) => {
|
||||
return self
|
||||
.db()
|
||||
.lookup_intern_closure(it)
|
||||
.0
|
||||
.as_generic_def_id(self.db())
|
||||
.unwrap()
|
||||
.into();
|
||||
return self.db().lookup_intern_closure(it).0.generic_def(self.db()).into();
|
||||
}
|
||||
SolverDefId::InternedCoroutineId(it) => {
|
||||
return self
|
||||
.db()
|
||||
.lookup_intern_coroutine(it)
|
||||
.0
|
||||
.as_generic_def_id(self.db())
|
||||
.unwrap()
|
||||
.into();
|
||||
return self.db().lookup_intern_coroutine(it).0.generic_def(self.db()).into();
|
||||
}
|
||||
SolverDefId::StaticId(_)
|
||||
| SolverDefId::AdtId(_)
|
||||
@@ -1332,7 +1327,8 @@ fn parent(self, def_id: Self::DefId) -> Self::DefId {
|
||||
| SolverDefId::BuiltinDeriveImplId(_)
|
||||
| SolverDefId::EnumVariantId(..)
|
||||
| SolverDefId::Ctor(..)
|
||||
| SolverDefId::InternedOpaqueTyId(..) => panic!(),
|
||||
| SolverDefId::InternedOpaqueTyId(..)
|
||||
| SolverDefId::AnonConstId(_) => panic!(),
|
||||
};
|
||||
|
||||
match container {
|
||||
@@ -1361,8 +1357,8 @@ fn coroutine_movability(self, def_id: Self::CoroutineId) -> rustc_ast_ir::Movabi
|
||||
// FIXME: Make this a query? I don't believe this can be accessed from bodies other than
|
||||
// the current infer query, except with revealed opaques - is it rare enough to not matter?
|
||||
let InternedCoroutine(owner, expr_id) = def_id.0.loc(self.db);
|
||||
let body = self.db.body(owner);
|
||||
let expr = &body[expr_id];
|
||||
let store = ExpressionStore::of(self.db, owner);
|
||||
let expr = &store[expr_id];
|
||||
match *expr {
|
||||
hir_def::hir::Expr::Closure { closure_kind, .. } => match closure_kind {
|
||||
hir_def::hir::ClosureKind::Coroutine(movability) => match movability {
|
||||
@@ -1795,6 +1791,7 @@ fn for_each_relevant_impl(
|
||||
| SolverDefId::InternedCoroutineId(_)
|
||||
| SolverDefId::InternedOpaqueTyId(_)
|
||||
| SolverDefId::EnumVariantId(_)
|
||||
| SolverDefId::AnonConstId(_)
|
||||
| SolverDefId::Ctor(_) => return None,
|
||||
};
|
||||
module.block(self.db)
|
||||
@@ -1933,7 +1930,7 @@ fn has_item_definition(self, _def_id: Self::DefId) -> bool {
|
||||
|
||||
fn impl_is_default(self, impl_def_id: Self::ImplId) -> bool {
|
||||
match impl_def_id {
|
||||
AnyImplId::ImplId(impl_id) => self.db.impl_signature(impl_id).is_default(),
|
||||
AnyImplId::ImplId(impl_id) => ImplSignature::of(self.db, impl_id).is_default(),
|
||||
AnyImplId::BuiltinDeriveImplId(_) => false,
|
||||
}
|
||||
}
|
||||
@@ -1960,7 +1957,7 @@ fn impl_polarity(self, impl_id: Self::ImplId) -> rustc_type_ir::ImplPolarity {
|
||||
let AnyImplId::ImplId(impl_id) = impl_id else {
|
||||
return ImplPolarity::Positive;
|
||||
};
|
||||
let impl_data = self.db().impl_signature(impl_id);
|
||||
let impl_data = ImplSignature::of(self.db(), impl_id);
|
||||
if impl_data.flags.contains(ImplFlags::NEGATIVE) {
|
||||
ImplPolarity::Negative
|
||||
} else {
|
||||
@@ -1969,12 +1966,12 @@ fn impl_polarity(self, impl_id: Self::ImplId) -> rustc_type_ir::ImplPolarity {
|
||||
}
|
||||
|
||||
fn trait_is_auto(self, trait_: Self::TraitId) -> bool {
|
||||
let trait_data = self.db().trait_signature(trait_.0);
|
||||
let trait_data = TraitSignature::of(self.db(), trait_.0);
|
||||
trait_data.flags.contains(TraitFlags::AUTO)
|
||||
}
|
||||
|
||||
fn trait_is_alias(self, trait_: Self::TraitId) -> bool {
|
||||
let trait_data = self.db().trait_signature(trait_.0);
|
||||
let trait_data = TraitSignature::of(self.db(), trait_.0);
|
||||
trait_data.flags.contains(TraitFlags::ALIAS)
|
||||
}
|
||||
|
||||
@@ -1983,7 +1980,7 @@ fn trait_is_dyn_compatible(self, trait_: Self::TraitId) -> bool {
|
||||
}
|
||||
|
||||
fn trait_is_fundamental(self, trait_: Self::TraitId) -> bool {
|
||||
let trait_data = self.db().trait_signature(trait_.0);
|
||||
let trait_data = TraitSignature::of(self.db(), trait_.0);
|
||||
trait_data.flags.contains(TraitFlags::FUNDAMENTAL)
|
||||
}
|
||||
|
||||
@@ -2006,9 +2003,9 @@ fn is_general_coroutine(self, def_id: Self::CoroutineId) -> bool {
|
||||
// FIXME: Make this a query? I don't believe this can be accessed from bodies other than
|
||||
// the current infer query, except with revealed opaques - is it rare enough to not matter?
|
||||
let InternedCoroutine(owner, expr_id) = def_id.0.loc(self.db);
|
||||
let body = self.db.body(owner);
|
||||
let store = ExpressionStore::of(self.db, owner);
|
||||
matches!(
|
||||
body[expr_id],
|
||||
store[expr_id],
|
||||
hir_def::hir::Expr::Closure {
|
||||
closure_kind: hir_def::hir::ClosureKind::Coroutine(_),
|
||||
..
|
||||
@@ -2020,9 +2017,9 @@ fn coroutine_is_async(self, def_id: Self::CoroutineId) -> bool {
|
||||
// FIXME: Make this a query? I don't believe this can be accessed from bodies other than
|
||||
// the current infer query, except with revealed opaques - is it rare enough to not matter?
|
||||
let InternedCoroutine(owner, expr_id) = def_id.0.loc(self.db);
|
||||
let body = self.db.body(owner);
|
||||
let store = ExpressionStore::of(self.db, owner);
|
||||
matches!(
|
||||
body[expr_id],
|
||||
store[expr_id],
|
||||
hir_def::hir::Expr::Closure { closure_kind: hir_def::hir::ClosureKind::Async, .. }
|
||||
| hir_def::hir::Expr::Async { .. }
|
||||
)
|
||||
@@ -2143,7 +2140,7 @@ fn opaque_types_and_coroutines_defined_by(self, def_id: Self::LocalDefId) -> Sel
|
||||
crate::opaques::opaque_types_defined_by(self.db, def_id, &mut result);
|
||||
|
||||
// Collect coroutines.
|
||||
let body = self.db.body(def_id);
|
||||
let body = Body::of(self.db, def_id);
|
||||
body.exprs().for_each(|(expr_id, expr)| {
|
||||
if matches!(
|
||||
expr,
|
||||
@@ -2154,8 +2151,10 @@ fn opaque_types_and_coroutines_defined_by(self, def_id: Self::LocalDefId) -> Sel
|
||||
..
|
||||
}
|
||||
) {
|
||||
let coroutine =
|
||||
InternedCoroutineId::new(self.db, InternedCoroutine(def_id, expr_id));
|
||||
let coroutine = InternedCoroutineId::new(
|
||||
self.db,
|
||||
InternedCoroutine(ExpressionStoreOwnerId::Body(def_id), expr_id),
|
||||
);
|
||||
result.push(coroutine.into());
|
||||
}
|
||||
});
|
||||
@@ -2184,7 +2183,7 @@ fn fn_is_const(self, id: Self::FunctionId) -> bool {
|
||||
CallableDefId::FunctionId(id) => id,
|
||||
_ => return false,
|
||||
};
|
||||
self.db().function_signature(id).flags.contains(FnFlags::CONST)
|
||||
FunctionSignature::of(self.db(), id).flags.contains(FnFlags::CONST)
|
||||
}
|
||||
|
||||
fn impl_is_const(self, _def_id: Self::ImplId) -> bool {
|
||||
@@ -2232,11 +2231,11 @@ fn is_default_trait(self, def_id: Self::TraitId) -> bool {
|
||||
}
|
||||
|
||||
fn trait_is_coinductive(self, trait_: Self::TraitId) -> bool {
|
||||
self.db().trait_signature(trait_.0).flags.contains(TraitFlags::COINDUCTIVE)
|
||||
TraitSignature::of(self.db(), trait_.0).flags.contains(TraitFlags::COINDUCTIVE)
|
||||
}
|
||||
|
||||
fn trait_is_unsafe(self, trait_: Self::TraitId) -> bool {
|
||||
self.db().trait_signature(trait_.0).flags.contains(TraitFlags::UNSAFE)
|
||||
TraitSignature::of(self.db(), trait_.0).flags.contains(TraitFlags::UNSAFE)
|
||||
}
|
||||
|
||||
fn impl_self_is_guaranteed_unsized(self, _def_id: Self::ImplId) -> bool {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
//! Things related to IR printing in the next-trait-solver.
|
||||
|
||||
use hir_def::signatures::{TraitSignature, TypeAliasSignature};
|
||||
use rustc_type_ir::{self as ty, ir_print::IrPrint};
|
||||
|
||||
use super::SolverDefId;
|
||||
@@ -14,7 +15,7 @@ fn print_debug(t: &ty::AliasTy<Self>, fmt: &mut std::fmt::Formatter<'_>) -> std:
|
||||
crate::with_attached_db(|db| match t.def_id {
|
||||
SolverDefId::TypeAliasId(id) => fmt.write_str(&format!(
|
||||
"AliasTy({:?}[{:?}])",
|
||||
db.type_alias_signature(id).name.as_str(),
|
||||
TypeAliasSignature::of(db, id).name.as_str(),
|
||||
t.args
|
||||
)),
|
||||
SolverDefId::InternedOpaqueTyId(id) => {
|
||||
@@ -34,7 +35,7 @@ fn print_debug(t: &ty::AliasTerm<Self>, fmt: &mut std::fmt::Formatter<'_>) -> st
|
||||
crate::with_attached_db(|db| match t.def_id {
|
||||
SolverDefId::TypeAliasId(id) => fmt.write_str(&format!(
|
||||
"AliasTerm({:?}[{:?}])",
|
||||
db.type_alias_signature(id).name.as_str(),
|
||||
TypeAliasSignature::of(db, id).name.as_str(),
|
||||
t.args
|
||||
)),
|
||||
SolverDefId::InternedOpaqueTyId(id) => {
|
||||
@@ -58,13 +59,13 @@ fn print_debug(t: &ty::TraitRef<Self>, fmt: &mut std::fmt::Formatter<'_>) -> std
|
||||
fmt.write_str(&format!(
|
||||
"{:?}: {}",
|
||||
self_ty,
|
||||
db.trait_signature(trait_).name.as_str()
|
||||
TraitSignature::of(db, trait_).name.as_str()
|
||||
))
|
||||
} else {
|
||||
fmt.write_str(&format!(
|
||||
"{:?}: {}<{:?}>",
|
||||
self_ty,
|
||||
db.trait_signature(trait_).name.as_str(),
|
||||
TraitSignature::of(db, trait_).name.as_str(),
|
||||
trait_args
|
||||
))
|
||||
}
|
||||
@@ -121,7 +122,7 @@ fn print_debug(
|
||||
let trait_ = t.def_id.0;
|
||||
fmt.write_str(&format!(
|
||||
"ExistentialTraitRef({:?}[{:?}])",
|
||||
db.trait_signature(trait_).name.as_str(),
|
||||
TraitSignature::of(db, trait_).name.as_str(),
|
||||
t.args
|
||||
))
|
||||
})
|
||||
@@ -146,7 +147,7 @@ fn print_debug(
|
||||
};
|
||||
fmt.write_str(&format!(
|
||||
"ExistentialProjection(({:?}[{:?}]) -> {:?})",
|
||||
db.type_alias_signature(id).name.as_str(),
|
||||
TypeAliasSignature::of(db, id).name.as_str(),
|
||||
t.args,
|
||||
t.term
|
||||
))
|
||||
@@ -172,7 +173,7 @@ fn print_debug(
|
||||
};
|
||||
fmt.write_str(&format!(
|
||||
"ProjectionPredicate(({:?}[{:?}]) -> {:?})",
|
||||
db.type_alias_signature(id).name.as_str(),
|
||||
TypeAliasSignature::of(db, id).name.as_str(),
|
||||
t.projection_term.args,
|
||||
t.term
|
||||
))
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
//! Defining `SolverContext` for next-trait-solver.
|
||||
|
||||
use hir_def::{AssocItemId, GeneralConstId};
|
||||
use hir_def::{
|
||||
AssocItemId, GeneralConstId,
|
||||
signatures::{ConstSignature, TypeAliasSignature},
|
||||
};
|
||||
use rustc_next_trait_solver::delegate::SolverDelegate;
|
||||
use rustc_type_ir::{
|
||||
AliasTyKind, GenericArgKind, InferCtxtLike, Interner, PredicatePolarity, TypeFlags,
|
||||
@@ -18,7 +21,7 @@
|
||||
};
|
||||
|
||||
use super::{
|
||||
DbInterner, ErrorGuaranteed, GenericArg, SolverDefId, Span,
|
||||
Const, DbInterner, ErrorGuaranteed, GenericArg, SolverDefId, Span,
|
||||
infer::{DbInternerInferExt, InferCtxt, canonical::instantiate::CanonicalExt},
|
||||
};
|
||||
|
||||
@@ -181,52 +184,53 @@ fn fetch_eligible_assoc_item(
|
||||
return Ok(None);
|
||||
};
|
||||
let impl_items = impl_id.impl_items(self.0.interner.db());
|
||||
let id =
|
||||
match trait_assoc_def_id {
|
||||
SolverDefId::TypeAliasId(trait_assoc_id) => {
|
||||
let trait_assoc_data = self.0.interner.db.type_alias_signature(trait_assoc_id);
|
||||
impl_items
|
||||
.items
|
||||
.iter()
|
||||
.find_map(|(impl_assoc_name, impl_assoc_id)| {
|
||||
if let AssocItemId::TypeAliasId(impl_assoc_id) = *impl_assoc_id
|
||||
&& *impl_assoc_name == trait_assoc_data.name
|
||||
{
|
||||
Some(impl_assoc_id)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.or_else(|| {
|
||||
if trait_assoc_data.ty.is_some() { Some(trait_assoc_id) } else { None }
|
||||
})
|
||||
.map(SolverDefId::TypeAliasId)
|
||||
}
|
||||
SolverDefId::ConstId(trait_assoc_id) => {
|
||||
let trait_assoc_data = self.0.interner.db.const_signature(trait_assoc_id);
|
||||
let trait_assoc_name = trait_assoc_data
|
||||
.name
|
||||
.as_ref()
|
||||
.expect("unnamed consts should not get passed to the solver");
|
||||
impl_items
|
||||
.items
|
||||
.iter()
|
||||
.find_map(|(impl_assoc_name, impl_assoc_id)| {
|
||||
if let AssocItemId::ConstId(impl_assoc_id) = *impl_assoc_id
|
||||
&& impl_assoc_name == trait_assoc_name
|
||||
{
|
||||
Some(impl_assoc_id)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.or_else(|| {
|
||||
let id = match trait_assoc_def_id {
|
||||
SolverDefId::TypeAliasId(trait_assoc_id) => {
|
||||
let trait_assoc_data = TypeAliasSignature::of(self.0.interner.db, trait_assoc_id);
|
||||
impl_items
|
||||
.items
|
||||
.iter()
|
||||
.find_map(|(impl_assoc_name, impl_assoc_id)| {
|
||||
if let AssocItemId::TypeAliasId(impl_assoc_id) = *impl_assoc_id
|
||||
&& *impl_assoc_name == trait_assoc_data.name
|
||||
{
|
||||
Some(impl_assoc_id)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.or_else(|| {
|
||||
if trait_assoc_data.ty.is_some() { Some(trait_assoc_id) } else { None }
|
||||
})
|
||||
.map(SolverDefId::TypeAliasId)
|
||||
}
|
||||
SolverDefId::ConstId(trait_assoc_id) => {
|
||||
let trait_assoc_data = ConstSignature::of(self.0.interner.db, trait_assoc_id);
|
||||
let trait_assoc_name = trait_assoc_data
|
||||
.name
|
||||
.as_ref()
|
||||
.expect("unnamed consts should not get passed to the solver");
|
||||
impl_items
|
||||
.items
|
||||
.iter()
|
||||
.find_map(|(impl_assoc_name, impl_assoc_id)| {
|
||||
if let AssocItemId::ConstId(impl_assoc_id) = *impl_assoc_id
|
||||
&& impl_assoc_name == trait_assoc_name
|
||||
{
|
||||
Some(impl_assoc_id)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.or_else(
|
||||
|| {
|
||||
if trait_assoc_data.has_body() { Some(trait_assoc_id) } else { None }
|
||||
})
|
||||
.map(SolverDefId::ConstId)
|
||||
}
|
||||
_ => panic!("Unexpected SolverDefId"),
|
||||
};
|
||||
},
|
||||
)
|
||||
.map(SolverDefId::ConstId)
|
||||
}
|
||||
_ => panic!("Unexpected SolverDefId"),
|
||||
};
|
||||
Ok(id)
|
||||
}
|
||||
|
||||
@@ -256,6 +260,11 @@ fn evaluate_const(
|
||||
let ec = self.cx().db.const_eval_static(c).ok()?;
|
||||
Some(ec)
|
||||
}
|
||||
// TODO: Wire up const_eval_anon query in Phase 5.
|
||||
// For now, return an error const so normalization resolves the
|
||||
// unevaluated const to Error (matching the old behavior where
|
||||
// complex expressions produced ConstKind::Error directly).
|
||||
GeneralConstId::AnonConstId(_) => Some(Const::error(self.cx())),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
use hir_def::{
|
||||
AdtId, HasModule, TypeParamId,
|
||||
hir::generics::{TypeOrConstParamData, TypeParamProvenance},
|
||||
hir::generics::{GenericParams, TypeOrConstParamData, TypeParamProvenance},
|
||||
};
|
||||
use hir_def::{TraitId, type_ref::Rawness};
|
||||
use intern::{Interned, InternedRef, impl_internable};
|
||||
@@ -690,7 +690,7 @@ pub fn impl_trait_bounds(self, db: &'db dyn HirDatabase) -> Option<Vec<Clause<'d
|
||||
),
|
||||
TyKind::Param(param) => {
|
||||
// FIXME: We shouldn't use `param.id` here.
|
||||
let generic_params = db.generic_params(param.id.parent());
|
||||
let generic_params = GenericParams::of(db, param.id.parent());
|
||||
let param_data = &generic_params[param.id.local_id()];
|
||||
match param_data {
|
||||
TypeOrConstParamData::TypeParamData(p) => match p.provenance {
|
||||
@@ -714,7 +714,7 @@ pub fn impl_trait_bounds(self, db: &'db dyn HirDatabase) -> Option<Vec<Clause<'d
|
||||
}
|
||||
TyKind::Coroutine(coroutine_id, _args) => {
|
||||
let InternedCoroutine(owner, _) = coroutine_id.0.loc(db);
|
||||
let krate = owner.module(db).krate(db);
|
||||
let krate = owner.krate(db);
|
||||
if let Some(future_trait) = hir_def::lang_item::lang_items(db, krate).Future {
|
||||
// This is only used by type walking.
|
||||
// Parameters will be walked outside, and projection predicate is not used.
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
//! Handling of opaque types, detection of defining scope and hidden type.
|
||||
|
||||
use hir_def::{
|
||||
AssocItemId, AssocItemLoc, DefWithBodyId, FunctionId, HasModule, ItemContainerId, TypeAliasId,
|
||||
AssocItemId, AssocItemLoc, DefWithBodyId, ExpressionStoreOwnerId, FunctionId, GenericDefId,
|
||||
HasModule, ItemContainerId, TypeAliasId, signatures::ImplSignature,
|
||||
};
|
||||
use hir_expand::name::Name;
|
||||
use la_arena::ArenaMap;
|
||||
@@ -55,7 +56,7 @@ pub(crate) fn opaque_types_defined_by(
|
||||
};
|
||||
let extend_with_atpit_from_container = |container| match container {
|
||||
ItemContainerId::ImplId(impl_id) => {
|
||||
if db.impl_signature(impl_id).target_trait.is_some() {
|
||||
if ImplSignature::of(db, impl_id).target_trait.is_some() {
|
||||
extend_with_atpit_from_assoc_items(&impl_id.impl_items(db).items);
|
||||
}
|
||||
}
|
||||
@@ -94,7 +95,7 @@ pub(crate) fn rpit_hidden_types<'db>(
|
||||
db: &'db dyn HirDatabase,
|
||||
function: FunctionId,
|
||||
) -> ArenaMap<ImplTraitIdx, StoredEarlyBinder<StoredTy>> {
|
||||
let infer = InferenceResult::for_body(db, function.into());
|
||||
let infer = InferenceResult::of(db, DefWithBodyId::from(function));
|
||||
let mut result = ArenaMap::new();
|
||||
for (opaque, hidden_type) in infer.return_position_impl_trait_types(db) {
|
||||
result.insert(opaque, StoredEarlyBinder::bind(hidden_type.store()));
|
||||
@@ -122,13 +123,14 @@ pub(crate) fn tait_hidden_types<'db>(
|
||||
let infcx = interner.infer_ctxt().build(TypingMode::non_body_analysis());
|
||||
let mut ocx = ObligationCtxt::new(&infcx);
|
||||
let cause = ObligationCause::dummy();
|
||||
let param_env = db.trait_environment(type_alias.into());
|
||||
let param_env =
|
||||
db.trait_environment(ExpressionStoreOwnerId::from(GenericDefId::from(type_alias)));
|
||||
|
||||
let defining_bodies = tait_defining_bodies(db, &loc);
|
||||
|
||||
let mut result = ArenaMap::with_capacity(taits_count);
|
||||
for defining_body in defining_bodies {
|
||||
let infer = InferenceResult::for_body(db, defining_body);
|
||||
let infer = InferenceResult::of(db, defining_body);
|
||||
for (&opaque, hidden_type) in &infer.type_of_opaque {
|
||||
let ImplTraitId::TypeAliasImplTrait(opaque_owner, opaque_idx) = opaque.loc(db) else {
|
||||
continue;
|
||||
@@ -195,7 +197,7 @@ fn tait_defining_bodies(
|
||||
};
|
||||
match loc.container {
|
||||
ItemContainerId::ImplId(impl_id) => {
|
||||
if db.impl_signature(impl_id).target_trait.is_some() {
|
||||
if ImplSignature::of(db, impl_id).target_trait.is_some() {
|
||||
return from_assoc_items(&impl_id.impl_items(db).items);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//! Detecting whether a type is infinitely-sized.
|
||||
|
||||
use hir_def::{AdtId, VariantId};
|
||||
use hir_def::{AdtId, VariantId, hir::generics::GenericParams};
|
||||
use rustc_type_ir::inherent::{AdtDef, IntoKind};
|
||||
|
||||
use crate::{
|
||||
@@ -88,7 +88,7 @@ fn representability_adt_ty<'db>(
|
||||
}
|
||||
|
||||
fn params_in_repr(db: &dyn HirDatabase, def_id: AdtId) -> Box<[bool]> {
|
||||
let generics = db.generic_params(def_id.into());
|
||||
let generics = GenericParams::of(db, def_id.into());
|
||||
let mut params_in_repr = (0..generics.len_lifetimes() + generics.len_type_or_consts())
|
||||
.map(|_| false)
|
||||
.collect::<Box<[bool]>>();
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
//! Impl specialization related things
|
||||
|
||||
use hir_def::{HasModule, ImplId, nameres::crate_def_map};
|
||||
use hir_def::{
|
||||
ExpressionStoreOwnerId, GenericDefId, HasModule, ImplId, nameres::crate_def_map,
|
||||
signatures::ImplSignature,
|
||||
};
|
||||
use intern::sym;
|
||||
use tracing::debug;
|
||||
|
||||
@@ -45,11 +48,13 @@ fn specializes_query(
|
||||
specializing_impl_def_id: ImplId,
|
||||
parent_impl_def_id: ImplId,
|
||||
) -> bool {
|
||||
let trait_env = db.trait_environment(specializing_impl_def_id.into());
|
||||
let trait_env = db.trait_environment(ExpressionStoreOwnerId::from(GenericDefId::from(
|
||||
specializing_impl_def_id,
|
||||
)));
|
||||
let interner = DbInterner::new_with(db, specializing_impl_def_id.krate(db));
|
||||
|
||||
let specializing_impl_signature = db.impl_signature(specializing_impl_def_id);
|
||||
let parent_impl_signature = db.impl_signature(parent_impl_def_id);
|
||||
let specializing_impl_signature = ImplSignature::of(db, specializing_impl_def_id);
|
||||
let parent_impl_signature = ImplSignature::of(db, parent_impl_def_id);
|
||||
|
||||
// We determine whether there's a subset relationship by:
|
||||
//
|
||||
|
||||
@@ -16,9 +16,9 @@
|
||||
use base_db::{Crate, SourceDatabase};
|
||||
use expect_test::Expect;
|
||||
use hir_def::{
|
||||
AssocItemId, DefWithBodyId, HasModule, Lookup, ModuleDefId, ModuleId, SyntheticSyntax,
|
||||
db::DefDatabase,
|
||||
expr_store::{Body, BodySourceMap},
|
||||
AssocItemId, DefWithBodyId, GenericDefId, HasModule, Lookup, ModuleDefId, ModuleId,
|
||||
SyntheticSyntax,
|
||||
expr_store::{Body, BodySourceMap, ExpressionStore, ExpressionStoreSourceMap},
|
||||
hir::{ExprId, Pat, PatId},
|
||||
item_scope::ItemScope,
|
||||
nameres::DefMap,
|
||||
@@ -34,7 +34,6 @@
|
||||
ast::{self, AstNode, HasName},
|
||||
};
|
||||
use test_fixture::WithFixture;
|
||||
use triomphe::Arc;
|
||||
|
||||
use crate::{
|
||||
InferenceResult,
|
||||
@@ -146,15 +145,15 @@ fn check_impl(
|
||||
let mut unexpected_type_mismatches = String::new();
|
||||
for (def, krate) in defs {
|
||||
let display_target = DisplayTarget::from_crate(&db, krate);
|
||||
let (body, body_source_map) = db.body_with_source_map(def);
|
||||
let inference_result = InferenceResult::for_body(&db, def);
|
||||
let (body, body_source_map) = Body::with_source_map(&db, def);
|
||||
let inference_result = InferenceResult::of(&db, def);
|
||||
|
||||
for (pat, ty) in inference_result.type_of_pat.iter() {
|
||||
let mut ty = ty.as_ref();
|
||||
if let Pat::Bind { id, .. } = body[pat] {
|
||||
ty = inference_result.type_of_binding[id].as_ref();
|
||||
}
|
||||
let node = match pat_node(&body_source_map, pat, &db) {
|
||||
let node = match pat_node(body_source_map, pat, &db) {
|
||||
Some(value) => value,
|
||||
None => continue,
|
||||
};
|
||||
@@ -171,7 +170,7 @@ fn check_impl(
|
||||
|
||||
for (expr, ty) in inference_result.type_of_expr.iter() {
|
||||
let ty = ty.as_ref();
|
||||
let node = match expr_node(&body_source_map, expr, &db) {
|
||||
let node = match expr_node(body_source_map, expr, &db) {
|
||||
Some(value) => value,
|
||||
None => continue,
|
||||
};
|
||||
@@ -202,9 +201,9 @@ fn check_impl(
|
||||
for (expr_or_pat, mismatch) in inference_result.type_mismatches() {
|
||||
let Some(node) = (match expr_or_pat {
|
||||
hir_def::hir::ExprOrPatId::ExprId(expr) => {
|
||||
expr_node(&body_source_map, expr, &db)
|
||||
expr_node(body_source_map, expr, &db)
|
||||
}
|
||||
hir_def::hir::ExprOrPatId::PatId(pat) => pat_node(&body_source_map, pat, &db),
|
||||
hir_def::hir::ExprOrPatId::PatId(pat) => pat_node(body_source_map, pat, &db),
|
||||
}) else {
|
||||
continue;
|
||||
};
|
||||
@@ -223,7 +222,7 @@ fn check_impl(
|
||||
}
|
||||
|
||||
for (type_ref, ty) in inference_result.placeholder_types() {
|
||||
let node = match type_node(&body_source_map, type_ref, &db) {
|
||||
let node = match type_node(body_source_map, type_ref, &db) {
|
||||
Some(value) => value,
|
||||
None => continue,
|
||||
};
|
||||
@@ -321,16 +320,20 @@ fn infer_with_mismatches(content: &str, include_mismatches: bool) -> String {
|
||||
let mut buf = String::new();
|
||||
|
||||
let mut infer_def = |inference_result: &InferenceResult,
|
||||
body: Arc<Body>,
|
||||
body_source_map: Arc<BodySourceMap>,
|
||||
store: &ExpressionStore,
|
||||
source_map: &ExpressionStoreSourceMap,
|
||||
self_param: Option<(
|
||||
hir_def::hir::BindingId,
|
||||
Option<InFile<hir_def::expr_store::SelfParamPtr>>,
|
||||
)>,
|
||||
krate: Crate| {
|
||||
let display_target = DisplayTarget::from_crate(&db, krate);
|
||||
let mut types: Vec<(InFile<SyntaxNode>, Ty<'_>)> = Vec::new();
|
||||
let mut mismatches: Vec<(InFile<SyntaxNode>, &TypeMismatch)> = Vec::new();
|
||||
|
||||
if let Some(self_param) = body.self_param {
|
||||
let ty = &inference_result.type_of_binding[self_param];
|
||||
if let Some(syntax_ptr) = body_source_map.self_param_syntax() {
|
||||
if let Some((binding_id, syntax_ptr)) = self_param {
|
||||
let ty = &inference_result.type_of_binding[binding_id];
|
||||
if let Some(syntax_ptr) = syntax_ptr {
|
||||
let root = db.parse_or_expand(syntax_ptr.file_id);
|
||||
let node = syntax_ptr.map(|ptr| ptr.to_node(&root).syntax().clone());
|
||||
types.push((node, ty.as_ref()));
|
||||
@@ -338,10 +341,10 @@ fn infer_with_mismatches(content: &str, include_mismatches: bool) -> String {
|
||||
}
|
||||
|
||||
for (pat, mut ty) in inference_result.type_of_pat.iter() {
|
||||
if let Pat::Bind { id, .. } = body[pat] {
|
||||
if let Pat::Bind { id, .. } = store[pat] {
|
||||
ty = &inference_result.type_of_binding[id];
|
||||
}
|
||||
let node = match body_source_map.pat_syntax(pat) {
|
||||
let node = match source_map.pat_syntax(pat) {
|
||||
Ok(sp) => {
|
||||
let root = db.parse_or_expand(sp.file_id);
|
||||
sp.map(|ptr| ptr.to_node(&root).syntax().clone())
|
||||
@@ -355,7 +358,7 @@ fn infer_with_mismatches(content: &str, include_mismatches: bool) -> String {
|
||||
}
|
||||
|
||||
for (expr, ty) in inference_result.type_of_expr.iter() {
|
||||
let node = match body_source_map.expr_syntax(expr) {
|
||||
let node = match source_map.expr_syntax(expr) {
|
||||
Ok(sp) => {
|
||||
let root = db.parse_or_expand(sp.file_id);
|
||||
sp.map(|ptr| ptr.to_node(&root).syntax().clone())
|
||||
@@ -414,16 +417,56 @@ fn infer_with_mismatches(content: &str, include_mismatches: bool) -> String {
|
||||
let def_map = module.def_map(&db);
|
||||
|
||||
let mut defs: Vec<(DefWithBodyId, Crate)> = Vec::new();
|
||||
let mut generic_defs: Vec<(GenericDefId, Crate)> = Vec::new();
|
||||
visit_module(&db, def_map, module, &mut |it| {
|
||||
let def = match it {
|
||||
ModuleDefId::FunctionId(it) => it.into(),
|
||||
ModuleDefId::EnumVariantId(it) => it.into(),
|
||||
ModuleDefId::ConstId(it) => it.into(),
|
||||
ModuleDefId::StaticId(it) => it.into(),
|
||||
_ => return,
|
||||
};
|
||||
defs.push((def, module.krate(&db)))
|
||||
let krate = module.krate(&db);
|
||||
match it {
|
||||
ModuleDefId::FunctionId(it) => {
|
||||
defs.push((it.into(), krate));
|
||||
generic_defs.push((it.into(), krate));
|
||||
}
|
||||
ModuleDefId::EnumVariantId(it) => {
|
||||
defs.push((it.into(), krate));
|
||||
}
|
||||
ModuleDefId::ConstId(it) => {
|
||||
defs.push((it.into(), krate));
|
||||
generic_defs.push((it.into(), krate));
|
||||
}
|
||||
ModuleDefId::StaticId(it) => {
|
||||
defs.push((it.into(), krate));
|
||||
generic_defs.push((it.into(), krate));
|
||||
}
|
||||
ModuleDefId::AdtId(it) => {
|
||||
generic_defs.push((it.into(), krate));
|
||||
}
|
||||
ModuleDefId::TraitId(it) => {
|
||||
generic_defs.push((it.into(), krate));
|
||||
}
|
||||
ModuleDefId::TypeAliasId(it) => {
|
||||
generic_defs.push((it.into(), krate));
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
});
|
||||
// Also collect impls
|
||||
for impl_id in def_map[module].scope.impls() {
|
||||
generic_defs.push((impl_id.into(), module.krate(&db)));
|
||||
let impl_data = impl_id.impl_items(&db);
|
||||
for &(_, item) in impl_data.items.iter() {
|
||||
match item {
|
||||
AssocItemId::FunctionId(it) => {
|
||||
generic_defs.push((it.into(), module.krate(&db)));
|
||||
}
|
||||
AssocItemId::ConstId(it) => {
|
||||
generic_defs.push((it.into(), module.krate(&db)));
|
||||
}
|
||||
AssocItemId::TypeAliasId(it) => {
|
||||
generic_defs.push((it.into(), module.krate(&db)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
defs.sort_by_key(|(def, _)| match def {
|
||||
DefWithBodyId::FunctionId(it) => {
|
||||
let loc = it.lookup(&db);
|
||||
@@ -443,9 +486,22 @@ fn infer_with_mismatches(content: &str, include_mismatches: bool) -> String {
|
||||
}
|
||||
});
|
||||
for (def, krate) in defs {
|
||||
let (body, source_map) = db.body_with_source_map(def);
|
||||
let infer = InferenceResult::for_body(&db, def);
|
||||
infer_def(infer, body, source_map, krate);
|
||||
let (body, source_map) = Body::with_source_map(&db, def);
|
||||
let infer = InferenceResult::of(&db, def);
|
||||
let self_param = body.self_param.map(|id| (id, source_map.self_param_syntax()));
|
||||
infer_def(infer, body, source_map, self_param, krate);
|
||||
}
|
||||
|
||||
// Also infer signature const expressions (array lengths, const generic args, etc.)
|
||||
generic_defs.dedup();
|
||||
for (def, krate) in generic_defs {
|
||||
let (store, source_map) = ExpressionStore::with_source_map(&db, def.into());
|
||||
// Skip if there are no const expressions in the signature
|
||||
if store.const_expr_origins().is_empty() {
|
||||
continue;
|
||||
}
|
||||
let infer = InferenceResult::of(&db, def);
|
||||
infer_def(infer, store, source_map, None, krate);
|
||||
}
|
||||
|
||||
buf.truncate(buf.trim_end().len());
|
||||
@@ -465,14 +521,14 @@ pub(crate) fn visit_module(
|
||||
for &(_, item) in impl_data.items.iter() {
|
||||
match item {
|
||||
AssocItemId::FunctionId(it) => {
|
||||
let body = db.body(it.into());
|
||||
let body = Body::of(db, it.into());
|
||||
cb(it.into());
|
||||
visit_body(db, &body, cb);
|
||||
visit_body(db, body, cb);
|
||||
}
|
||||
AssocItemId::ConstId(it) => {
|
||||
let body = db.body(it.into());
|
||||
let body = Body::of(db, it.into());
|
||||
cb(it.into());
|
||||
visit_body(db, &body, cb);
|
||||
visit_body(db, body, cb);
|
||||
}
|
||||
AssocItemId::TypeAliasId(it) => {
|
||||
cb(it.into());
|
||||
@@ -491,22 +547,22 @@ fn visit_scope(
|
||||
cb(decl);
|
||||
match decl {
|
||||
ModuleDefId::FunctionId(it) => {
|
||||
let body = db.body(it.into());
|
||||
visit_body(db, &body, cb);
|
||||
let body = Body::of(db, it.into());
|
||||
visit_body(db, body, cb);
|
||||
}
|
||||
ModuleDefId::ConstId(it) => {
|
||||
let body = db.body(it.into());
|
||||
visit_body(db, &body, cb);
|
||||
let body = Body::of(db, it.into());
|
||||
visit_body(db, body, cb);
|
||||
}
|
||||
ModuleDefId::StaticId(it) => {
|
||||
let body = db.body(it.into());
|
||||
visit_body(db, &body, cb);
|
||||
let body = Body::of(db, it.into());
|
||||
visit_body(db, body, cb);
|
||||
}
|
||||
ModuleDefId::AdtId(hir_def::AdtId::EnumId(it)) => {
|
||||
it.enum_variants(db).variants.iter().for_each(|&(it, _, _)| {
|
||||
let body = db.body(it.into());
|
||||
let body = Body::of(db, it.into());
|
||||
cb(it.into());
|
||||
visit_body(db, &body, cb);
|
||||
visit_body(db, body, cb);
|
||||
});
|
||||
}
|
||||
ModuleDefId::TraitId(it) => {
|
||||
@@ -596,16 +652,14 @@ fn main() {
|
||||
let module = db.module_for_file(pos.file_id.file_id(&db));
|
||||
let crate_def_map = module.def_map(&db);
|
||||
visit_module(&db, crate_def_map, module, &mut |def| {
|
||||
InferenceResult::for_body(
|
||||
&db,
|
||||
match def {
|
||||
ModuleDefId::FunctionId(it) => it.into(),
|
||||
ModuleDefId::EnumVariantId(it) => it.into(),
|
||||
ModuleDefId::ConstId(it) => it.into(),
|
||||
ModuleDefId::StaticId(it) => it.into(),
|
||||
_ => return,
|
||||
},
|
||||
);
|
||||
let body_def: DefWithBodyId = match def {
|
||||
ModuleDefId::FunctionId(it) => it.into(),
|
||||
ModuleDefId::EnumVariantId(it) => it.into(),
|
||||
ModuleDefId::ConstId(it) => it.into(),
|
||||
ModuleDefId::StaticId(it) => it.into(),
|
||||
_ => return,
|
||||
};
|
||||
InferenceResult::of(&db, body_def);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -640,16 +694,14 @@ fn main() {
|
||||
let module = db.module_for_file(pos.file_id.file_id(&db));
|
||||
let crate_def_map = module.def_map(&db);
|
||||
visit_module(&db, crate_def_map, module, &mut |def| {
|
||||
InferenceResult::for_body(
|
||||
&db,
|
||||
match def {
|
||||
ModuleDefId::FunctionId(it) => it.into(),
|
||||
ModuleDefId::EnumVariantId(it) => it.into(),
|
||||
ModuleDefId::ConstId(it) => it.into(),
|
||||
ModuleDefId::StaticId(it) => it.into(),
|
||||
_ => return,
|
||||
},
|
||||
);
|
||||
let body_def: DefWithBodyId = match def {
|
||||
ModuleDefId::FunctionId(it) => it.into(),
|
||||
ModuleDefId::EnumVariantId(it) => it.into(),
|
||||
ModuleDefId::ConstId(it) => it.into(),
|
||||
ModuleDefId::StaticId(it) => it.into(),
|
||||
_ => return,
|
||||
};
|
||||
InferenceResult::of(&db, body_def);
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
use expect_test::{Expect, expect};
|
||||
use hir_def::db::DefDatabase;
|
||||
use hir_def::{
|
||||
DefWithBodyId,
|
||||
expr_store::{Body, ExpressionStore},
|
||||
};
|
||||
use hir_expand::{HirFileId, files::InFileWrapper};
|
||||
use itertools::Itertools;
|
||||
use span::TextRange;
|
||||
@@ -28,19 +31,20 @@ fn check_closure_captures(#[rust_analyzer::rust_fixture] ra_fixture: &str, expec
|
||||
|
||||
let mut captures_info = Vec::new();
|
||||
for def in defs {
|
||||
let def = match def {
|
||||
let def: DefWithBodyId = match def {
|
||||
hir_def::ModuleDefId::FunctionId(it) => it.into(),
|
||||
hir_def::ModuleDefId::EnumVariantId(it) => it.into(),
|
||||
hir_def::ModuleDefId::ConstId(it) => it.into(),
|
||||
hir_def::ModuleDefId::StaticId(it) => it.into(),
|
||||
_ => continue,
|
||||
};
|
||||
let infer = InferenceResult::for_body(&db, def);
|
||||
let infer = InferenceResult::of(&db, def);
|
||||
let db = &db;
|
||||
captures_info.extend(infer.closure_info.iter().flat_map(
|
||||
|(closure_id, (captures, _))| {
|
||||
let closure = db.lookup_intern_closure(*closure_id);
|
||||
let source_map = db.body_with_source_map(closure.0).1;
|
||||
let body_owner = closure.0;
|
||||
let source_map = ExpressionStore::with_source_map(db, body_owner).1;
|
||||
let closure_text_range = source_map
|
||||
.expr_syntax(closure.1)
|
||||
.expect("failed to map closure to SyntaxNode")
|
||||
@@ -56,7 +60,8 @@ fn text_range<N: AstNode>(
|
||||
}
|
||||
|
||||
// FIXME: Deduplicate this with hir::Local::sources().
|
||||
let (body, source_map) = db.body_with_source_map(closure.0);
|
||||
let (body, source_map) =
|
||||
Body::with_source_map(db, body_owner.as_def_with_body().unwrap());
|
||||
let local_text_range =
|
||||
match body.self_param.zip(source_map.self_param_syntax()) {
|
||||
Some((param, source)) if param == capture.local() => {
|
||||
@@ -71,7 +76,7 @@ fn text_range<N: AstNode>(
|
||||
.map(|it| format!("{it:?}"))
|
||||
.join(", "),
|
||||
};
|
||||
let place = capture.display_place(closure.0, db);
|
||||
let place = capture.display_place(body_owner, db);
|
||||
let capture_ty = capture
|
||||
.ty
|
||||
.get()
|
||||
|
||||
@@ -24,7 +24,7 @@ fn foo() -> i32 {
|
||||
let crate_def_map = module.def_map(&db);
|
||||
visit_module(&db, crate_def_map, module, &mut |def| {
|
||||
if let ModuleDefId::FunctionId(it) = def {
|
||||
InferenceResult::for_body(&db, it.into());
|
||||
InferenceResult::of(&db, DefWithBodyId::from(it));
|
||||
}
|
||||
});
|
||||
},
|
||||
@@ -34,21 +34,21 @@ fn foo() -> i32 {
|
||||
"source_root_crates_shim",
|
||||
"crate_local_def_map",
|
||||
"file_item_tree_query",
|
||||
"ast_id_map_shim",
|
||||
"ast_id_map",
|
||||
"parse_shim",
|
||||
"real_span_map_shim",
|
||||
"InferenceResult::for_body_",
|
||||
"function_signature_shim",
|
||||
"function_signature_with_source_map_shim",
|
||||
"FunctionSignature::of_",
|
||||
"FunctionSignature::with_source_map_",
|
||||
"AttrFlags::query_",
|
||||
"body_shim",
|
||||
"body_with_source_map_shim",
|
||||
"Body::of_",
|
||||
"Body::with_source_map_",
|
||||
"trait_environment_query",
|
||||
"lang_items",
|
||||
"crate_lang_items",
|
||||
"GenericPredicates::query_with_diagnostics_",
|
||||
"ImplTraits::return_type_impl_traits_",
|
||||
"expr_scopes_shim",
|
||||
"ExprScopes::body_expr_scopes_",
|
||||
]
|
||||
"#]],
|
||||
);
|
||||
@@ -69,7 +69,7 @@ fn foo() -> i32 {
|
||||
let crate_def_map = module.def_map(&db);
|
||||
visit_module(&db, crate_def_map, module, &mut |def| {
|
||||
if let ModuleDefId::FunctionId(it) = def {
|
||||
InferenceResult::for_body(&db, it.into());
|
||||
InferenceResult::of(&db, DefWithBodyId::from(it));
|
||||
}
|
||||
});
|
||||
},
|
||||
@@ -77,14 +77,14 @@ fn foo() -> i32 {
|
||||
expect_test::expect![[r#"
|
||||
[
|
||||
"parse_shim",
|
||||
"ast_id_map_shim",
|
||||
"ast_id_map",
|
||||
"file_item_tree_query",
|
||||
"real_span_map_shim",
|
||||
"AttrFlags::query_",
|
||||
"function_signature_with_source_map_shim",
|
||||
"function_signature_shim",
|
||||
"body_with_source_map_shim",
|
||||
"body_shim",
|
||||
"FunctionSignature::with_source_map_",
|
||||
"FunctionSignature::of_",
|
||||
"Body::with_source_map_",
|
||||
"Body::of_",
|
||||
]
|
||||
"#]],
|
||||
);
|
||||
@@ -112,7 +112,7 @@ fn baz() -> i32 {
|
||||
let crate_def_map = module.def_map(&db);
|
||||
visit_module(&db, crate_def_map, module, &mut |def| {
|
||||
if let ModuleDefId::FunctionId(it) = def {
|
||||
InferenceResult::for_body(&db, it.into());
|
||||
InferenceResult::of(&db, DefWithBodyId::from(it));
|
||||
}
|
||||
});
|
||||
},
|
||||
@@ -122,41 +122,41 @@ fn baz() -> i32 {
|
||||
"source_root_crates_shim",
|
||||
"crate_local_def_map",
|
||||
"file_item_tree_query",
|
||||
"ast_id_map_shim",
|
||||
"ast_id_map",
|
||||
"parse_shim",
|
||||
"real_span_map_shim",
|
||||
"InferenceResult::for_body_",
|
||||
"function_signature_shim",
|
||||
"function_signature_with_source_map_shim",
|
||||
"FunctionSignature::of_",
|
||||
"FunctionSignature::with_source_map_",
|
||||
"AttrFlags::query_",
|
||||
"body_shim",
|
||||
"body_with_source_map_shim",
|
||||
"Body::of_",
|
||||
"Body::with_source_map_",
|
||||
"trait_environment_query",
|
||||
"lang_items",
|
||||
"crate_lang_items",
|
||||
"GenericPredicates::query_with_diagnostics_",
|
||||
"ImplTraits::return_type_impl_traits_",
|
||||
"expr_scopes_shim",
|
||||
"ExprScopes::body_expr_scopes_",
|
||||
"InferenceResult::for_body_",
|
||||
"function_signature_shim",
|
||||
"function_signature_with_source_map_shim",
|
||||
"FunctionSignature::of_",
|
||||
"FunctionSignature::with_source_map_",
|
||||
"AttrFlags::query_",
|
||||
"body_shim",
|
||||
"body_with_source_map_shim",
|
||||
"Body::of_",
|
||||
"Body::with_source_map_",
|
||||
"trait_environment_query",
|
||||
"GenericPredicates::query_with_diagnostics_",
|
||||
"ImplTraits::return_type_impl_traits_",
|
||||
"expr_scopes_shim",
|
||||
"ExprScopes::body_expr_scopes_",
|
||||
"InferenceResult::for_body_",
|
||||
"function_signature_shim",
|
||||
"function_signature_with_source_map_shim",
|
||||
"FunctionSignature::of_",
|
||||
"FunctionSignature::with_source_map_",
|
||||
"AttrFlags::query_",
|
||||
"body_shim",
|
||||
"body_with_source_map_shim",
|
||||
"Body::of_",
|
||||
"Body::with_source_map_",
|
||||
"trait_environment_query",
|
||||
"GenericPredicates::query_with_diagnostics_",
|
||||
"ImplTraits::return_type_impl_traits_",
|
||||
"expr_scopes_shim",
|
||||
"ExprScopes::body_expr_scopes_",
|
||||
]
|
||||
"#]],
|
||||
);
|
||||
@@ -182,7 +182,7 @@ fn baz() -> i32 {
|
||||
let crate_def_map = module.def_map(&db);
|
||||
visit_module(&db, crate_def_map, module, &mut |def| {
|
||||
if let ModuleDefId::FunctionId(it) = def {
|
||||
InferenceResult::for_body(&db, it.into());
|
||||
InferenceResult::of(&db, DefWithBodyId::from(it));
|
||||
}
|
||||
});
|
||||
},
|
||||
@@ -190,26 +190,26 @@ fn baz() -> i32 {
|
||||
expect_test::expect![[r#"
|
||||
[
|
||||
"parse_shim",
|
||||
"ast_id_map_shim",
|
||||
"ast_id_map",
|
||||
"file_item_tree_query",
|
||||
"real_span_map_shim",
|
||||
"AttrFlags::query_",
|
||||
"function_signature_with_source_map_shim",
|
||||
"function_signature_shim",
|
||||
"body_with_source_map_shim",
|
||||
"body_shim",
|
||||
"FunctionSignature::with_source_map_",
|
||||
"FunctionSignature::of_",
|
||||
"Body::with_source_map_",
|
||||
"Body::of_",
|
||||
"AttrFlags::query_",
|
||||
"function_signature_with_source_map_shim",
|
||||
"function_signature_shim",
|
||||
"body_with_source_map_shim",
|
||||
"body_shim",
|
||||
"FunctionSignature::with_source_map_",
|
||||
"FunctionSignature::of_",
|
||||
"Body::with_source_map_",
|
||||
"Body::of_",
|
||||
"InferenceResult::for_body_",
|
||||
"expr_scopes_shim",
|
||||
"ExprScopes::body_expr_scopes_",
|
||||
"AttrFlags::query_",
|
||||
"function_signature_with_source_map_shim",
|
||||
"function_signature_shim",
|
||||
"body_with_source_map_shim",
|
||||
"body_shim",
|
||||
"FunctionSignature::with_source_map_",
|
||||
"FunctionSignature::of_",
|
||||
"Body::with_source_map_",
|
||||
"Body::of_",
|
||||
]
|
||||
"#]],
|
||||
);
|
||||
@@ -242,7 +242,7 @@ fn bar() -> f32 {
|
||||
"source_root_crates_shim",
|
||||
"crate_local_def_map",
|
||||
"file_item_tree_query",
|
||||
"ast_id_map_shim",
|
||||
"ast_id_map",
|
||||
"parse_shim",
|
||||
"real_span_map_shim",
|
||||
"TraitImpls::for_crate_",
|
||||
@@ -279,7 +279,7 @@ pub struct NewStruct {
|
||||
expect_test::expect![[r#"
|
||||
[
|
||||
"parse_shim",
|
||||
"ast_id_map_shim",
|
||||
"ast_id_map",
|
||||
"file_item_tree_query",
|
||||
"real_span_map_shim",
|
||||
"crate_local_def_map",
|
||||
@@ -317,7 +317,7 @@ fn bar() -> f32 {
|
||||
"source_root_crates_shim",
|
||||
"crate_local_def_map",
|
||||
"file_item_tree_query",
|
||||
"ast_id_map_shim",
|
||||
"ast_id_map",
|
||||
"parse_shim",
|
||||
"real_span_map_shim",
|
||||
"TraitImpls::for_crate_",
|
||||
@@ -355,7 +355,7 @@ pub enum SomeEnum {
|
||||
expect_test::expect![[r#"
|
||||
[
|
||||
"parse_shim",
|
||||
"ast_id_map_shim",
|
||||
"ast_id_map",
|
||||
"file_item_tree_query",
|
||||
"real_span_map_shim",
|
||||
"crate_local_def_map",
|
||||
@@ -393,7 +393,7 @@ fn bar() -> f32 {
|
||||
"source_root_crates_shim",
|
||||
"crate_local_def_map",
|
||||
"file_item_tree_query",
|
||||
"ast_id_map_shim",
|
||||
"ast_id_map",
|
||||
"parse_shim",
|
||||
"real_span_map_shim",
|
||||
"TraitImpls::for_crate_",
|
||||
@@ -428,7 +428,7 @@ fn bar() -> f32 {
|
||||
expect_test::expect![[r#"
|
||||
[
|
||||
"parse_shim",
|
||||
"ast_id_map_shim",
|
||||
"ast_id_map",
|
||||
"file_item_tree_query",
|
||||
"real_span_map_shim",
|
||||
"crate_local_def_map",
|
||||
@@ -470,7 +470,7 @@ pub struct SomeStruct {
|
||||
"source_root_crates_shim",
|
||||
"crate_local_def_map",
|
||||
"file_item_tree_query",
|
||||
"ast_id_map_shim",
|
||||
"ast_id_map",
|
||||
"parse_shim",
|
||||
"real_span_map_shim",
|
||||
"TraitImpls::for_crate_",
|
||||
@@ -513,7 +513,7 @@ pub fn new(value: i32) -> Self {
|
||||
expect_test::expect![[r#"
|
||||
[
|
||||
"parse_shim",
|
||||
"ast_id_map_shim",
|
||||
"ast_id_map",
|
||||
"file_item_tree_query",
|
||||
"real_span_map_shim",
|
||||
"crate_local_def_map",
|
||||
@@ -562,7 +562,7 @@ fn main() {
|
||||
});
|
||||
|
||||
for def in defs {
|
||||
let _inference_result = InferenceResult::for_body(&db, def);
|
||||
let _inference_result = InferenceResult::of(&db, def);
|
||||
}
|
||||
},
|
||||
&[("trait_solve_shim", 0)],
|
||||
@@ -571,23 +571,23 @@ fn main() {
|
||||
"source_root_crates_shim",
|
||||
"crate_local_def_map",
|
||||
"file_item_tree_query",
|
||||
"ast_id_map_shim",
|
||||
"ast_id_map",
|
||||
"parse_shim",
|
||||
"real_span_map_shim",
|
||||
"TraitItems::query_with_diagnostics_",
|
||||
"body_shim",
|
||||
"body_with_source_map_shim",
|
||||
"Body::of_",
|
||||
"Body::with_source_map_",
|
||||
"AttrFlags::query_",
|
||||
"ImplItems::of_",
|
||||
"InferenceResult::for_body_",
|
||||
"trait_signature_shim",
|
||||
"trait_signature_with_source_map_shim",
|
||||
"TraitSignature::of_",
|
||||
"TraitSignature::with_source_map_",
|
||||
"AttrFlags::query_",
|
||||
"function_signature_shim",
|
||||
"function_signature_with_source_map_shim",
|
||||
"FunctionSignature::of_",
|
||||
"FunctionSignature::with_source_map_",
|
||||
"AttrFlags::query_",
|
||||
"body_shim",
|
||||
"body_with_source_map_shim",
|
||||
"Body::of_",
|
||||
"Body::with_source_map_",
|
||||
"trait_environment_query",
|
||||
"lang_items",
|
||||
"crate_lang_items",
|
||||
@@ -595,14 +595,14 @@ fn main() {
|
||||
"GenericPredicates::query_with_diagnostics_",
|
||||
"ImplTraits::return_type_impl_traits_",
|
||||
"InferenceResult::for_body_",
|
||||
"function_signature_shim",
|
||||
"function_signature_with_source_map_shim",
|
||||
"FunctionSignature::of_",
|
||||
"FunctionSignature::with_source_map_",
|
||||
"trait_environment_query",
|
||||
"GenericPredicates::query_with_diagnostics_",
|
||||
"ImplTraits::return_type_impl_traits_",
|
||||
"expr_scopes_shim",
|
||||
"struct_signature_shim",
|
||||
"struct_signature_with_source_map_shim",
|
||||
"ExprScopes::body_expr_scopes_",
|
||||
"StructSignature::of_",
|
||||
"StructSignature::with_source_map_",
|
||||
"AttrFlags::query_",
|
||||
"GenericPredicates::query_with_diagnostics_",
|
||||
"value_ty_query",
|
||||
@@ -611,8 +611,8 @@ fn main() {
|
||||
"TraitImpls::for_crate_and_deps_",
|
||||
"TraitImpls::for_crate_",
|
||||
"impl_trait_with_diagnostics_query",
|
||||
"impl_signature_shim",
|
||||
"impl_signature_with_source_map_shim",
|
||||
"ImplSignature::of_",
|
||||
"ImplSignature::with_source_map_",
|
||||
"impl_self_ty_with_diagnostics_query",
|
||||
"AttrFlags::query_",
|
||||
"GenericPredicates::query_with_diagnostics_",
|
||||
@@ -658,47 +658,47 @@ fn main() {
|
||||
});
|
||||
|
||||
for def in defs {
|
||||
let _inference_result = InferenceResult::for_body(&db, def);
|
||||
let _inference_result = InferenceResult::of(&db, def);
|
||||
}
|
||||
},
|
||||
&[("trait_solve_shim", 0)],
|
||||
expect_test::expect![[r#"
|
||||
[
|
||||
"parse_shim",
|
||||
"ast_id_map_shim",
|
||||
"ast_id_map",
|
||||
"file_item_tree_query",
|
||||
"real_span_map_shim",
|
||||
"crate_local_def_map",
|
||||
"TraitItems::query_with_diagnostics_",
|
||||
"body_with_source_map_shim",
|
||||
"Body::with_source_map_",
|
||||
"AttrFlags::query_",
|
||||
"body_shim",
|
||||
"Body::of_",
|
||||
"ImplItems::of_",
|
||||
"InferenceResult::for_body_",
|
||||
"AttrFlags::query_",
|
||||
"trait_signature_with_source_map_shim",
|
||||
"TraitSignature::with_source_map_",
|
||||
"AttrFlags::query_",
|
||||
"function_signature_with_source_map_shim",
|
||||
"function_signature_shim",
|
||||
"body_with_source_map_shim",
|
||||
"body_shim",
|
||||
"FunctionSignature::with_source_map_",
|
||||
"FunctionSignature::of_",
|
||||
"Body::with_source_map_",
|
||||
"Body::of_",
|
||||
"crate_lang_items",
|
||||
"GenericPredicates::query_with_diagnostics_",
|
||||
"GenericPredicates::query_with_diagnostics_",
|
||||
"ImplTraits::return_type_impl_traits_",
|
||||
"InferenceResult::for_body_",
|
||||
"function_signature_with_source_map_shim",
|
||||
"FunctionSignature::with_source_map_",
|
||||
"GenericPredicates::query_with_diagnostics_",
|
||||
"ImplTraits::return_type_impl_traits_",
|
||||
"expr_scopes_shim",
|
||||
"struct_signature_with_source_map_shim",
|
||||
"ExprScopes::body_expr_scopes_",
|
||||
"StructSignature::with_source_map_",
|
||||
"AttrFlags::query_",
|
||||
"GenericPredicates::query_with_diagnostics_",
|
||||
"InherentImpls::for_crate_",
|
||||
"callable_item_signature_query",
|
||||
"TraitImpls::for_crate_",
|
||||
"impl_signature_with_source_map_shim",
|
||||
"impl_signature_shim",
|
||||
"ImplSignature::with_source_map_",
|
||||
"ImplSignature::of_",
|
||||
"impl_trait_with_diagnostics_query",
|
||||
"impl_self_ty_with_diagnostics_query",
|
||||
"AttrFlags::query_",
|
||||
@@ -716,6 +716,7 @@ fn execute_assert_events(
|
||||
) {
|
||||
crate::attach_db(db, || {
|
||||
let (executed, events) = db.log_executed(f);
|
||||
expect.assert_debug_eq(&executed);
|
||||
for (event, count) in required {
|
||||
let n = executed.iter().filter(|it| it.contains(event)).count();
|
||||
assert_eq!(
|
||||
@@ -731,6 +732,5 @@ fn execute_assert_events(
|
||||
.collect::<Vec<_>>(),
|
||||
);
|
||||
}
|
||||
expect.assert_debug_eq(&executed);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -421,6 +421,8 @@ fn index(&self, index: core::ops::RangeFull) -> &Self::Output {
|
||||
254..256 '&v': &'? [u8; 3]
|
||||
255..256 'v': [u8; 3]
|
||||
257..259 '{}': ()
|
||||
199..200 '3': usize
|
||||
62..63 'N': usize
|
||||
"#]],
|
||||
);
|
||||
}
|
||||
|
||||
@@ -2754,6 +2754,7 @@ fn filter(&self, filter: &Filter<T>) -> Self::Output {
|
||||
664..680 'filter...ter_fn': dyn Fn(&'? T) -> bool + 'static
|
||||
691..698 'loop {}': !
|
||||
696..698 '{}': ()
|
||||
512..513 'N': usize
|
||||
"#]],
|
||||
);
|
||||
}
|
||||
|
||||
@@ -34,6 +34,7 @@ pub trait Space: IntoIterator {
|
||||
223..227 'iter': IntoIter<u8>
|
||||
230..231 'a': Vec<u8>
|
||||
230..243 'a.into_iter()': IntoIter<u8>
|
||||
322..323 '1': usize
|
||||
"#]],
|
||||
);
|
||||
}
|
||||
@@ -472,6 +473,8 @@ fn foo() {
|
||||
249..257 'to_bytes': fn to_bytes() -> [u8; _]
|
||||
249..259 'to_bytes()': [u8; _]
|
||||
249..268 'to_byt..._vec()': Vec<<[u8; _] as Foo>::Item>
|
||||
205..206 '_': usize
|
||||
156..157 'N': usize
|
||||
"#]],
|
||||
);
|
||||
}
|
||||
@@ -541,6 +544,11 @@ fn test_at_most() {
|
||||
617..620 'num': Between<0, 1, char>
|
||||
623..626 ''9'': char
|
||||
623..641 ''9'.at...:<1>()': Between<0, 1, char>
|
||||
320..335 '{ Consts::MAX }': usize
|
||||
322..333 'Consts::MAX': usize
|
||||
421..422 '0': i32
|
||||
144..159 '{ Consts::MAX }': usize
|
||||
146..157 'Consts::MAX': usize
|
||||
"#]],
|
||||
);
|
||||
}
|
||||
|
||||
@@ -3868,6 +3868,8 @@ fn main() {
|
||||
208..209 'c': u8
|
||||
213..214 'a': A
|
||||
213..221 'a.into()': [u8; 2]
|
||||
33..34 '2': usize
|
||||
111..112 '3': usize
|
||||
"#]],
|
||||
);
|
||||
}
|
||||
@@ -4061,6 +4063,8 @@ fn foo() {
|
||||
248..282 'LazyLo..._LOCK)': &'? [u32; _]
|
||||
264..281 '&VALUE...Y_LOCK': &'? LazyLock<[u32; _]>
|
||||
265..281 'VALUES...Y_LOCK': LazyLock<[u32; _]>
|
||||
197..202 '{ 0 }': usize
|
||||
199..200 '0': usize
|
||||
"#]],
|
||||
);
|
||||
}
|
||||
@@ -4109,3 +4113,38 @@ fn foo() {
|
||||
"#,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn signature_inference() {
|
||||
check_infer(
|
||||
r#"
|
||||
trait Trait<const A: u8> {}
|
||||
struct S<T: Trait<2>, const C: f32 = 0.0>
|
||||
where
|
||||
(): Trait<2>
|
||||
{
|
||||
field: [(); { C as usize }],
|
||||
field2: *mut S<T, 5.0>
|
||||
}
|
||||
|
||||
struct S2<const C: u16>;
|
||||
|
||||
type Alias = S2<0>;
|
||||
impl S2<0> {}
|
||||
enum E {
|
||||
V(S2<0>) = 0,
|
||||
}
|
||||
union U {
|
||||
field: S2<0>
|
||||
}
|
||||
"#,
|
||||
expect![[r#"
|
||||
242..243 '0': isize
|
||||
46..47 '2': i32
|
||||
65..68 '0.0': f32
|
||||
90..91 '2': i32
|
||||
200..201 '0': i32
|
||||
212..213 '0': i32
|
||||
"#]],
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1271,6 +1271,7 @@ fn bar() {
|
||||
241..245 'R::B': fn B<(), i32>(i32) -> R<(), i32>
|
||||
241..248 'R::B(7)': R<(), i32>
|
||||
246..247 '7': i32
|
||||
46..47 '2': usize
|
||||
"#]],
|
||||
);
|
||||
}
|
||||
@@ -3781,6 +3782,8 @@ fn main() {
|
||||
371..373 'v4': usize
|
||||
376..378 'v3': [u8; 4]
|
||||
376..389 'v3.do_thing()': usize
|
||||
86..87 '4': usize
|
||||
192..193 '2': usize
|
||||
"#]],
|
||||
)
|
||||
}
|
||||
@@ -3820,6 +3823,9 @@ fn main() {
|
||||
240..242 'v2': [u8; 2]
|
||||
245..246 'v': [u8; 2]
|
||||
245..257 'v.do_thing()': [u8; 2]
|
||||
130..131 'L': usize
|
||||
102..103 'L': usize
|
||||
130..131 'L': usize
|
||||
"#]],
|
||||
)
|
||||
}
|
||||
|
||||
@@ -7,7 +7,11 @@
|
||||
AdtId, AssocItemId, HasModule, ImplId, Lookup, TraitId,
|
||||
lang_item::LangItems,
|
||||
nameres::DefMap,
|
||||
signatures::{ConstFlags, EnumFlags, FnFlags, StructFlags, TraitFlags, TypeAliasFlags},
|
||||
signatures::{
|
||||
ConstFlags, ConstSignature, EnumFlags, EnumSignature, FnFlags, FunctionSignature,
|
||||
StructFlags, StructSignature, TraitFlags, TraitSignature, TypeAliasFlags,
|
||||
TypeAliasSignature, UnionSignature,
|
||||
},
|
||||
};
|
||||
use hir_expand::name::Name;
|
||||
use intern::sym;
|
||||
@@ -279,21 +283,18 @@ pub fn is_inherent_impl_coherent(db: &dyn HirDatabase, def_map: &DefMap, impl_id
|
||||
| TyKind::Float(_) => true,
|
||||
|
||||
TyKind::Adt(adt_def, _) => match adt_def.def_id().0 {
|
||||
hir_def::AdtId::StructId(id) => db
|
||||
.struct_signature(id)
|
||||
hir_def::AdtId::StructId(id) => StructSignature::of(db, id)
|
||||
.flags
|
||||
.contains(StructFlags::RUSTC_HAS_INCOHERENT_INHERENT_IMPLS),
|
||||
hir_def::AdtId::UnionId(id) => db
|
||||
.union_signature(id)
|
||||
hir_def::AdtId::UnionId(id) => UnionSignature::of(db, id)
|
||||
.flags
|
||||
.contains(StructFlags::RUSTC_HAS_INCOHERENT_INHERENT_IMPLS),
|
||||
hir_def::AdtId::EnumId(it) => db
|
||||
.enum_signature(it)
|
||||
hir_def::AdtId::EnumId(it) => EnumSignature::of(db, it)
|
||||
.flags
|
||||
.contains(EnumFlags::RUSTC_HAS_INCOHERENT_INHERENT_IMPLS),
|
||||
},
|
||||
TyKind::Dynamic(it, _) => it.principal_def_id().is_some_and(|trait_id| {
|
||||
db.trait_signature(trait_id.0)
|
||||
TraitSignature::of(db, trait_id.0)
|
||||
.flags
|
||||
.contains(TraitFlags::RUSTC_HAS_INCOHERENT_INHERENT_IMPLS)
|
||||
}),
|
||||
@@ -304,14 +305,13 @@ pub fn is_inherent_impl_coherent(db: &dyn HirDatabase, def_map: &DefMap, impl_id
|
||||
rustc_has_incoherent_inherent_impls
|
||||
&& !items.items.is_empty()
|
||||
&& items.items.iter().all(|&(_, assoc)| match assoc {
|
||||
AssocItemId::FunctionId(it) => {
|
||||
db.function_signature(it).flags.contains(FnFlags::RUSTC_ALLOW_INCOHERENT_IMPL)
|
||||
}
|
||||
AssocItemId::ConstId(it) => {
|
||||
db.const_signature(it).flags.contains(ConstFlags::RUSTC_ALLOW_INCOHERENT_IMPL)
|
||||
}
|
||||
AssocItemId::TypeAliasId(it) => db
|
||||
.type_alias_signature(it)
|
||||
AssocItemId::FunctionId(it) => FunctionSignature::of(db, it)
|
||||
.flags
|
||||
.contains(FnFlags::RUSTC_ALLOW_INCOHERENT_IMPL),
|
||||
AssocItemId::ConstId(it) => ConstSignature::of(db, it)
|
||||
.flags
|
||||
.contains(ConstFlags::RUSTC_ALLOW_INCOHERENT_IMPL),
|
||||
AssocItemId::TypeAliasId(it) => TypeAliasSignature::of(db, it)
|
||||
.flags
|
||||
.contains(TypeAliasFlags::RUSTC_ALLOW_INCOHERENT_IMPL),
|
||||
})
|
||||
@@ -350,7 +350,7 @@ pub fn check_orphan_rules<'db>(db: &'db dyn HirDatabase, impl_: ImplId) -> bool
|
||||
let AdtId::StructId(s) = adt_def.def_id().0 else {
|
||||
break ty;
|
||||
};
|
||||
let struct_signature = db.struct_signature(s);
|
||||
let struct_signature = StructSignature::of(db, s);
|
||||
if struct_signature.flags.contains(StructFlags::FUNDAMENTAL) {
|
||||
let next = subs.types().next();
|
||||
match next {
|
||||
|
||||
@@ -44,10 +44,10 @@ pub fn upvars_mentioned(
|
||||
db: &dyn HirDatabase,
|
||||
owner: DefWithBodyId,
|
||||
) -> Option<Box<FxHashMap<ExprId, Upvars>>> {
|
||||
let body = db.body(owner);
|
||||
let body = Body::of(db, owner);
|
||||
let mut resolver = owner.resolver(db);
|
||||
let mut result = FxHashMap::default();
|
||||
handle_expr_outside_closure(db, &mut resolver, owner, &body, body.body_expr, &mut result);
|
||||
handle_expr_outside_closure(db, &mut resolver, owner, body, body.root_expr(), &mut result);
|
||||
return if result.is_empty() {
|
||||
None
|
||||
} else {
|
||||
@@ -198,7 +198,7 @@ fn resolve_maybe_upvar<'db>(
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use expect_test::{Expect, expect};
|
||||
use hir_def::{ModuleDefId, db::DefDatabase, nameres::crate_def_map};
|
||||
use hir_def::{ModuleDefId, expr_store::Body, nameres::crate_def_map};
|
||||
use itertools::Itertools;
|
||||
use span::Edition;
|
||||
use test_fixture::WithFixture;
|
||||
@@ -219,7 +219,7 @@ fn check(#[rust_analyzer::rust_fixture] ra_fixture: &str, expectation: Expect) {
|
||||
})
|
||||
.exactly_one()
|
||||
.unwrap_or_else(|_| panic!("expected one function"));
|
||||
let (body, source_map) = db.body_with_source_map(func.into());
|
||||
let (body, source_map) = Body::with_source_map(&db, func.into());
|
||||
let Some(upvars) = upvars_mentioned(&db, func.into()) else {
|
||||
expectation.assert_eq("");
|
||||
return;
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
use base_db::target::{self, TargetData};
|
||||
use hir_def::{
|
||||
EnumId, EnumVariantId, FunctionId, Lookup, TraitId, attrs::AttrFlags, lang_item::LangItems,
|
||||
signatures::FunctionSignature,
|
||||
};
|
||||
use intern::sym;
|
||||
use rustc_abi::TargetDataLayout;
|
||||
@@ -79,7 +80,7 @@ pub fn is_fn_unsafe_to_call(
|
||||
call_edition: Edition,
|
||||
target_feature_is_safe: TargetFeatureIsSafeInTarget,
|
||||
) -> Unsafety {
|
||||
let data = db.function_signature(func);
|
||||
let data = FunctionSignature::of(db, func);
|
||||
if data.is_unsafe() {
|
||||
return Unsafety::Unsafe;
|
||||
}
|
||||
|
||||
@@ -13,7 +13,10 @@
|
||||
//! by the next salsa version. If not, we will likely have to adapt and go with the rustc approach
|
||||
//! while installing firewall per item queries to prevent invalidation issues.
|
||||
|
||||
use hir_def::{AdtId, GenericDefId, GenericParamId, VariantId, signatures::StructFlags};
|
||||
use hir_def::{
|
||||
AdtId, GenericDefId, GenericParamId, VariantId,
|
||||
signatures::{StructFlags, StructSignature},
|
||||
};
|
||||
use rustc_ast_ir::Mutability;
|
||||
use rustc_type_ir::{
|
||||
Variance,
|
||||
@@ -45,7 +48,7 @@ fn variances_of_query(db: &dyn HirDatabase, def: GenericDefId) -> StoredVariance
|
||||
GenericDefId::FunctionId(_) => (),
|
||||
GenericDefId::AdtId(adt) => {
|
||||
if let AdtId::StructId(id) = adt {
|
||||
let flags = &db.struct_signature(id).flags;
|
||||
let flags = &StructSignature::of(db, id).flags;
|
||||
let types = || crate::next_solver::default_types(db);
|
||||
if flags.contains(StructFlags::IS_UNSAFE_CELL) {
|
||||
return types().one_invariant.store();
|
||||
@@ -113,7 +116,7 @@ pub(crate) fn variances_of_cycle_initial(
|
||||
|
||||
struct Context<'db> {
|
||||
db: &'db dyn HirDatabase,
|
||||
generics: Generics,
|
||||
generics: Generics<'db>,
|
||||
variances: Box<[Variance]>,
|
||||
}
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
TraitId, TypeOrConstParamId,
|
||||
attrs::{AttrFlags, Docs, IsInnerDoc},
|
||||
expr_store::path::Path,
|
||||
hir::generics::GenericParams,
|
||||
item_scope::ItemInNs,
|
||||
per_ns::Namespace,
|
||||
resolver::{HasResolver, Resolver, TypeNs},
|
||||
@@ -26,9 +27,9 @@
|
||||
use stdx::never;
|
||||
|
||||
use crate::{
|
||||
Adt, AsAssocItem, AssocItem, BuiltinType, Const, ConstParam, DocLinkDef, Enum, ExternCrateDecl,
|
||||
Field, Function, GenericParam, HasCrate, Impl, LangItem, LifetimeParam, Macro, Module,
|
||||
ModuleDef, Static, Struct, Trait, Type, TypeAlias, TypeParam, Union, Variant, VariantDef,
|
||||
Adt, AsAssocItem, AssocItem, BuiltinType, Const, ConstParam, DocLinkDef, Enum, EnumVariant,
|
||||
ExternCrateDecl, Field, Function, GenericParam, HasCrate, Impl, LangItem, LifetimeParam, Macro,
|
||||
Module, ModuleDef, Static, Struct, Trait, Type, TypeAlias, TypeParam, Union, Variant,
|
||||
};
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
@@ -199,7 +200,7 @@ fn attr_id(self, _db: &dyn HirDatabase) -> AttrsOwner {
|
||||
}
|
||||
|
||||
impl_has_attrs![
|
||||
(Variant, EnumVariantId),
|
||||
(EnumVariant, EnumVariantId),
|
||||
(Static, StaticId),
|
||||
(Const, ConstId),
|
||||
(Trait, TraitId),
|
||||
@@ -377,7 +378,7 @@ fn resolve_assoc_or_field(
|
||||
let ty = match base_def {
|
||||
TypeNs::SelfType(id) => Impl::from(id).self_ty(db),
|
||||
TypeNs::GenericParam(param) => {
|
||||
let generic_params = db.generic_params(param.parent());
|
||||
let generic_params = GenericParams::of(db, param.parent());
|
||||
if generic_params[param.local_id()].is_trait_self() {
|
||||
// `Self::assoc` in traits should refer to the trait itself.
|
||||
let parent_trait = |container| match container {
|
||||
@@ -406,7 +407,7 @@ fn resolve_assoc_or_field(
|
||||
TypeNs::AdtId(id) | TypeNs::AdtSelfType(id) => Adt::from(id).ty(db),
|
||||
TypeNs::EnumVariantId(id) => {
|
||||
// Enum variants don't have path candidates.
|
||||
let variant = Variant::from(id);
|
||||
let variant = EnumVariant::from(id);
|
||||
return resolve_field(db, variant.into(), name, ns);
|
||||
}
|
||||
TypeNs::TypeAliasId(id) => {
|
||||
@@ -443,7 +444,7 @@ fn resolve_assoc_or_field(
|
||||
.id
|
||||
.enum_variants(db)
|
||||
.variant(&name)
|
||||
.map(|variant| DocLinkDef::ModuleDef(ModuleDef::Variant(variant.into())));
|
||||
.map(|variant| DocLinkDef::ModuleDef(ModuleDef::EnumVariant(variant.into())));
|
||||
}
|
||||
};
|
||||
resolve_field(db, variant_def, name, ns)
|
||||
@@ -505,7 +506,7 @@ fn resolve_impl_trait_item<'db>(
|
||||
|
||||
fn resolve_field(
|
||||
db: &dyn HirDatabase,
|
||||
def: VariantDef,
|
||||
def: Variant,
|
||||
name: Name,
|
||||
ns: Option<Namespace>,
|
||||
) -> Option<DocLinkDef> {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user