mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-27 05:23:24 +00:00
Merge #2243
2243: Move body queries to hir_def r=matklad a=matklad Co-authored-by: Aleksey Kladov <aleksey.kladov@gmail.com>
This commit is contained in:
commit
f2c64ba15d
14 changed files with 129 additions and 94 deletions
|
@ -8,6 +8,7 @@ use std::sync::Arc;
|
|||
|
||||
use hir_def::{
|
||||
adt::VariantData,
|
||||
body::scope::ExprScopes,
|
||||
builtin_type::BuiltinType,
|
||||
type_ref::{Mutability, TypeRef},
|
||||
CrateModuleId, LocalEnumVariantId, LocalStructFieldId, ModuleId, UnionId,
|
||||
|
@ -539,6 +540,7 @@ pub trait HasBody: Copy {
|
|||
fn infer(self, db: &impl HirDatabase) -> Arc<InferenceResult>;
|
||||
fn body(self, db: &impl HirDatabase) -> Arc<Body>;
|
||||
fn body_source_map(self, db: &impl HirDatabase) -> Arc<BodySourceMap>;
|
||||
fn expr_scopes(self, db: &impl HirDatabase) -> Arc<ExprScopes>;
|
||||
}
|
||||
|
||||
impl<T> HasBody for T
|
||||
|
@ -550,11 +552,15 @@ where
|
|||
}
|
||||
|
||||
fn body(self, db: &impl HirDatabase) -> Arc<Body> {
|
||||
db.body(self.into())
|
||||
self.into().body(db)
|
||||
}
|
||||
|
||||
fn body_source_map(self, db: &impl HirDatabase) -> Arc<BodySourceMap> {
|
||||
db.body_with_source_map(self.into()).1
|
||||
self.into().body_source_map(db)
|
||||
}
|
||||
|
||||
fn expr_scopes(self, db: &impl HirDatabase) -> Arc<ExprScopes> {
|
||||
self.into().expr_scopes(db)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -564,11 +570,15 @@ impl HasBody for DefWithBody {
|
|||
}
|
||||
|
||||
fn body(self, db: &impl HirDatabase) -> Arc<Body> {
|
||||
db.body(self)
|
||||
db.body(self.into())
|
||||
}
|
||||
|
||||
fn body_source_map(self, db: &impl HirDatabase) -> Arc<BodySourceMap> {
|
||||
db.body_with_source_map(self).1
|
||||
db.body_with_source_map(self.into()).1
|
||||
}
|
||||
|
||||
fn expr_scopes(self, db: &impl HirDatabase) -> Arc<ExprScopes> {
|
||||
db.expr_scopes(self.into())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -662,11 +672,11 @@ impl Function {
|
|||
}
|
||||
|
||||
pub(crate) fn body_source_map(self, db: &impl HirDatabase) -> Arc<BodySourceMap> {
|
||||
db.body_with_source_map(self.into()).1
|
||||
db.body_with_source_map(self.id.into()).1
|
||||
}
|
||||
|
||||
pub fn body(self, db: &impl HirDatabase) -> Arc<Body> {
|
||||
db.body(self.into())
|
||||
db.body(self.id.into())
|
||||
}
|
||||
|
||||
pub fn ty(self, db: &impl HirDatabase) -> Ty {
|
||||
|
@ -1079,7 +1089,7 @@ pub struct Local {
|
|||
|
||||
impl Local {
|
||||
pub fn name(self, db: &impl HirDatabase) -> Option<Name> {
|
||||
let body = db.body(self.parent);
|
||||
let body = self.parent.body(db);
|
||||
match &body[self.pat_id] {
|
||||
Pat::Bind { name, .. } => Some(name.clone()),
|
||||
_ => None,
|
||||
|
@ -1091,7 +1101,7 @@ impl Local {
|
|||
}
|
||||
|
||||
pub fn is_mut(self, db: &impl HirDatabase) -> bool {
|
||||
let body = db.body(self.parent);
|
||||
let body = self.parent.body(db);
|
||||
match &body[self.pat_id] {
|
||||
Pat::Bind { mode, .. } => match mode {
|
||||
BindingAnnotation::Mutable | BindingAnnotation::RefMut => true,
|
||||
|
@ -1115,7 +1125,7 @@ impl Local {
|
|||
}
|
||||
|
||||
pub fn source(self, db: &impl HirDatabase) -> Source<Either<ast::BindPat, ast::SelfParam>> {
|
||||
let (_body, source_map) = db.body_with_source_map(self.parent);
|
||||
let source_map = self.parent.body_source_map(db);
|
||||
let src = source_map.pat_syntax(self.pat_id).unwrap(); // Hmm...
|
||||
let root = src.file_syntax(db);
|
||||
src.map(|ast| ast.map(|it| it.cast().unwrap().to_node(&root), |it| it.to_node(&root)))
|
||||
|
|
|
@ -8,7 +8,6 @@ use ra_syntax::SmolStr;
|
|||
|
||||
use crate::{
|
||||
debug::HirDebugDatabase,
|
||||
expr::{Body, BodySourceMap},
|
||||
generics::{GenericDef, GenericParams},
|
||||
ids,
|
||||
impl_block::{ImplBlock, ImplSourceMap, ModuleImplBlocks},
|
||||
|
@ -19,13 +18,14 @@ use crate::{
|
|||
InferenceResult, Namespace, Substs, Ty, TypableDef, TypeCtor,
|
||||
},
|
||||
type_alias::TypeAliasData,
|
||||
Const, ConstData, Crate, DefWithBody, ExprScopes, FnData, Function, Module, Static,
|
||||
StructField, Trait, TypeAlias,
|
||||
Const, ConstData, Crate, DefWithBody, FnData, Function, Module, Static, StructField, Trait,
|
||||
TypeAlias,
|
||||
};
|
||||
|
||||
pub use hir_def::db::{
|
||||
CrateDefMapQuery, DefDatabase2, DefDatabase2Storage, EnumDataQuery, InternDatabase,
|
||||
InternDatabaseStorage, RawItemsQuery, RawItemsWithSourceMapQuery, StructDataQuery,
|
||||
BodyQuery, BodyWithSourceMapQuery, CrateDefMapQuery, DefDatabase2, DefDatabase2Storage,
|
||||
EnumDataQuery, ExprScopesQuery, InternDatabase, InternDatabaseStorage, RawItemsQuery,
|
||||
RawItemsWithSourceMapQuery, StructDataQuery,
|
||||
};
|
||||
pub use hir_expand::db::{
|
||||
AstDatabase, AstDatabaseStorage, AstIdMapQuery, MacroArgQuery, MacroDefQuery, MacroExpandQuery,
|
||||
|
@ -85,9 +85,6 @@ pub trait DefDatabase: HirDebugDatabase + DefDatabase2 {
|
|||
#[salsa::query_group(HirDatabaseStorage)]
|
||||
#[salsa::requires(salsa::Database)]
|
||||
pub trait HirDatabase: DefDatabase + AstDatabase {
|
||||
#[salsa::invoke(crate::expr::expr_scopes_query)]
|
||||
fn expr_scopes(&self, def: DefWithBody) -> Arc<ExprScopes>;
|
||||
|
||||
#[salsa::invoke(crate::ty::infer_query)]
|
||||
fn infer(&self, def: DefWithBody) -> Arc<InferenceResult>;
|
||||
|
||||
|
@ -113,12 +110,6 @@ pub trait HirDatabase: DefDatabase + AstDatabase {
|
|||
#[salsa::invoke(crate::ty::generic_defaults_query)]
|
||||
fn generic_defaults(&self, def: GenericDef) -> Substs;
|
||||
|
||||
#[salsa::invoke(crate::expr::body_with_source_map_query)]
|
||||
fn body_with_source_map(&self, def: DefWithBody) -> (Arc<Body>, Arc<BodySourceMap>);
|
||||
|
||||
#[salsa::invoke(crate::expr::body_query)]
|
||||
fn body(&self, def: DefWithBody) -> Arc<Body>;
|
||||
|
||||
#[salsa::invoke(crate::ty::method_resolution::CrateImplBlocks::impls_in_crate_query)]
|
||||
fn impls_in_crate(&self, krate: Crate) -> Arc<CrateImplBlocks>;
|
||||
|
||||
|
|
|
@ -4,9 +4,9 @@ pub(crate) mod validation;
|
|||
|
||||
use std::sync::Arc;
|
||||
|
||||
use ra_syntax::{ast, AstPtr};
|
||||
use ra_syntax::AstPtr;
|
||||
|
||||
use crate::{db::HirDatabase, DefWithBody, HasSource, Resolver};
|
||||
use crate::{db::HirDatabase, DefWithBody, HasBody, Resolver};
|
||||
|
||||
pub use hir_def::{
|
||||
body::{
|
||||
|
@ -19,48 +19,13 @@ pub use hir_def::{
|
|||
},
|
||||
};
|
||||
|
||||
pub(crate) fn body_with_source_map_query(
|
||||
db: &impl HirDatabase,
|
||||
def: DefWithBody,
|
||||
) -> (Arc<Body>, Arc<BodySourceMap>) {
|
||||
let mut params = None;
|
||||
|
||||
let (file_id, body) = match def {
|
||||
DefWithBody::Function(f) => {
|
||||
let src = f.source(db);
|
||||
params = src.ast.param_list();
|
||||
(src.file_id, src.ast.body().map(ast::Expr::from))
|
||||
}
|
||||
DefWithBody::Const(c) => {
|
||||
let src = c.source(db);
|
||||
(src.file_id, src.ast.body())
|
||||
}
|
||||
DefWithBody::Static(s) => {
|
||||
let src = s.source(db);
|
||||
(src.file_id, src.ast.body())
|
||||
}
|
||||
};
|
||||
let expander = hir_def::body::Expander::new(db, file_id, def.module(db).id);
|
||||
let (body, source_map) = Body::new(db, expander, params, body);
|
||||
(Arc::new(body), Arc::new(source_map))
|
||||
}
|
||||
|
||||
pub(crate) fn body_query(db: &impl HirDatabase, def: DefWithBody) -> Arc<Body> {
|
||||
db.body_with_source_map(def).0
|
||||
}
|
||||
|
||||
pub(crate) fn expr_scopes_query(db: &impl HirDatabase, def: DefWithBody) -> Arc<ExprScopes> {
|
||||
let body = db.body(def);
|
||||
Arc::new(ExprScopes::new(&*body))
|
||||
}
|
||||
|
||||
// needs arbitrary_self_types to be a method... or maybe move to the def?
|
||||
pub(crate) fn resolver_for_expr(
|
||||
db: &impl HirDatabase,
|
||||
owner: DefWithBody,
|
||||
expr_id: ExprId,
|
||||
) -> Resolver {
|
||||
let scopes = db.expr_scopes(owner);
|
||||
let scopes = owner.expr_scopes(db);
|
||||
resolver_for_scope(db, owner, scopes.scope_for(expr_id))
|
||||
}
|
||||
|
||||
|
@ -70,7 +35,7 @@ pub(crate) fn resolver_for_scope(
|
|||
scope_id: Option<ScopeId>,
|
||||
) -> Resolver {
|
||||
let mut r = owner.resolver(db);
|
||||
let scopes = db.expr_scopes(owner);
|
||||
let scopes = owner.expr_scopes(db);
|
||||
let scope_chain = scopes.scope_chain(scope_id).collect::<Vec<_>>();
|
||||
for scope in scope_chain.into_iter().rev() {
|
||||
r = r.push_expr_scope(Arc::clone(&scopes), scope);
|
||||
|
|
|
@ -3,9 +3,9 @@
|
|||
//! It's unclear if we need this long-term, but it's definitelly useful while we
|
||||
//! are splitting the hir.
|
||||
|
||||
use hir_def::{AdtId, EnumVariantId, ModuleDefId};
|
||||
use hir_def::{AdtId, DefWithBodyId, EnumVariantId, ModuleDefId};
|
||||
|
||||
use crate::{Adt, EnumVariant, ModuleDef};
|
||||
use crate::{Adt, DefWithBody, EnumVariant, ModuleDef};
|
||||
|
||||
macro_rules! from_id {
|
||||
($(($id:path, $ty:path)),*) => {$(
|
||||
|
@ -61,3 +61,13 @@ impl From<ModuleDefId> for ModuleDef {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<DefWithBody> for DefWithBodyId {
|
||||
fn from(def: DefWithBody) -> Self {
|
||||
match def {
|
||||
DefWithBody::Function(it) => DefWithBodyId::FunctionId(it.id),
|
||||
DefWithBody::Static(it) => DefWithBodyId::StaticId(it.id),
|
||||
DefWithBody::Const(it) => DefWithBodyId::ConstId(it.id),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ use ra_syntax::{
|
|||
use crate::{
|
||||
db::{AstDatabase, DefDatabase, HirDatabase},
|
||||
ids::{AstItemDef, LocationCtx},
|
||||
AstId, Const, Crate, DefWithBody, Enum, EnumVariant, FieldSource, Function, HasSource,
|
||||
AstId, Const, Crate, DefWithBody, Enum, EnumVariant, FieldSource, Function, HasBody, HasSource,
|
||||
ImplBlock, Local, Module, ModuleSource, Source, Static, Struct, StructField, Trait, TypeAlias,
|
||||
Union, VariantDef,
|
||||
};
|
||||
|
@ -144,7 +144,7 @@ impl Local {
|
|||
};
|
||||
Some(res)
|
||||
})?;
|
||||
let (_body, source_map) = db.body_with_source_map(parent);
|
||||
let source_map = parent.body_source_map(db);
|
||||
let src = src.map(ast::Pat::from);
|
||||
let pat_id = source_map.node_pat(src.as_ref())?;
|
||||
Some(Local { parent, pat_id })
|
||||
|
|
|
@ -146,7 +146,7 @@ impl SourceAnalyzer {
|
|||
let def_with_body = def_with_body_from_child_node(db, file_id, node);
|
||||
if let Some(def) = def_with_body {
|
||||
let source_map = def.body_source_map(db);
|
||||
let scopes = db.expr_scopes(def);
|
||||
let scopes = def.expr_scopes(db);
|
||||
let scope = match offset {
|
||||
None => scope_for(&scopes, &source_map, file_id.into(), &node),
|
||||
Some(offset) => scope_for_offset(&scopes, &source_map, file_id.into(), offset),
|
||||
|
|
|
@ -43,7 +43,8 @@ use crate::{
|
|||
expr::{BindingAnnotation, Body, ExprId, PatId},
|
||||
resolve::{Resolver, TypeNs},
|
||||
ty::infer::diagnostics::InferenceDiagnostic,
|
||||
Adt, AssocItem, ConstData, DefWithBody, FloatTy, FnData, Function, IntTy, Path, StructField,
|
||||
Adt, AssocItem, ConstData, DefWithBody, FloatTy, FnData, Function, HasBody, IntTy, Path,
|
||||
StructField,
|
||||
};
|
||||
|
||||
macro_rules! ty_app {
|
||||
|
@ -214,7 +215,7 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> {
|
|||
coerce_unsized_map: Self::init_coerce_unsized_map(db, &resolver),
|
||||
db,
|
||||
owner,
|
||||
body: db.body(owner),
|
||||
body: owner.body(db),
|
||||
resolver,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@ use crate::{
|
|||
ApplicationTy, GenericPredicate, Namespace, ProjectionTy, Substs, TraitRef, Ty, TypeCtor,
|
||||
TypeWalk,
|
||||
},
|
||||
AssocItem, Crate, ImplBlock, Trait, TypeAlias,
|
||||
AssocItem, Crate, HasBody, ImplBlock, Trait, TypeAlias,
|
||||
};
|
||||
|
||||
/// This represents a trait whose name we could not resolve.
|
||||
|
@ -714,7 +714,7 @@ fn closure_fn_trait_impl_datum(
|
|||
let fn_once_trait = get_fn_trait(db, krate, super::FnTrait::FnOnce)?;
|
||||
let trait_ = get_fn_trait(db, krate, data.fn_trait)?; // get corresponding fn trait
|
||||
|
||||
let num_args: u16 = match &db.body(data.def)[data.expr] {
|
||||
let num_args: u16 = match &data.def.body(db)[data.expr] {
|
||||
crate::expr::Expr::Lambda { args, .. } => args.len() as u16,
|
||||
_ => {
|
||||
log::warn!("closure for closure type {:?} not found", data);
|
||||
|
|
|
@ -17,7 +17,7 @@ use crate::{
|
|||
expr::{Expr, ExprId, Pat, PatId},
|
||||
nameres::CrateDefMap,
|
||||
path::Path,
|
||||
ModuleId,
|
||||
AstItemDef, DefWithBodyId, ModuleId,
|
||||
};
|
||||
|
||||
pub struct Expander {
|
||||
|
@ -141,7 +141,37 @@ pub struct BodySourceMap {
|
|||
}
|
||||
|
||||
impl Body {
|
||||
pub fn new(
|
||||
pub(crate) fn body_with_source_map_query(
|
||||
db: &impl DefDatabase2,
|
||||
def: DefWithBodyId,
|
||||
) -> (Arc<Body>, Arc<BodySourceMap>) {
|
||||
let mut params = None;
|
||||
|
||||
let (file_id, module, body) = match def {
|
||||
DefWithBodyId::FunctionId(f) => {
|
||||
let src = f.source(db);
|
||||
params = src.ast.param_list();
|
||||
(src.file_id, f.module(db), src.ast.body().map(ast::Expr::from))
|
||||
}
|
||||
DefWithBodyId::ConstId(c) => {
|
||||
let src = c.source(db);
|
||||
(src.file_id, c.module(db), src.ast.body())
|
||||
}
|
||||
DefWithBodyId::StaticId(s) => {
|
||||
let src = s.source(db);
|
||||
(src.file_id, s.module(db), src.ast.body())
|
||||
}
|
||||
};
|
||||
let expander = Expander::new(db, file_id, module);
|
||||
let (body, source_map) = Body::new(db, expander, params, body);
|
||||
(Arc::new(body), Arc::new(source_map))
|
||||
}
|
||||
|
||||
pub(crate) fn body_query(db: &impl DefDatabase2, def: DefWithBodyId) -> Arc<Body> {
|
||||
db.body_with_source_map(def).0
|
||||
}
|
||||
|
||||
fn new(
|
||||
db: &impl DefDatabase2,
|
||||
expander: Expander,
|
||||
params: Option<ast::ParamList>,
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
//! FIXME: write short doc here
|
||||
use std::sync::Arc;
|
||||
|
||||
use hir_expand::name::Name;
|
||||
use ra_arena::{impl_arena_id, Arena, RawId};
|
||||
|
@ -6,7 +7,9 @@ use rustc_hash::FxHashMap;
|
|||
|
||||
use crate::{
|
||||
body::Body,
|
||||
db::DefDatabase2,
|
||||
expr::{Expr, ExprId, Pat, PatId, Statement},
|
||||
DefWithBodyId,
|
||||
};
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
|
@ -42,7 +45,12 @@ pub struct ScopeData {
|
|||
}
|
||||
|
||||
impl ExprScopes {
|
||||
pub fn new(body: &Body) -> ExprScopes {
|
||||
pub(crate) fn expr_scopes_query(db: &impl DefDatabase2, def: DefWithBodyId) -> Arc<ExprScopes> {
|
||||
let body = db.body(def);
|
||||
Arc::new(ExprScopes::new(&*body))
|
||||
}
|
||||
|
||||
fn new(body: &Body) -> ExprScopes {
|
||||
let mut scopes =
|
||||
ExprScopes { scopes: Arena::default(), scope_by_expr: FxHashMap::default() };
|
||||
let root = scopes.root_scope();
|
||||
|
|
|
@ -7,11 +7,12 @@ use ra_syntax::ast;
|
|||
|
||||
use crate::{
|
||||
adt::{EnumData, StructData},
|
||||
body::{scope::ExprScopes, Body, BodySourceMap},
|
||||
nameres::{
|
||||
raw::{ImportSourceMap, RawItems},
|
||||
CrateDefMap,
|
||||
},
|
||||
EnumId, StructOrUnionId,
|
||||
DefWithBodyId, EnumId, StructOrUnionId,
|
||||
};
|
||||
|
||||
#[salsa::query_group(InternDatabaseStorage)]
|
||||
|
@ -52,4 +53,13 @@ pub trait DefDatabase2: InternDatabase + AstDatabase {
|
|||
|
||||
#[salsa::invoke(EnumData::enum_data_query)]
|
||||
fn enum_data(&self, e: EnumId) -> Arc<EnumData>;
|
||||
|
||||
#[salsa::invoke(Body::body_with_source_map_query)]
|
||||
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>;
|
||||
}
|
||||
|
|
|
@ -374,3 +374,13 @@ impl_froms!(
|
|||
TypeAliasId,
|
||||
BuiltinType
|
||||
);
|
||||
|
||||
/// The defs which have a body.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
pub enum DefWithBodyId {
|
||||
FunctionId(FunctionId),
|
||||
StaticId(StaticId),
|
||||
ConstId(ConstId),
|
||||
}
|
||||
|
||||
impl_froms!(DefWithBodyId: FunctionId, ConstId, StaticId);
|
||||
|
|
|
@ -40,24 +40,24 @@ pub(crate) fn literal(p: &mut Parser) -> Option<CompletedMarker> {
|
|||
// E.g. for after the break in `if break {}`, this should not match
|
||||
pub(super) const ATOM_EXPR_FIRST: TokenSet =
|
||||
LITERAL_FIRST.union(paths::PATH_FIRST).union(token_set![
|
||||
L_PAREN,
|
||||
L_CURLY,
|
||||
L_BRACK,
|
||||
PIPE,
|
||||
MOVE_KW,
|
||||
BOX_KW,
|
||||
IF_KW,
|
||||
WHILE_KW,
|
||||
MATCH_KW,
|
||||
UNSAFE_KW,
|
||||
RETURN_KW,
|
||||
BREAK_KW,
|
||||
CONTINUE_KW,
|
||||
T!['('],
|
||||
T!['{'],
|
||||
T!['['],
|
||||
T![|],
|
||||
T![move],
|
||||
T![box],
|
||||
T![if],
|
||||
T![while],
|
||||
T![match],
|
||||
T![unsafe],
|
||||
T![return],
|
||||
T![break],
|
||||
T![continue],
|
||||
T![async],
|
||||
T![try],
|
||||
T![loop],
|
||||
T![for],
|
||||
LIFETIME,
|
||||
ASYNC_KW,
|
||||
TRY_KW,
|
||||
LOOP_KW,
|
||||
FOR_KW,
|
||||
]);
|
||||
|
||||
const EXPR_RECOVERY_SET: TokenSet = token_set![LET_KW];
|
||||
|
|
|
@ -30,8 +30,8 @@ const fn mask(kind: SyntaxKind) -> u128 {
|
|||
|
||||
#[macro_export]
|
||||
macro_rules! token_set {
|
||||
($($t:ident),*) => { TokenSet::empty()$(.union(TokenSet::singleton($t)))* };
|
||||
($($t:ident),* ,) => { token_set!($($t),*) };
|
||||
($($t:expr),*) => { TokenSet::empty()$(.union(TokenSet::singleton($t)))* };
|
||||
($($t:expr),* ,) => { token_set!($($t),*) };
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
Loading…
Reference in a new issue