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:
bors
2026-03-30 07:41:45 +00:00
208 changed files with 4843 additions and 2805 deletions
+1 -1
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
+1
View File
@@ -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))
}
+117 -27
View File
@@ -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) = &param.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 &param 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